diff --git a/docs/.vitepress/config.ts b/docs/.vitepress/config.ts index 7bd7e3fec..3c9312dff 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 000000000..1e40a6a02 --- /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 c581c52b4..3b4320809 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 c45f35dbc..f9319c8bb 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 273aa0ee9..656b600ba 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 40c6706f4..b17781f3e 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 e72819b01..fd8896910 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 0ab84ab18..2eaa9cf79 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 694d6c700..1f79b96f1 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 0c8bab18b..7ff9c4e4b 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 bbfcb13a2..af5d2702a 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 ce1c4863a..1cf4176e8 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 2dd5eec1c..664fbaef7 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 d1fcdc662..d6bd456f8 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 cb665ace4..947c9db5c 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 000000000..6d604c5b1 --- /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 000000000..f917f92ac --- /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 000000000..cd23f77ed --- /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 000000000..80ffabbc0 --- /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 333660f91..fa0a7f564 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 4c532793f..e51c56c13 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 c16b0a2c7..43e7be193 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 168d51e25..a76a61aad 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 dadc05360..9cd8612e3 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() {