From e39adea8383cb05f7e5e1c93b680aadf90234b40 Mon Sep 17 00:00:00 2001 From: Vladimir Date: Tue, 30 May 2023 11:16:27 +0200 Subject: [PATCH] feat: pass down meta information to Node.js process (#3449) Co-authored-by: Anjorin Damilare --- docs/.vitepress/config.ts | 4 + docs/advanced/metadata.md | 74 +++++ docs/guide/test-context.md | 4 +- packages/browser/src/client/runner.ts | 4 +- packages/runner/src/collect.ts | 1 + packages/runner/src/context.ts | 1 + packages/runner/src/run.ts | 15 +- packages/runner/src/suite.ts | 3 + packages/runner/src/types/runner.ts | 4 +- packages/runner/src/types/tasks.ts | 21 +- packages/vitest/src/node/state.ts | 10 +- packages/vitest/src/typecheck/typechecker.ts | 2 +- packages/vitest/src/types/global.ts | 5 + packages/vitest/src/types/tasks.ts | 3 +- pnpm-lock.yaml | 287 +++++++++--------- test/public-api/fixtures/custom.spec.ts | 16 + test/public-api/package.json | 11 + test/public-api/tests/runner.spec.ts | 70 +++++ test/public-api/vitest.config.ts | 7 + test/reporters/src/data-for-junit.ts | 3 + test/reporters/src/data.ts | 12 + .../tests/__snapshots__/html.test.ts.snap | 10 + test/reporters/tests/junit.test.ts | 2 + test/test-utils/index.ts | 7 +- 24 files changed, 417 insertions(+), 159 deletions(-) create mode 100644 docs/advanced/metadata.md create mode 100644 test/public-api/fixtures/custom.spec.ts create mode 100644 test/public-api/package.json create mode 100644 test/public-api/tests/runner.spec.ts create mode 100644 test/public-api/vitest.config.ts diff --git a/docs/.vitepress/config.ts b/docs/.vitepress/config.ts index 7bd7e3fec8a3..3c9312dffed0 100644 --- a/docs/.vitepress/config.ts +++ b/docs/.vitepress/config.ts @@ -128,6 +128,10 @@ export default withPwa(defineConfig({ text: 'Runner API', link: '/advanced/runner', }, + { + text: 'Task Metadata', + link: '/advanced/metadata', + }, ], }, ], diff --git a/docs/advanced/metadata.md b/docs/advanced/metadata.md new file mode 100644 index 000000000000..1e40a6a02be1 --- /dev/null +++ b/docs/advanced/metadata.md @@ -0,0 +1,74 @@ +# Task Metadata + +::: warning +Vitest exposes experimental private API. Breaking changes might not follow semver, please pin Vitest's version when using it. +::: + +If you are developing a custom reporter or using Vitest Node.js API, you might find it useful to pass data from tests that are being executed in various contexts to your reporter or custom Vitest handler. + +To accomplish this, relying on the [test context](/guide/test-context) is not feasible since it cannot be serialized. However, with Vitest, you can utilize the `meta` property available on every task (suite or test) to share data between your tests and the Node.js process. It's important to note that this communication is one-way only, as the `meta` property can only be modified from within the test context. Any changes made within the Node.js context will not be visible in your tests. + +You can populate `meta` property on test context or inside `beforeAll`/`afterAll` hooks for suite tasks. + +```ts +afterAll((suite) => { + suite.meta.done = true +}) + +test('custom', ({ task }) => { + task.meta.custom = 'some-custom-handler' +}) +``` + +Once a test is completed, Vitest will send a task including the result and `meta` to the Node.js process using RPC. To intercept and process this task, you can utilize the `onTaskUpdate` method available in your reporter implementation: + +```ts +// custom-reporter.js +export default { + // you can intercept packs if needed + onTaskUpdate(packs) { + const [id, result, meta] = packs[0] + }, + // meta is located on every task inside "onFinished" + onFinished(files) { + files[0].meta.done === true + files[0].tasks[0].meta.custom === 'some-custom-handler' + } +} +``` + +::: warning +Vitest can send several tasks at the same time if several tests are completed in a short period of time. +::: + +::: danger BEWARE +Vitest uses different methods to communicate with the Node.js process. + +- If Vitest runs tests inside worker threads, it will send data via [message port](https://developer.mozilla.org/en-US/docs/Web/API/MessagePort) +- If Vitest uses child process, the data will be send as a serialized Buffer via [`process.send`](https://nodejs.org/api/process.html#processsendmessage-sendhandle-options-callback) API +- If Vitest run tests in the browser, the data will be stringified using [flatted](https://www.npmjs.com/package/flatted) package + +The general rule of thumb is that you can send almost anything, except for functions, Promises, regexp (`v8.stringify` cannot serialize it, but you can send a string version and parse it in the Node.js process yourself), and other non-serializable data, but you can have cyclic references inside. + +Also, make sure you serialize [Error properties](https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API/Structured_clone_algorithm#error_types) before you set them. +::: + +You can also get this information from Vitest state when tests finished running: + +```ts +const vitest = await createVitest('test') +await vitest.start() +vitest.state.getFiles()[0].meta.done === true +vitest.state.getFiles()[0].tasks[0].meta.custom === 'some-custom-handler' +``` + +It's also possible to extend type definitions when using TypeScript: + +```ts +declare module 'vitest' { + interface TaskMeta { + done?: boolean + custom?: string + } +} +``` \ No newline at end of file diff --git a/docs/guide/test-context.md b/docs/guide/test-context.md index c581c52b42d7..3b4320809595 100644 --- a/docs/guide/test-context.md +++ b/docs/guide/test-context.md @@ -15,13 +15,13 @@ import { it } from 'vitest' it('should work', (ctx) => { // prints name of the test - console.log(ctx.meta.name) + console.log(ctx.task.name) }) ``` ## Built-in Test Context -#### `context.meta` +#### `context.task` A readonly object containing metadata about the test. diff --git a/packages/browser/src/client/runner.ts b/packages/browser/src/client/runner.ts index c45f35dbc767..f9319c8bb0e1 100644 --- a/packages/browser/src/client/runner.ts +++ b/packages/browser/src/client/runner.ts @@ -1,4 +1,4 @@ -import type { File, TaskResult, Test } from '@vitest/runner' +import type { File, TaskResultPack, Test } from '@vitest/runner' import { rpc } from './rpc' import type { ResolvedConfig } from '#types' @@ -49,7 +49,7 @@ export function createBrowserRunner(original: any, coverageModule: CoverageHandl return rpc().onCollected(files) } - onTaskUpdate(task: [string, TaskResult | undefined][]): Promise { + onTaskUpdate(task: TaskResultPack[]): Promise { return rpc().onTaskUpdate(task) } diff --git a/packages/runner/src/collect.ts b/packages/runner/src/collect.ts index 273aa0ee95d6..656b600baeba 100644 --- a/packages/runner/src/collect.ts +++ b/packages/runner/src/collect.ts @@ -24,6 +24,7 @@ export async function collectTests(paths: string[], runner: VitestRunner): Promi mode: 'run', filepath, tasks: [], + meta: Object.create(null), projectName: config.name, } diff --git a/packages/runner/src/context.ts b/packages/runner/src/context.ts index 40c6706f4d21..b17781f3e49d 100644 --- a/packages/runner/src/context.ts +++ b/packages/runner/src/context.ts @@ -47,6 +47,7 @@ export function createTestContext(test: Test, runner: VitestRunner): TestContext } as unknown as TestContext context.meta = test + context.task = test context.onTestFailed = (fn) => { test.onFailed ||= [] diff --git a/packages/runner/src/run.ts b/packages/runner/src/run.ts index e72819b01504..fd889691055a 100644 --- a/packages/runner/src/run.ts +++ b/packages/runner/src/run.ts @@ -1,7 +1,7 @@ import limit from 'p-limit' import { getSafeTimers, shuffle } from '@vitest/utils' import type { VitestRunner } from './types/runner' -import type { File, HookCleanupCallback, HookListener, SequenceHooks, Suite, SuiteHooks, Task, TaskResult, TaskState, Test } from './types' +import type { File, HookCleanupCallback, HookListener, SequenceHooks, Suite, SuiteHooks, Task, TaskMeta, TaskResult, TaskResultPack, TaskState, Test } from './types' import { partitionSuiteChildren } from './utils/suite' import { getFn, getHooks } from './map' import { collectTests } from './collect' @@ -70,12 +70,12 @@ export async function callSuiteHook( return callbacks } -const packs = new Map() +const packs = new Map() let updateTimer: any let previousUpdate: Promise | undefined export function updateTask(task: Task, runner: VitestRunner) { - packs.set(task.id, task.result) + packs.set(task.id, [task.result, task.meta]) const { clearTimeout, setTimeout } = getSafeTimers() @@ -91,7 +91,14 @@ async function sendTasksUpdate(runner: VitestRunner) { await previousUpdate if (packs.size) { - const p = runner.onTaskUpdate?.(Array.from(packs)) + const taskPacks = Array.from(packs).map(([id, task]) => { + return [ + id, + task[0], + task[1], + ] + }) + const p = runner.onTaskUpdate?.(taskPacks) packs.clear() return p } diff --git a/packages/runner/src/suite.ts b/packages/runner/src/suite.ts index 0ab84ab18d72..2eaa9cf792e0 100644 --- a/packages/runner/src/suite.ts +++ b/packages/runner/src/suite.ts @@ -87,6 +87,7 @@ function createSuiteCollector(name: string, factory: SuiteFactory = () => { }, m fails: this.fails, retry: options?.retry, repeats: options?.repeats, + meta: Object.create(null), } as Omit as Test if (this.concurrent || concurrent) @@ -116,6 +117,7 @@ function createSuiteCollector(name: string, factory: SuiteFactory = () => { }, m name, type: 'custom', mode: self.only ? 'only' : self.skip ? 'skip' : self.todo ? 'todo' : 'run', + meta: Object.create(null), } tasks.push(task) return task @@ -150,6 +152,7 @@ function createSuiteCollector(name: string, factory: SuiteFactory = () => { }, m each, shuffle, tasks: [], + meta: Object.create(null), } setHooks(suite, createSuiteHooks()) diff --git a/packages/runner/src/types/runner.ts b/packages/runner/src/types/runner.ts index 694d6c70045d..1f79b96f1f79 100644 --- a/packages/runner/src/types/runner.ts +++ b/packages/runner/src/types/runner.ts @@ -1,4 +1,4 @@ -import type { File, SequenceHooks, SequenceSetupFiles, Suite, TaskResult, Test, TestContext } from './tasks' +import type { File, SequenceHooks, SequenceSetupFiles, Suite, TaskResultPack, Test, TestContext } from './tasks' export interface VitestRunnerConfig { root: string @@ -86,7 +86,7 @@ export interface VitestRunner { /** * Called, when a task is updated. The same as "onTaskUpdate" in a reporter, but this is running in the same thread as tests. */ - onTaskUpdate?(task: [string, TaskResult | undefined][]): Promise + onTaskUpdate?(task: TaskResultPack[]): Promise /** * Called before running all tests in collected paths. diff --git a/packages/runner/src/types/tasks.ts b/packages/runner/src/types/tasks.ts index 0c8bab18b301..7ff9c4e4b7b1 100644 --- a/packages/runner/src/types/tasks.ts +++ b/packages/runner/src/types/tasks.ts @@ -9,6 +9,7 @@ export interface TaskBase { id: string name: string mode: RunMode + meta: TaskMeta each?: boolean concurrent?: boolean shuffle?: boolean @@ -16,10 +17,11 @@ export interface TaskBase { file?: File result?: TaskResult retry?: number - meta?: any repeats?: number } +export interface TaskMeta {} + export interface TaskCustom extends TaskBase { type: 'custom' } @@ -40,7 +42,7 @@ export interface TaskResult { repeatCount?: number } -export type TaskResultPack = [id: string, result: TaskResult | undefined] +export type TaskResultPack = [id: string, result: TaskResult | undefined, meta: TaskMeta] export interface Suite extends TaskBase { type: 'suite' @@ -205,10 +207,10 @@ export type HookListener = (...args: T) => Await export type HookCleanupCallback = (() => Awaitable) | void export interface SuiteHooks { - beforeAll: HookListener<[Suite | File], HookCleanupCallback>[] - afterAll: HookListener<[Suite | File]>[] - beforeEach: HookListener<[TestContext & ExtraContext, Suite], HookCleanupCallback>[] - afterEach: HookListener<[TestContext & ExtraContext, Suite]>[] + beforeAll: HookListener<[Readonly], HookCleanupCallback>[] + afterAll: HookListener<[Readonly]>[] + beforeEach: HookListener<[TestContext & ExtraContext, Readonly], HookCleanupCallback>[] + afterEach: HookListener<[TestContext & ExtraContext, Readonly]>[] } export interface SuiteCollector { @@ -234,9 +236,16 @@ export interface RuntimeContext { export interface TestContext { /** * Metadata of the current test + * + * @deprecated Use `task` instead */ meta: Readonly + /** + * Metadata of the current test + */ + task: Readonly + /** * Extract hooks on test failed */ diff --git a/packages/vitest/src/node/state.ts b/packages/vitest/src/node/state.ts index bbfcb13a2087..af5d2702a2b4 100644 --- a/packages/vitest/src/node/state.ts +++ b/packages/vitest/src/node/state.ts @@ -117,9 +117,12 @@ export class StateManager { } updateTasks(packs: TaskResultPack[]) { - for (const [id, result] of packs) { - if (this.idMap.has(id)) - this.idMap.get(id)!.result = result + for (const [id, result, meta] of packs) { + const task = this.idMap.get(id) + if (task) { + task.result = result + task.meta = meta + } } } @@ -146,6 +149,7 @@ export class StateManager { result: { state: 'skip', }, + meta: {}, // Cancelled files have not yet collected tests tasks: [], }))) diff --git a/packages/vitest/src/typecheck/typechecker.ts b/packages/vitest/src/typecheck/typechecker.ts index ce1c4863afc6..1cf4176e8868 100644 --- a/packages/vitest/src/typecheck/typechecker.ts +++ b/packages/vitest/src/typecheck/typechecker.ts @@ -290,6 +290,6 @@ export class Typechecker { return Object.values(this._tests || {}) .map(({ file }) => getTasks(file)) .flat() - .map(i => [i.id, undefined] as TaskResultPack) + .map(i => [i.id, undefined, { typecheck: true }]) } } diff --git a/packages/vitest/src/types/global.ts b/packages/vitest/src/types/global.ts index 2dd5eec1ca81..664fbaef7004 100644 --- a/packages/vitest/src/types/global.ts +++ b/packages/vitest/src/types/global.ts @@ -34,6 +34,11 @@ declare module '@vitest/runner' { expect: ExpectStatic } + interface TaskMeta { + typecheck?: boolean + benchmark?: boolean + } + interface File { prepareDuration?: number environmentLoad?: number diff --git a/packages/vitest/src/types/tasks.ts b/packages/vitest/src/types/tasks.ts index d1fcdc66232e..d6bd456f8b30 100644 --- a/packages/vitest/src/types/tasks.ts +++ b/packages/vitest/src/types/tasks.ts @@ -21,4 +21,5 @@ export type { RuntimeContext, TestContext, OnTestFailedHandler, -} from '@vitest/runner/types' + TaskMeta, +} from '@vitest/runner' diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index cb665ace47f0..947c9db5c62e 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -259,7 +259,7 @@ importers: version: link:../../packages/ui jsdom: specifier: latest - version: 22.1.0 + version: 22.0.0 vite: specifier: ^4.2.1 version: 4.2.1(@types/node@18.16.3) @@ -318,7 +318,7 @@ importers: version: 13.3.0(react-dom@18.0.0)(react@18.0.0) '@types/node': specifier: latest - version: 20.2.5 + version: 20.2.3 '@types/react': specifier: latest version: 18.2.7 @@ -327,7 +327,7 @@ importers: version: 4.0.0(vite@4.2.1) jsdom: specifier: latest - version: 22.1.0 + version: 22.0.0 typescript: specifier: ^4.8.4 version: 4.8.4 @@ -388,10 +388,10 @@ importers: version: link:../../packages/ui happy-dom: specifier: latest - version: 9.20.3 + version: 9.1.9 jsdom: specifier: latest - version: 22.1.0 + version: 22.0.0 react-test-renderer: specifier: 17.0.2 version: 17.0.2(react@17.0.2) @@ -495,7 +495,7 @@ importers: version: 2.29.2 jsdom: specifier: latest - version: 22.1.0 + version: 22.0.0 vite: specifier: ^4.2.1 version: 4.2.1(@types/node@18.16.3) @@ -565,7 +565,7 @@ importers: version: 8.2.5(@babel/core@7.18.13)(webpack@5.74.0) jsdom: specifier: latest - version: 22.1.0 + version: 22.0.0 msw: specifier: ^0.49.2 version: 0.49.2(typescript@4.8.4) @@ -617,7 +617,7 @@ importers: version: link:../../packages/ui jsdom: specifier: latest - version: 22.1.0 + version: 22.0.0 typescript: specifier: ^4.8.4 version: 4.8.4 @@ -663,7 +663,7 @@ importers: version: 3.1.5 jsdom: specifier: latest - version: 22.1.0 + version: 22.0.0 msw: specifier: ^1.2.1 version: 1.2.1(typescript@5.0.4) @@ -684,7 +684,7 @@ importers: version: 2.3.2(vue@3.3.4) jsdom: specifier: latest - version: 22.1.0 + version: 22.0.0 vite: specifier: ^4.2.1 version: 4.2.1(@types/node@18.16.3) @@ -709,7 +709,7 @@ importers: version: 5.16.5 jsdom: specifier: latest - version: 22.1.0 + version: 22.0.0 solid-testing-library: specifier: ^0.5.0 version: 0.5.0(solid-js@1.5.2) @@ -727,19 +727,19 @@ importers: devDependencies: '@sveltejs/vite-plugin-svelte': specifier: ^2.0.0 - version: 2.0.0(svelte@3.59.1)(vite@4.2.1) + version: 2.0.0(svelte@3.58.0)(vite@4.2.1) '@testing-library/svelte': specifier: ^3.2.2 - version: 3.2.2(svelte@3.59.1) + version: 3.2.2(svelte@3.58.0) '@vitest/ui': specifier: latest version: link:../../packages/ui jsdom: specifier: latest - version: 22.1.0 + version: 22.0.0 svelte: specifier: latest - version: 3.59.1 + version: 3.58.0 vite: specifier: ^4.2.1 version: 4.2.1(@types/node@18.16.3) @@ -761,13 +761,13 @@ importers: version: 2.0.2(vue@3.3.4) jsdom: specifier: latest - version: 22.1.0 + version: 22.0.0 unplugin-auto-import: specifier: latest - version: 0.16.2(rollup@3.20.2) + version: 0.12.1(rollup@3.20.2) unplugin-vue-components: specifier: latest - version: 0.24.1(rollup@3.20.2)(vue@3.3.4) + version: 0.22.12(rollup@3.20.2)(vue@3.3.4) vite: specifier: ^4.2.1 version: 4.2.1(@types/node@18.16.3) @@ -789,7 +789,7 @@ importers: version: 2.0.0(vue@3.3.4) jsdom: specifier: latest - version: 22.1.0 + version: 22.0.0 vite: specifier: ^4.2.1 version: 4.2.1(@types/node@18.16.3) @@ -810,7 +810,7 @@ importers: version: 2.3.2(vue@3.3.4) jsdom: specifier: latest - version: 22.1.0 + version: 22.0.0 vite: specifier: ^4.2.1 version: 4.2.1(@types/node@18.16.3) @@ -835,7 +835,7 @@ importers: version: 1.3.0(vue-template-compiler@2.7.10)(vue@2.7.10) jsdom: specifier: latest - version: 22.1.0 + version: 22.0.0 vite: specifier: ^4.2.1 version: 4.2.1(@types/node@18.16.3) @@ -1412,7 +1412,7 @@ importers: version: link:../../packages/vitest webdriverio: specifier: latest - version: 8.10.5(typescript@5.0.4) + version: 8.10.2(typescript@5.0.4) test/base: devDependencies: @@ -1526,7 +1526,7 @@ importers: version: 2.3.2(vue@3.3.4) happy-dom: specifier: latest - version: 9.20.3 + version: 9.1.9 istanbul-lib-coverage: specifier: ^3.2.0 version: 3.2.0 @@ -1541,7 +1541,7 @@ importers: version: 3.3.4 webdriverio: specifier: latest - version: 8.10.5(typescript@5.0.4) + version: 8.10.2(typescript@5.0.4) test/css: devDependencies: @@ -1654,6 +1654,15 @@ importers: test/path-resolution-target: {} + test/public-api: + devDependencies: + '@vitest/browser': + specifier: workspace:* + version: link:../../packages/browser + vitest: + specifier: workspace:* + version: link:../../packages/vitest + test/related: devDependencies: vitest: @@ -1797,7 +1806,7 @@ importers: version: link:../../packages/vitest webdriverio: specifier: latest - version: 8.10.5(typescript@5.0.4) + version: 8.10.2(typescript@5.0.4) test/web-worker: devDependencies: @@ -1818,7 +1827,7 @@ importers: version: 3.2.0 jsdom: specifier: latest - version: 22.1.0 + version: 22.0.0 vitest: specifier: workspace:* version: link:../../packages/vitest @@ -6452,7 +6461,7 @@ packages: engines: {node: '>=14'} hasBin: true dependencies: - '@types/node': 20.2.5 + '@types/node': 18.16.3 playwright-core: 1.28.0 dev: true @@ -6525,8 +6534,8 @@ packages: - supports-color dev: true - /@puppeteer/browsers@1.3.0(typescript@5.0.4): - resolution: {integrity: sha512-an3QdbNPkuU6qpxpbssxAbjRLJcF+eP4L8UqIY3+6n0sbaVxw5pz7PiCLy9g32XEZuoamUlV5ZQPnA6FxvkIHA==} + /@puppeteer/browsers@1.0.1(typescript@5.0.4): + resolution: {integrity: sha512-9wkYhON9zBgtjYRE3FcokGCfjG25zjzNAYmsHpiWitRZ/4DeT3v125/fCUU66SaPJ4nUsxGNPgpS1TOcQ+8StA==} engines: {node: '>=16.0.0'} hasBin: true peerDependencies: @@ -8142,7 +8151,7 @@ packages: string.prototype.matchall: 4.0.7 dev: true - /@sveltejs/vite-plugin-svelte@2.0.0(svelte@3.59.1)(vite@4.2.1): + /@sveltejs/vite-plugin-svelte@2.0.0(svelte@3.58.0)(vite@4.2.1): resolution: {integrity: sha512-oUFrYQarRv4fppmxdrv00qw3wX8Ycdj0uv33MfpRZyR8K67dyxiOcHnqkB0zSy5sDJA8RC/2aNtYhXJ8NINVHQ==} engines: {node: ^14.18.0 || >= 16} peerDependencies: @@ -8153,8 +8162,8 @@ packages: deepmerge: 4.2.2 kleur: 4.1.5 magic-string: 0.27.0 - svelte: 3.59.1 - svelte-hmr: 0.15.1(svelte@3.59.1) + svelte: 3.58.0 + svelte-hmr: 0.15.1(svelte@3.58.0) vite: 4.2.1(@types/node@18.16.3) vitefu: 0.2.3(vite@4.2.1) transitivePeerDependencies: @@ -8278,14 +8287,14 @@ packages: react-dom: 18.2.0(react@18.2.0) dev: true - /@testing-library/svelte@3.2.2(svelte@3.59.1): + /@testing-library/svelte@3.2.2(svelte@3.58.0): resolution: {integrity: sha512-IKwZgqbekC3LpoRhSwhd0JswRGxKdAGkf39UiDXTywK61YyLXbCYoR831e/UUC6EeNW4hiHPY+2WuovxOgI5sw==} engines: {node: '>= 10'} peerDependencies: svelte: 3.x dependencies: '@testing-library/dom': 8.17.1 - svelte: 3.59.1 + svelte: 3.58.0 dev: true /@testing-library/user-event@13.5.0(@testing-library/dom@8.17.1): @@ -8464,13 +8473,13 @@ packages: resolution: {integrity: sha512-MxObHvNl4A69ofaTRU8DFqvgzzv8s9yRtaPPm5gud9HDNvpB3GPQFvNuTWAI59B9huVGV5jXYJwbCsmBsOGYWA==} dependencies: '@types/jsonfile': 6.1.1 - '@types/node': 20.2.5 + '@types/node': 18.16.3 dev: true /@types/fs-extra@9.0.13: resolution: {integrity: sha512-nEnwB++1u5lVDM2UI4c1+5R+FYaKfaAzS4OococimjVm3nQw3TuzH5UNsocrcTBbhnerblyHj4A49qXbIiZdpA==} dependencies: - '@types/node': 20.2.5 + '@types/node': 18.16.3 dev: true /@types/glob@7.2.0: @@ -8555,7 +8564,7 @@ packages: /@types/jsdom@21.1.1: resolution: {integrity: sha512-cZFuoVLtzKP3gmq9eNosUL1R50U+USkbLtUQ1bYVgl/lKp0FZM7Cq4aIHAL8oIvQ17uSHi7jXPtfDOdjPwBE7A==} dependencies: - '@types/node': 20.2.5 + '@types/node': 18.16.3 '@types/tough-cookie': 4.0.2 parse5: 7.1.2 dev: true @@ -8624,6 +8633,10 @@ packages: resolution: {integrity: sha512-46yIhxSe5xEaJZXWdIBP7GU4HDTG8/eo0qd9atdiL+lFpA03y8KS+lkTN834TWJj5767GbWv4n/P6efyTFt1Dw==} dev: false + /@types/node@20.2.3: + resolution: {integrity: sha512-pg9d0yC4rVNWQzX8U7xb4olIOFuuVL9za3bzMT2pu2SU0SNEi66i2qrvhE2qt0HvkhuCaWJu7pLNOt/Pj8BIrw==} + dev: true + /@types/node@20.2.5: resolution: {integrity: sha512-JJulVEQXmiY9Px5axXHeYGLSjhkZEnD+MDPDGbCbIAbMslkKwmygtZFy1X6s/075Yo94sf8GuSlFfPzysQrWZQ==} dev: true @@ -8654,7 +8667,7 @@ packages: /@types/prompts@2.4.4: resolution: {integrity: sha512-p5N9uoTH76lLvSAaYSZtBCdEXzpOOufsRjnhjVSrZGXikVGHX9+cc9ERtHRV4hvBKHyZb1bg4K+56Bd2TqUn4A==} dependencies: - '@types/node': 20.2.5 + '@types/node': 18.16.3 kleur: 3.0.3 dev: true @@ -8722,7 +8735,7 @@ packages: dependencies: '@types/prop-types': 15.7.5 '@types/scheduler': 0.16.2 - csstype: 3.1.0 + csstype: 3.1.2 /@types/resolve@1.17.1: resolution: {integrity: sha512-yy7HuzQhj0dhGpD8RLXSZWEkLsV9ibvxvi6EiJ3bkqLAO1RGo0WbkWQiwpRlSFymTJRz0d3k5LM3kkx8ArDbLw==} @@ -8841,7 +8854,7 @@ packages: /@types/ws@8.5.4: resolution: {integrity: sha512-zdQDHKUgcX/zBc4GrwsE/7dVdAD8JR4EuiAXiiUhhfyIJXXb2+PrGshFyeXWQPMmmZ2XxgaqclgpIC7eTXc1mg==} dependencies: - '@types/node': 20.2.5 + '@types/node': 18.16.3 dev: true /@types/yargs-parser@21.0.0: @@ -9284,7 +9297,7 @@ packages: '@babel/plugin-transform-react-jsx-self': 7.21.0(@babel/core@7.21.4) '@babel/plugin-transform-react-jsx-source': 7.19.6(@babel/core@7.21.4) react-refresh: 0.14.0 - vite: 4.2.1(@types/node@20.2.5) + vite: 4.2.1(@types/node@20.2.3) transitivePeerDependencies: - supports-color dev: true @@ -9387,7 +9400,7 @@ packages: '@vue/compiler-core': 3.3.4 '@vue/compiler-dom': 3.3.4 '@vue/compiler-sfc': 3.3.4 - '@vue/reactivity': 3.3.4 + '@vue/reactivity': 3.2.47 '@vue/shared': 3.3.4 dev: true @@ -9839,13 +9852,13 @@ packages: vue-demi: 0.14.0(vue@3.2.39) dev: false - /@wdio/config@8.10.4: - resolution: {integrity: sha512-AjIGkQAMDduzIsl2Sz8B3YOkedf6c2gdI0GftvRSzdwke10XsJuISyP+SPvhzserxHAOIpK5u0fiWXw4x7WYbA==} + /@wdio/config@8.10.2: + resolution: {integrity: sha512-CBPyxay3vVlAnwF+Dv2zsM4QMOVg8rOiD1HAdm9BilwbID2RnLF5i0IYNIFsAblhSZQhXkn5BXAcFSEIVHwOgA==} engines: {node: ^16.13 || >=18} dependencies: '@wdio/logger': 8.6.6 - '@wdio/types': 8.10.4 - '@wdio/utils': 8.10.4 + '@wdio/types': 8.10.2 + '@wdio/utils': 8.10.2 decamelize: 6.0.0 deepmerge-ts: 5.0.0 glob: 10.2.2 @@ -9899,8 +9912,8 @@ packages: '@types/node': 18.16.3 dev: true - /@wdio/types@8.10.4: - resolution: {integrity: sha512-aLJ1QQW+hhALeRK3bvMLjIrlUVyhOs3Od+91pR4Z4pLwyeNG1bJZCJRD5bAJK/mm7CnFa0NsdixPS9jJxZcRrw==} + /@wdio/types@8.10.2: + resolution: {integrity: sha512-d0oWX82CVE4Z7ipD2GpPhaeFKh7JDaDNzgiQpPYkS74TBSqQV+yrqvqRlrmHD4nmRgFwnjtD8AFOo7ackeURhg==} engines: {node: ^16.13 || >=18} dependencies: '@types/node': 20.2.5 @@ -9913,12 +9926,12 @@ packages: '@types/node': 18.16.3 dev: true - /@wdio/utils@8.10.4: - resolution: {integrity: sha512-ZkUnNMuurO+Zw2Ert1V+C+W5u+aUWTPDyCb5eHMfwIIxEVis/AbwYtuFCxp0Luj5asmZbukb+UryCfoVt6kdmg==} + /@wdio/utils@8.10.2: + resolution: {integrity: sha512-lMIqztb4Mmi2arsM089SDfubx9v0/a/7Ul+vMOt7P19ZEogiWnbELmIs/CaVOxjEcgaNjXM2s56ORKnAObJfgg==} engines: {node: ^16.13 || >=18} dependencies: '@wdio/logger': 8.6.6 - '@wdio/types': 8.10.4 + '@wdio/types': 8.10.2 import-meta-resolve: 3.0.0 p-iteration: 1.1.8 dev: true @@ -11500,7 +11513,7 @@ packages: dotenv: 16.0.3 giget: 1.1.2 jiti: 1.18.2 - mlly: 1.2.0 + mlly: 1.3.0 pathe: 1.1.0 pkg-types: 1.0.3 rc9: 2.0.1 @@ -11901,8 +11914,8 @@ packages: mitt: 3.0.0 dev: true - /chromium-bidi@0.4.9(devtools-protocol@0.0.1120988): - resolution: {integrity: sha512-u3DC6XwgLCA9QJ5ak1voPslCmacQdulZNCPsI3qNXxSnEcZS7DFIbww+5RM2bznMEje7cc0oydavRLRvOIZtHw==} + /chromium-bidi@0.4.7(devtools-protocol@0.0.1120988): + resolution: {integrity: sha512-6+mJuFXwTMU6I3vYLs6IL8A1DyQTPjCfIL971X0aMPVGRbGnNfl6i6Cl0NMbxi2bRYLGESt9T2ZIMRM5PAEcIQ==} peerDependencies: devtools-protocol: '*' dependencies: @@ -12437,14 +12450,6 @@ packages: transitivePeerDependencies: - encoding - /cross-fetch@3.1.6: - resolution: {integrity: sha512-riRvo06crlE8HiqOwIpQhxwdOk4fOeR7FVM/wXoxchFEqMNUjvbs3bfo4OTgMEMHzppd4DxFBDbyySj8Cv781g==} - dependencies: - node-fetch: 2.6.11 - transitivePeerDependencies: - - encoding - dev: true - /cross-spawn@5.1.0: resolution: {integrity: sha512-pTgQJ5KC0d2hcY8eyL1IzlBPYjTkyH72XRZPnLyKus2mBfNjQs3klqbJU2VILqZryAZUt9JOb3h/mWMy23/f5A==} dependencies: @@ -13117,28 +13122,28 @@ packages: resolution: {integrity: sha512-LF+0k1kYkrx2dZsvjLyNY2ySydz4lCy/xFvjuI5mCFGnepk5hC9iXbsdFk6jYma0ZvXaTxl3sGTiVr/GC0knyQ==} dev: true - /devtools-protocol@0.0.1146845: - resolution: {integrity: sha512-i1M5hKmaEO49cQk1YN21YRwxlmIR7ZpeteOgvU2cLhHPkP3Il95x2Fif45yOD6jUcUbzpdoKoEFJ4ylw7KHHAw==} + /devtools-protocol@0.0.1138159: + resolution: {integrity: sha512-IVXe1ZEQJWkMkeg10hRoZu3luP054z8USOpBIyorCTTABKVg0gBGt4rmwjGmThMEKaTb4nEmjVJkZ3/YxU0whA==} dev: true /devtools-protocol@0.0.981744: resolution: {integrity: sha512-0cuGS8+jhR67Fy7qG3i3Pc7Aw494sb9yG9QgpG97SFVWwolgYjlhJg7n+UaHxOQT30d1TYu/EYe9k01ivLErIg==} dev: true - /devtools@8.10.5(typescript@5.0.4): - resolution: {integrity: sha512-+Fc2RduaLSsCwOza6OtSUYsYbXuRkTmMfGszwjoPppMJvyQTn19A/ku1P9M901smNlqWZ1eftJpUDMhZpqWrxQ==} + /devtools@8.10.2(typescript@5.0.4): + resolution: {integrity: sha512-pvnTf0GtY1ILgBBxjGpQmwmiIklPQFQNirW4deluoLnhKLt6ekdKjYRLoK7goNN0rYPx7R/KK6Aqe5mgWKxBaA==} engines: {node: ^16.13 || >=18} dependencies: '@types/node': 20.2.5 - '@wdio/config': 8.10.4 + '@wdio/config': 8.10.2 '@wdio/logger': 8.6.6 '@wdio/protocols': 8.10.2 - '@wdio/types': 8.10.4 - '@wdio/utils': 8.10.4 + '@wdio/types': 8.10.2 + '@wdio/utils': 8.10.2 chrome-launcher: 0.15.1 edge-paths: 3.0.5 import-meta-resolve: 3.0.0 - puppeteer-core: 20.3.0(typescript@5.0.4) + puppeteer-core: 20.1.1(typescript@5.0.4) query-selector-shadow-dom: 1.0.1 ua-parser-js: 1.0.34 uuid: 9.0.0 @@ -15853,8 +15858,8 @@ packages: uglify-js: 3.17.0 dev: true - /happy-dom@9.10.7: - resolution: {integrity: sha512-AF9qCTEDmwY+4Rc+YQ9mHSFuw7dxwhLeSnNMJWGKUsOz3VWsC7O9kniuil5yVgnpx9UIzAjtK9UdbuRKMSGfSQ==} + /happy-dom@9.1.9: + resolution: {integrity: sha512-OMbnoknA7iNNG/5fwt1JckCKc53QLLFo2ljzit1pCV9SC1TYwcQj0obq0QUTeqIf2p2skbFG69bo19YoSj/1DA==} dependencies: css.escape: 1.5.1 he: 1.2.0 @@ -15864,11 +15869,11 @@ packages: whatwg-mimetype: 3.0.0 dev: true - /happy-dom@9.20.3: - resolution: {integrity: sha512-eBsgauT435fXFvQDNcmm5QbGtYzxEzOaX35Ia+h6yP/wwa4xSWZh1CfP+mGby8Hk6Xu59mTkpyf72rUXHNxY7A==} + /happy-dom@9.10.7: + resolution: {integrity: sha512-AF9qCTEDmwY+4Rc+YQ9mHSFuw7dxwhLeSnNMJWGKUsOz3VWsC7O9kniuil5yVgnpx9UIzAjtK9UdbuRKMSGfSQ==} dependencies: css.escape: 1.5.1 - entities: 4.5.0 + he: 1.2.0 iconv-lite: 0.6.3 webidl-conversions: 7.0.0 whatwg-encoding: 2.0.0 @@ -17927,8 +17932,8 @@ packages: - utf-8-validate dev: true - /jsdom@22.1.0: - resolution: {integrity: sha512-/9AVW7xNbsBv6GfWho4TTNjEo9fe6Zhf9O7s0Fhhr3u+awPwAJMKwAMXnkk5vBxflqLW9hTHX/0cs+P3gW+cQw==} + /jsdom@22.0.0: + resolution: {integrity: sha512-p5ZTEb5h+O+iU02t0GfEjAnkdYPrQSkfuTSMkMYyIoMvUNEHsbG0bHHbfXIcfTqD2UfvjQX7mmgiFsyRwGscVw==} engines: {node: '>=16'} peerDependencies: canvas: ^2.5.0 @@ -18916,13 +18921,6 @@ packages: brace-expansion: 2.0.1 dev: true - /minimatch@9.0.1: - resolution: {integrity: sha512-0jWhJpD/MdhPXwPuiRkCbfYfSKp2qnn2eOc279qI7f+osl/l+prKSrvhg157zSYvx/1nmgn2NqdT6k2Z7zSH9w==} - engines: {node: '>=16 || 14 >=14.17'} - dependencies: - brace-expansion: 2.0.1 - dev: true - /minimist@1.2.7: resolution: {integrity: sha512-bzfL1YUZsP41gmu/qjrEk0Q6i2ix/cVeAhbCbqH9u3zYutS1cLg00qhrD0M2MVdCcx4Sc0UpP2eBWo9rotpq6g==} dev: true @@ -20733,8 +20731,8 @@ packages: - utf-8-validate dev: true - /puppeteer-core@20.3.0(typescript@5.0.4): - resolution: {integrity: sha512-264pBrIui5bO6NJeOcbJrLa0OCwmA4+WK00JMrLIKTfRiqe2gx8KWTzLsjyw/bizErp3TKS7vt/I0i5fTC+mAw==} + /puppeteer-core@20.1.1(typescript@5.0.4): + resolution: {integrity: sha512-iB9F2Om8J+nU4qi30oYw0hMWOw6eQN7kFkLLI/u3UvxONOCx5o0KmM6+byaK2/QGIuQu2ly1mPaJnC1DyoW07Q==} engines: {node: '>=16.0.0'} peerDependencies: typescript: '>= 4.7.4' @@ -20742,12 +20740,17 @@ packages: typescript: optional: true dependencies: - '@puppeteer/browsers': 1.3.0(typescript@5.0.4) - chromium-bidi: 0.4.9(devtools-protocol@0.0.1120988) - cross-fetch: 3.1.6 + '@puppeteer/browsers': 1.0.1(typescript@5.0.4) + chromium-bidi: 0.4.7(devtools-protocol@0.0.1120988) + cross-fetch: 3.1.5 debug: 4.3.4(supports-color@8.1.1) devtools-protocol: 0.0.1120988 + extract-zip: 2.0.1(supports-color@8.1.1) + https-proxy-agent: 5.0.1 + proxy-from-env: 1.1.0 + tar-fs: 2.1.1 typescript: 5.0.4 + unbzip2-stream: 1.4.3 ws: 8.13.0 transitivePeerDependencies: - bufferutil @@ -22836,17 +22839,17 @@ packages: resolution: {integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==} engines: {node: '>= 0.4'} - /svelte-hmr@0.15.1(svelte@3.59.1): + /svelte-hmr@0.15.1(svelte@3.58.0): resolution: {integrity: sha512-BiKB4RZ8YSwRKCNVdNxK/GfY+r4Kjgp9jCLEy0DuqAKfmQtpL38cQK3afdpjw4sqSs4PLi3jIPJIFp259NkZtA==} engines: {node: ^12.20 || ^14.13.1 || >= 16} peerDependencies: svelte: '>=3.19.0' dependencies: - svelte: 3.59.1 + svelte: 3.58.0 dev: true - /svelte@3.59.1: - resolution: {integrity: sha512-pKj8fEBmqf6mq3/NfrB9SLtcJcUvjYSWyePlfCqN9gujLB25RitWK8PvFzlwim6hD/We35KbPlRteuA6rnPGcQ==} + /svelte@3.58.0: + resolution: {integrity: sha512-brIBNNB76mXFmU/Kerm4wFnkskBbluBDCjx/8TcpYRb298Yh2dztS2kQ6bhtjMcvUhd5ynClfwpz5h2gnzdQ1A==} engines: {node: '>= 8'} dev: true @@ -23629,6 +23632,24 @@ packages: vfile: 4.2.1 dev: true + /unimport@1.3.0(rollup@3.20.2): + resolution: {integrity: sha512-fOkrdxglsHd428yegH0wPH/6IfaSdDeMXtdRGn6en/ccyzc2aaoxiUTMrJyc6Bu+xoa18RJRPMfLUHEzjz8atw==} + dependencies: + '@rollup/pluginutils': 5.0.2(rollup@3.20.2) + escape-string-regexp: 5.0.0 + fast-glob: 3.2.12 + local-pkg: 0.4.3 + magic-string: 0.27.0 + mlly: 1.3.0 + pathe: 1.1.0 + pkg-types: 1.0.3 + scule: 1.0.0 + strip-literal: 1.0.1 + unplugin: 1.3.1 + transitivePeerDependencies: + - rollup + dev: true + /unimport@3.0.6(rollup@3.20.2): resolution: {integrity: sha512-GYxGJ1Bri1oqx8VFDjdgooGzeK7jBk3bvhXmamTIpu3nONOcUMGwZbX7X0L5RA7OWMXpR4vzpSQP7pXUzJg1/Q==} dependencies: @@ -23837,32 +23858,27 @@ packages: engines: {node: '>= 0.8'} dev: true - /unplugin-auto-import@0.15.3(@vueuse/core@10.1.2)(rollup@3.20.2): - resolution: {integrity: sha512-RLT8SqbPn4bT7yBshZId0uPSofKWnwr66RyDaxWaFb/+f7OTDOWAsVNz+hOQLBWSjvbekr2xZY9ccS8TDHJbCQ==} + /unplugin-auto-import@0.12.1(rollup@3.20.2): + resolution: {integrity: sha512-J/3ZORq5YGKG+8D5vLLOgqaHNK77izlVN07mQ752yRLqBNDbJiwPRSnUwwYqH5N6rDay1SqnJCHaUdbJ9QMI2w==} engines: {node: '>=14'} peerDependencies: - '@nuxt/kit': ^3.2.2 '@vueuse/core': '*' peerDependenciesMeta: - '@nuxt/kit': - optional: true '@vueuse/core': optional: true dependencies: '@antfu/utils': 0.7.2 '@rollup/pluginutils': 5.0.2(rollup@3.20.2) - '@vueuse/core': 10.1.2(vue@3.2.47) local-pkg: 0.4.3 - magic-string: 0.30.0 - minimatch: 9.0.0 - unimport: 3.0.6(rollup@3.20.2) + magic-string: 0.27.0 + unimport: 1.3.0(rollup@3.20.2) unplugin: 1.3.1 transitivePeerDependencies: - rollup dev: true - /unplugin-auto-import@0.16.2(rollup@3.20.2): - resolution: {integrity: sha512-t5f+xArJZRsfgF8Zftc2JFTJJTo7BPkPSeLQUXt6xxambnwWBer8vpEgwaCYrR50MIm5mjmhjebt33OZXIW0uQ==} + /unplugin-auto-import@0.15.3(@vueuse/core@10.1.2)(rollup@3.20.2): + resolution: {integrity: sha512-RLT8SqbPn4bT7yBshZId0uPSofKWnwr66RyDaxWaFb/+f7OTDOWAsVNz+hOQLBWSjvbekr2xZY9ccS8TDHJbCQ==} engines: {node: '>=14'} peerDependencies: '@nuxt/kit': ^3.2.2 @@ -23875,37 +23891,36 @@ packages: dependencies: '@antfu/utils': 0.7.2 '@rollup/pluginutils': 5.0.2(rollup@3.20.2) + '@vueuse/core': 10.1.2(vue@3.2.47) local-pkg: 0.4.3 magic-string: 0.30.0 - minimatch: 9.0.1 - unimport: 3.0.7(rollup@3.20.2) + minimatch: 9.0.0 + unimport: 3.0.6(rollup@3.20.2) unplugin: 1.3.1 transitivePeerDependencies: - rollup dev: true - /unplugin-vue-components@0.24.1(rollup@2.79.1)(vue@3.3.4): - resolution: {integrity: sha512-T3A8HkZoIE1Cja95xNqolwza0yD5IVlgZZ1PVAGvVCx8xthmjsv38xWRCtHtwl+rvZyL9uif42SRkDGw9aCfMA==} + /unplugin-vue-components@0.22.12(rollup@3.20.2)(vue@3.3.4): + resolution: {integrity: sha512-FxyzsuBvMCYPIk+8cgscGBQ345tvwVu+qY5IhE++eorkyvA4Z1TiD/HCiim+Kbqozl10i4K+z+NCa2WO2jexRA==} engines: {node: '>=14'} peerDependencies: '@babel/parser': ^7.15.8 - '@nuxt/kit': ^3.2.2 vue: 2 || 3 peerDependenciesMeta: '@babel/parser': optional: true - '@nuxt/kit': - optional: true dependencies: '@antfu/utils': 0.7.2 - '@rollup/pluginutils': 5.0.2(rollup@2.79.1) + '@rollup/pluginutils': 5.0.2(rollup@3.20.2) chokidar: 3.5.3 debug: 4.3.4(supports-color@8.1.1) fast-glob: 3.2.12 local-pkg: 0.4.3 - magic-string: 0.30.0 - minimatch: 7.4.2 + magic-string: 0.27.0 + minimatch: 5.1.1 resolve: 1.22.1 + unimport: 3.0.7(rollup@3.20.2) unplugin: 1.3.1 vue: 3.3.4 transitivePeerDependencies: @@ -23913,7 +23928,7 @@ packages: - supports-color dev: true - /unplugin-vue-components@0.24.1(rollup@3.20.2)(vue@3.2.47): + /unplugin-vue-components@0.24.1(rollup@2.79.1)(vue@3.3.4): resolution: {integrity: sha512-T3A8HkZoIE1Cja95xNqolwza0yD5IVlgZZ1PVAGvVCx8xthmjsv38xWRCtHtwl+rvZyL9uif42SRkDGw9aCfMA==} engines: {node: '>=14'} peerDependencies: @@ -23927,7 +23942,7 @@ packages: optional: true dependencies: '@antfu/utils': 0.7.2 - '@rollup/pluginutils': 5.0.2(rollup@3.20.2) + '@rollup/pluginutils': 5.0.2(rollup@2.79.1) chokidar: 3.5.3 debug: 4.3.4(supports-color@8.1.1) fast-glob: 3.2.12 @@ -23936,13 +23951,13 @@ packages: minimatch: 7.4.2 resolve: 1.22.1 unplugin: 1.3.1 - vue: 3.2.47 + vue: 3.3.4 transitivePeerDependencies: - rollup - supports-color dev: true - /unplugin-vue-components@0.24.1(rollup@3.20.2)(vue@3.3.4): + /unplugin-vue-components@0.24.1(rollup@3.20.2)(vue@3.2.47): resolution: {integrity: sha512-T3A8HkZoIE1Cja95xNqolwza0yD5IVlgZZ1PVAGvVCx8xthmjsv38xWRCtHtwl+rvZyL9uif42SRkDGw9aCfMA==} engines: {node: '>=14'} peerDependencies: @@ -23965,7 +23980,7 @@ packages: minimatch: 7.4.2 resolve: 1.22.1 unplugin: 1.3.1 - vue: 3.3.4 + vue: 3.2.47 transitivePeerDependencies: - rollup - supports-color @@ -24342,7 +24357,7 @@ packages: fsevents: 2.3.2 dev: false - /vite@4.2.1(@types/node@20.2.5): + /vite@4.2.1(@types/node@20.2.3): resolution: {integrity: sha512-7MKhqdy0ISo4wnvwtqZkjke6XN4taqQ2TBaTccLIpOKv7Vp2h4Y+NpmWCnGDeSvvn45KxvWgGyb0MkHvY1vgbg==} engines: {node: ^14.18.0 || >=16.0.0} hasBin: true @@ -24367,7 +24382,7 @@ packages: terser: optional: true dependencies: - '@types/node': 20.2.5 + '@types/node': 20.2.3 esbuild: 0.17.15 postcss: 8.4.21 resolve: 1.22.1 @@ -24672,17 +24687,17 @@ packages: resolution: {integrity: sha512-wYxSGajtmoP4WxfejAPIr4l0fVh+jeMXZb08wNc0tMg6xsfZXj3cECqIK0G7ZAqUq0PP8WlMDtaOGVBTAWztNw==} dev: true - /webdriver@8.10.4: - resolution: {integrity: sha512-Dvv6LzylhbXN16roQuKzG2W+/IyTLKWFz4tzkwXotd48CAkdy8d2Ds0gVcwo8JpyZQweEKylGdvNC3W50aPLMQ==} + /webdriver@8.10.2: + resolution: {integrity: sha512-xwoY+JtmEwN9hFx00V08PBlLLbuOHnPcO78ImPn6IzlhDW960f/6C8fzP0oiJkDyjQ7U81gHU6Mjkp/tBNpKEQ==} engines: {node: ^16.13 || >=18} dependencies: '@types/node': 20.2.5 '@types/ws': 8.5.4 - '@wdio/config': 8.10.4 + '@wdio/config': 8.10.2 '@wdio/logger': 8.6.6 '@wdio/protocols': 8.10.2 - '@wdio/types': 8.10.4 - '@wdio/utils': 8.10.4 + '@wdio/types': 8.10.2 + '@wdio/utils': 8.10.2 deepmerge-ts: 5.0.0 got: 12.6.0 ky: 0.33.3 @@ -24712,35 +24727,35 @@ packages: - utf-8-validate dev: true - /webdriverio@8.10.5(typescript@5.0.4): - resolution: {integrity: sha512-XwlpWLbTOySDP0DFlZJn13G7rlz9OpYwbuWtpalypV4V7gpsOx0UfJXdO/TcaDWB8ZQ+b7YPg5zDYOVKwG1Whg==} + /webdriverio@8.10.2(typescript@5.0.4): + resolution: {integrity: sha512-VrA9oFI17sBhPDvMwywve4CwODHi5FEzjn9gyInN7Nv+6tVaDC+PVGsKV7ZQQSj5C0bzPCn3IgXSoM1Qqn3XeQ==} engines: {node: ^16.13 || >=18} dependencies: '@types/node': 20.2.5 - '@wdio/config': 8.10.4 + '@wdio/config': 8.10.2 '@wdio/logger': 8.6.6 '@wdio/protocols': 8.10.2 '@wdio/repl': 8.10.1 - '@wdio/types': 8.10.4 - '@wdio/utils': 8.10.4 + '@wdio/types': 8.10.2 + '@wdio/utils': 8.10.2 archiver: 5.3.1 aria-query: 5.0.2 css-shorthand-properties: 1.1.1 css-value: 0.0.1 - devtools: 8.10.5(typescript@5.0.4) - devtools-protocol: 0.0.1146845 + devtools: 8.10.2(typescript@5.0.4) + devtools-protocol: 0.0.1138159 grapheme-splitter: 1.0.4 import-meta-resolve: 3.0.0 is-plain-obj: 4.1.0 lodash.clonedeep: 4.5.0 lodash.zip: 4.2.0 - minimatch: 9.0.1 - puppeteer-core: 20.3.0(typescript@5.0.4) + minimatch: 9.0.0 + puppeteer-core: 20.1.1(typescript@5.0.4) query-selector-shadow-dom: 1.0.1 resq: 1.11.0 rgb2hex: 0.2.5 serialize-error: 8.1.0 - webdriver: 8.10.4 + webdriver: 8.10.2 transitivePeerDependencies: - bufferutil - encoding diff --git a/test/public-api/fixtures/custom.spec.ts b/test/public-api/fixtures/custom.spec.ts new file mode 100644 index 000000000000..6d604c5b15a4 --- /dev/null +++ b/test/public-api/fixtures/custom.spec.ts @@ -0,0 +1,16 @@ +import { afterAll, test } from 'vitest' + +declare module 'vitest' { + interface TaskMeta { + done?: boolean + custom?: string + } +} + +afterAll((suite) => { + suite.meta.done = true +}) + +test('custom', ({ task }) => { + task.meta.custom = 'some-custom-hanlder' +}) diff --git a/test/public-api/package.json b/test/public-api/package.json new file mode 100644 index 000000000000..f917f92ac653 --- /dev/null +++ b/test/public-api/package.json @@ -0,0 +1,11 @@ +{ + "name": "@vitest/test-public-api", + "private": true, + "scripts": { + "test": "vitest" + }, + "devDependencies": { + "@vitest/browser": "workspace:*", + "vitest": "workspace:*" + } +} diff --git a/test/public-api/tests/runner.spec.ts b/test/public-api/tests/runner.spec.ts new file mode 100644 index 000000000000..cd23f77ed655 --- /dev/null +++ b/test/public-api/tests/runner.spec.ts @@ -0,0 +1,70 @@ +import { expect, it } from 'vitest' +import type { File, TaskResultPack, UserConfig } from 'vitest' +import { resolve } from 'pathe' +import { runVitest } from '../../test-utils' + +it.each([ + { name: 'threads are enabled', threads: true }, + { name: 'threads are disabled', threads: false }, + { + name: 'running in the browser', + browser: { + enabled: true, + provider: 'playwright', + name: 'chromium', + headless: true, + }, + }, +] as UserConfig[])('passes down metadata when $name', async (config) => { + const taskUpdate: TaskResultPack[] = [] + const finishedFiles: File[] = [] + const { vitest, stdout } = await runVitest({ + root: resolve(__dirname, '..', 'fixtures'), + include: ['**/*.spec.ts'], + reporters: [ + 'verbose', + { + onTaskUpdate(packs) { + taskUpdate.push(...packs.filter(i => i[1]?.state === 'pass')) + }, + onFinished(files) { + finishedFiles.push(...files || []) + }, + }, + ], + ...config, + }) + + expect(stdout).toContain('custom.spec.ts > custom') + + const suiteMeta = { done: true } + const testMeta = { custom: 'some-custom-hanlder' } + + expect(taskUpdate).toHaveLength(2) + expect(finishedFiles).toHaveLength(1) + + const files = vitest?.state.getFiles() || [] + expect(files).toHaveLength(1) + + expect(taskUpdate).toContainEqual( + [ + expect.any(String), + expect.anything(), + suiteMeta, + ], + ) + + expect(taskUpdate).toContainEqual( + [ + expect.any(String), + expect.anything(), + testMeta, + ], + ) + + expect(finishedFiles[0].meta).toEqual(suiteMeta) + expect(finishedFiles[0].tasks[0].meta).toEqual(testMeta) + + expect(files[0].meta).toEqual(suiteMeta) + expect(files[0].tasks[0].meta).toEqual(testMeta) +}, 60_000) diff --git a/test/public-api/vitest.config.ts b/test/public-api/vitest.config.ts new file mode 100644 index 000000000000..80ffabbc0ae2 --- /dev/null +++ b/test/public-api/vitest.config.ts @@ -0,0 +1,7 @@ +import { defineConfig } from 'vitest/config' + +export default defineConfig({ + test: { + include: ['tests/**/*.spec.ts'], + }, +}) diff --git a/test/reporters/src/data-for-junit.ts b/test/reporters/src/data-for-junit.ts index 333660f91083..fa0a7f56400f 100644 --- a/test/reporters/src/data-for-junit.ts +++ b/test/reporters/src/data-for-junit.ts @@ -6,6 +6,7 @@ function createSuiteHavingFailedTestWithXmlInError(): File[] { id: '1223128da3', name: 'test/core/test/basic.test.ts', type: 'suite', + meta: {}, mode: 'run', filepath: '/vitest/test/core/test/basic.test.ts', result: { state: 'fail', duration: 145.99284195899963 }, @@ -17,6 +18,7 @@ function createSuiteHavingFailedTestWithXmlInError(): File[] { type: 'suite', name: 'suite', mode: 'run', + meta: {}, file, result: { state: 'pass', duration: 1.90183687210083 }, tasks: [], @@ -37,6 +39,7 @@ function createSuiteHavingFailedTestWithXmlInError(): File[] { type: 'test', name: 'test with xml in error', mode: 'run', + meta: {}, suite, fails: undefined, file, diff --git a/test/reporters/src/data.ts b/test/reporters/src/data.ts index 4c532793ffdf..e51c56c13e98 100644 --- a/test/reporters/src/data.ts +++ b/test/reporters/src/data.ts @@ -5,6 +5,7 @@ const file: File = { id: '1223128da3', name: 'test/core/test/basic.test.ts', type: 'suite', + meta: {}, mode: 'run', filepath: '/vitest/test/core/test/basic.test.ts', result: { state: 'fail', duration: 145.99284195899963 }, @@ -16,6 +17,7 @@ const suite: Suite = { type: 'suite', name: 'suite', mode: 'run', + meta: {}, file, result: { state: 'pass', duration: 1.90183687210083 }, tasks: [], @@ -27,6 +29,7 @@ const innerSuite: Suite = { name: 'inner suite', mode: 'run', file, + meta: {}, suite, result: { state: 'pass', duration: 1.90183687210083 }, tasks: [], @@ -59,6 +62,7 @@ const innerTasks: Task[] = [ mode: 'run', suite: innerSuite, fails: undefined, + meta: {}, file, result: { state: 'fail', @@ -81,6 +85,7 @@ const tasks: Task[] = [ mode: 'run', suite, fails: undefined, + meta: {}, file, result: { state: 'pass', duration: 1.0237109661102295 }, context: null as any, @@ -92,6 +97,7 @@ const tasks: Task[] = [ mode: 'skip', suite, fails: undefined, + meta: {}, file, result: undefined, context: null as any, @@ -103,6 +109,7 @@ const tasks: Task[] = [ mode: 'run', suite, fails: undefined, + meta: {}, file, result: { state: 'pass', duration: 100.50598406791687 }, context: null as any, @@ -114,6 +121,7 @@ const tasks: Task[] = [ mode: 'run', suite, fails: undefined, + meta: {}, file, result: { state: 'pass', duration: 20.184875011444092 }, context: null as any, @@ -125,6 +133,7 @@ const tasks: Task[] = [ mode: 'run', suite, fails: undefined, + meta: {}, file, result: { state: 'pass', duration: 0.33245420455932617 }, context: null as any, @@ -136,6 +145,7 @@ const tasks: Task[] = [ mode: 'run', suite, fails: undefined, + meta: {}, file, result: { state: 'pass', duration: 19.738605976104736 }, context: null as any, @@ -147,6 +157,7 @@ const tasks: Task[] = [ mode: 'run', suite, fails: undefined, + meta: {}, file, result: { state: 'pass', duration: 0.1923508644104004 }, context: null as any, @@ -166,6 +177,7 @@ const tasks: Task[] = [ mode: 'todo', suite, fails: undefined, + meta: {}, file, result: undefined, context: null as any, diff --git a/test/reporters/tests/__snapshots__/html.test.ts.snap b/test/reporters/tests/__snapshots__/html.test.ts.snap index c16b0a2c72ee..43e7be1930fe 100644 --- a/test/reporters/tests/__snapshots__/html.test.ts.snap +++ b/test/reporters/tests/__snapshots__/html.test.ts.snap @@ -9,6 +9,7 @@ exports[`html reporter > resolves to "failing" status for test file "json-fail" "environmentLoad": 0, "filepath": "/test/reporters/fixtures/json-fail.test.ts", "id": 0, + "meta": {}, "mode": "run", "name": "json-fail.test.ts", "prepareDuration": 0, @@ -36,6 +37,7 @@ exports[`html reporter > resolves to "failing" status for test file "json-fail" "type": "stdout", }, ], + "meta": {}, "mode": "run", "name": "should fail", "result": { @@ -92,6 +94,7 @@ exports[`html reporter > resolves to "failing" status for test file "json-fail" "suite": { "file": [Circular], "id": "", + "meta": {}, "mode": "run", "name": "", "tasks": [ @@ -131,6 +134,7 @@ exports[`html reporter > resolves to "passing" status for test file "all-passing "environmentLoad": 0, "filepath": "/test/reporters/fixtures/all-passing-or-skipped.test.ts", "id": 0, + "meta": {}, "mode": "run", "name": "all-passing-or-skipped.test.ts", "prepareDuration": 0, @@ -148,6 +152,7 @@ exports[`html reporter > resolves to "passing" status for test file "all-passing { "file": [Circular], "id": 0, + "meta": {}, "mode": "run", "name": "2 + 3 = 5", "result": { @@ -164,6 +169,7 @@ exports[`html reporter > resolves to "passing" status for test file "all-passing "suite": { "file": [Circular], "id": "", + "meta": {}, "mode": "run", "name": "", "tasks": [ @@ -171,6 +177,7 @@ exports[`html reporter > resolves to "passing" status for test file "all-passing { "file": [Circular], "id": "1111755131_1", + "meta": {}, "mode": "skip", "name": "3 + 3 = 6", "suite": [Circular], @@ -184,17 +191,20 @@ exports[`html reporter > resolves to "passing" status for test file "all-passing { "file": [Circular], "id": "1111755131_1", + "meta": {}, "mode": "skip", "name": "3 + 3 = 6", "suite": { "file": [Circular], "id": "", + "meta": {}, "mode": "run", "name": "", "tasks": [ { "file": [Circular], "id": 0, + "meta": {}, "mode": "run", "name": "2 + 3 = 5", "result": { diff --git a/test/reporters/tests/junit.test.ts b/test/reporters/tests/junit.test.ts index 168d51e25a65..a76a61aad0e3 100644 --- a/test/reporters/tests/junit.test.ts +++ b/test/reporters/tests/junit.test.ts @@ -10,6 +10,7 @@ test('calc the duration used by junit', () => { name: 'suite', mode: 'run', tasks: [], + meta: {}, } const task: Task = { id: '1', @@ -19,6 +20,7 @@ test('calc the duration used by junit', () => { result, context: null as any, suite, + meta: {}, } expect(getDuration(task)).toBe('0') result.duration = 0.12 diff --git a/test/test-utils/index.ts b/test/test-utils/index.ts index dadc05360c40..9cd8612e38d8 100644 --- a/test/test-utils/index.ts +++ b/test/test-utils/index.ts @@ -1,6 +1,7 @@ import { Console } from 'node:console' import { Writable } from 'node:stream' import { type UserConfig, type VitestRunMode, afterEach } from 'vitest' +import type { Vitest } from 'vitest/node' import { startVitest } from 'vitest/node' import { type Options, execa } from 'execa' import stripAnsi from 'strip-ansi' @@ -15,8 +16,9 @@ export async function runVitest(config: UserConfig, cliFilters: string[] = [], m const { getLogs, restore } = captureLogs() + let vitest: Vitest | undefined try { - await startVitest(mode, cliFilters, { + vitest = await startVitest(mode, cliFilters, { watch: false, reporters: ['verbose'], ...config, @@ -27,6 +29,7 @@ export async function runVitest(config: UserConfig, cliFilters: string[] = [], m stderr: `${getLogs().stderr}\n${e.message}`, stdout: getLogs().stdout, exitCode: process.exitCode, + vitest, } } finally { @@ -37,7 +40,7 @@ export async function runVitest(config: UserConfig, cliFilters: string[] = [], m process.exitCode = 0 process.exit = exit - return { ...getLogs(), exitCode } + return { ...getLogs(), exitCode, vitest } } function captureLogs() {