diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index e3faddaa..01718f6a 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -43,6 +43,8 @@ jobs: - name: test-e2e-legacy run: pnpm test-e2e --retry 2 + env: + TEST_LEGACY: true - uses: actions/upload-artifact@v4 if: always() diff --git a/CLAUDE.md b/CLAUDE.md new file mode 100644 index 00000000..b4df49fc --- /dev/null +++ b/CLAUDE.md @@ -0,0 +1,94 @@ +# CLAUDE.md + +This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository. + +## Project Overview + +This is the **Vitest extension for Visual Studio Code** - a VSCode extension that provides test running, debugging, and coverage capabilities for Vitest tests. The extension integrates with VSCode's native TestController API to provide a unified testing experience. + +## Architecture + +The project uses a monorepo structure with multiple packages that work together: + +- **packages/extension** - Main VSCode extension entry point and core logic +- **packages/shared** - Shared utilities and RPC communication between extension and workers +- **packages/worker** - New worker implementation for running Vitest processes +- **packages/worker-legacy** - Legacy worker implementation for older Vitest versions +- **samples/** - Sample projects for testing and demonstration + +### Key Components + +- **Extension Host** (packages/extension): Manages VSCode integration, test discovery, debugging, coverage +- **Worker Processes** (packages/worker*): Execute Vitest in isolated processes, handle test running and reporting +- **RPC Communication** (packages/shared): Bidirectional communication between extension and workers using birpc +- **API Abstraction**: Supports both child_process and terminal shell types for running Vitest + +## Development Commands + +### Building +```bash +pnpm build # Build for production (minified) +pnpm dev # Build in development mode with watch and sourcemap +pnpm vscode:prepublish # Prepare for publishing (runs build) +``` + +### Testing +```bash +pnpm test # Run unit tests (Mocha-based VSCode tests) +pnpm test:watch # Run unit tests in watch mode +pnpm test-e2e # Run end-to-end tests (Vitest-based) +``` + +### Code Quality +```bash +pnpm typecheck # TypeScript type checking +pnpm lint # Run ESLint +pnpm lint:fix # Run ESLint with auto-fix +``` + +### Packaging +```bash +pnpm package # Create .vsix package for distribution +``` + +## Package Manager + +Uses **pnpm** with workspaces. The project requires pnpm@10.11.1 as specified in package.json. + +## Build System + +- **tsup** - Main build tool for bundling TypeScript +- Multiple entry points: extension, workers, setup files +- Supports both CJS and ESM output formats +- External dependencies like 'vscode' and 'vitest' are excluded from bundles + +## Testing Infrastructure + +- **Unit Tests**: Mocha-based tests in `test/unit/` using `@vscode/test-cli` +- **E2E Tests**: Vitest-based tests in `test/e2e/` +- **VSCode Test Runner**: Uses `.vscode-test.mjs` configuration +- **Samples**: Multiple sample projects for testing different scenarios + +## Worker Architecture + +The extension uses a multi-process architecture: +- Extension runs in VSCode extension host +- Worker processes execute Vitest in isolation +- Communication via RPC (birpc) +- Supports both legacy and modern Vitest versions +- Can spawn workers via child_process or terminal + +## Key Configuration Files + +- `tsup.config.ts` - Build configuration with multiple entry points +- `pnpm-workspace.yaml` - Workspace and catalog definitions +- `.vscode-test.mjs` - VSCode test runner configuration +- `tsconfig.base.json` - Base TypeScript configuration + +## Development Notes + +- Extension activates on workspaces containing Vitest config files +- Supports both standalone configs and Vitest workspace configurations +- Uses static AST analysis for test discovery (experimentalStaticAstCollect) +- Integrates with VSCode's native testing UI and debugging capabilities +- Supports coverage collection and display diff --git a/package.json b/package.json index e7ccffa6..e9cb486f 100644 --- a/package.json +++ b/package.json @@ -315,21 +315,25 @@ }, "pnpm": { "overrides": { - "@vitest/browser": "^4.0.0-beta.8", - "@vitest/coverage": "^4.0.0-beta.8", - "@vitest/runner": "^4.0.0-beta.8", - "vitest": "^4.0.0-beta.8", + "@vitest/browser": "^4.0.0-beta.12", + "@vitest/coverage": "^4.0.0-beta.12", + "@vitest/runner": "^4.0.0-beta.12", + "@vitest/utils": "^4.0.0-beta.12", + "vitest": "^4.0.0-beta.12", "vitest-vscode-extension>@vitest/browser": "^3.2.0", "vitest-vscode-extension>@vitest/coverage": "^3.2.0", "vitest-vscode-extension>@vitest/runner": "^3.2.0", + "vitest-vscode-extension>@vitest/utils": "^3.2.0", "vitest-vscode-extension>vitest": "^3.2.0", "vitest-vscode-shared>@vitest/browser": "^3.2.0", "vitest-vscode-shared>@vitest/coverage": "^3.2.0", "vitest-vscode-shared>@vitest/runner": "^3.2.0", + "vitest-vscode-shared>@vitest/utils": "^3.2.0", "vitest-vscode-shared>vitest": "^3.2.0", "vitest-vscode-worker-legacy>@vitest/browser": "^3.2.0", "vitest-vscode-worker-legacy>@vitest/coverage": "^3.2.0", "vitest-vscode-worker-legacy>@vitest/runner": "^3.2.0", + "vitest-vscode-worker-legacy>@vitest/utils": "^3.2.0", "vitest-vscode-worker-legacy>vitest": "^3.2.0" } }, diff --git a/packages/extension/package.json b/packages/extension/package.json index 4e9847d5..fd55aa2c 100644 --- a/packages/extension/package.json +++ b/packages/extension/package.json @@ -3,6 +3,7 @@ "version": "0.0.0", "private": true, "dependencies": { + "@vitest/browser": "workspace:*", "vitest": "$vitest", "vitest-vscode-shared": "workspace:*" } diff --git a/packages/extension/src/api.ts b/packages/extension/src/api.ts index 153ec046..231e9da7 100644 --- a/packages/extension/src/api.ts +++ b/packages/extension/src/api.ts @@ -183,7 +183,11 @@ export class VitestFolderAPI { } waitForCoverageReport() { - return this.meta.rpc.waitForCoverageReport() + if (this.process.closed) + return + return this.meta.rpc.waitForCoverageReport().catch(() => { + // ignore if failed -- can only fail if rpc is closed + }) } async invalidateIstanbulTestModules(modules: string[] | null) { diff --git a/packages/extension/src/api/child_process.ts b/packages/extension/src/api/child_process.ts index e3da7d08..fba302fb 100644 --- a/packages/extension/src/api/child_process.ts +++ b/packages/extension/src/api/child_process.ts @@ -90,7 +90,7 @@ export async function createVitestProcess(pkg: VitestPackage) { vitest.on('exit', onExit) vitest.on('error', onError) - waitForWsConnection(wss, pkg, false, 'child_process', false) + waitForWsConnection(wss, pkg, 'child_process', false) .then((resolved) => { resolved.handlers.onStdout = (callback: (data: string) => void) => { stdoutCallbacks.add(callback) diff --git a/packages/extension/src/api/terminal.ts b/packages/extension/src/api/terminal.ts index cb96c873..9fa3582e 100644 --- a/packages/extension/src/api/terminal.ts +++ b/packages/extension/src/api/terminal.ts @@ -112,7 +112,7 @@ export async function createVitestTerminalProcess(pkg: VitestPackage): Promise { clearTimeout(timeout) }) - waitForWsConnection(wss, pkg, false, 'terminal', !!shellIntegration).then(resolve, reject) + waitForWsConnection(wss, pkg, 'terminal', !!shellIntegration).then(resolve, reject) }) log.info('[API]', `${formatPkg(pkg)} terminal process ${processId} created`) diff --git a/packages/extension/src/api/ws.ts b/packages/extension/src/api/ws.ts index ee423c08..c5fcaea4 100644 --- a/packages/extension/src/api/ws.ts +++ b/packages/extension/src/api/ws.ts @@ -1,11 +1,11 @@ -import type { WorkerEvent, WorkerRunnerOptions } from 'vitest-vscode-shared' +import type { WorkerEvent, WorkerRunnerDebugOptions, WorkerRunnerOptions } from 'vitest-vscode-shared' import type { WebSocket, WebSocketServer } from 'ws' import type { ResolvedMeta } from '../api' import type { VitestPackage } from './pkg' import { pathToFileURL } from 'node:url' import { gte } from 'semver' import { getConfig } from '../config' -import { finalCoverageFileName, setupFilePath } from '../constants' +import { browserSetupFilePath, finalCoverageFileName, setupFilePath } from '../constants' import { log } from '../log' import { createVitestRpc } from './rpc' @@ -16,7 +16,6 @@ export type WsConnectionMetadata = Omit & { export function waitForWsConnection( wss: WebSocketServer, pkg: VitestPackage, - debug: boolean, shellType: 'terminal' | 'child_process', hasShellIntegration: boolean, ) { @@ -25,7 +24,7 @@ export function waitForWsConnection( onWsConnection( ws, pkg, - debug, + false, shellType, hasShellIntegration, meta => resolve(meta), @@ -52,7 +51,7 @@ export function waitForWsConnection( export function onWsConnection( ws: WebSocket, pkg: VitestPackage, - debug: boolean, + debug: WorkerRunnerDebugOptions | boolean, shellType: 'terminal' | 'child_process', hasShellIntegration: boolean, onStart: (meta: WsConnectionMetadata) => unknown, @@ -132,7 +131,10 @@ export function onWsConnection( pnpLoader: pnpLoader && gte(process.version, '18.19.0') ? pathToFileURL(pnpLoader).toString() : undefined, - setupFilePath, + setupFilePaths: { + watcher: setupFilePath, + browserDebug: browserSetupFilePath, + }, finalCoverageFileName, }, debug, diff --git a/packages/extension/src/constants.ts b/packages/extension/src/constants.ts index ad4c42fe..a1d66b60 100644 --- a/packages/extension/src/constants.ts +++ b/packages/extension/src/constants.ts @@ -7,6 +7,7 @@ export const minimumNodeVersion = '18.0.0' export const distDir = __dirname export const workerPath = resolve(__dirname, 'worker.js') export const setupFilePath = resolve(__dirname, 'setupFile.mjs') +export const browserSetupFilePath = resolve(__dirname, 'browserSetupFile.mjs') export const configGlob = '**/*{vite,vitest}*.config*.{ts,js,mjs,cjs,cts,mts}' export const workspaceGlob = '**/*vitest.{workspace,projects}*.{ts,js,mjs,cjs,cts,mts,json}' diff --git a/packages/extension/src/debug.ts b/packages/extension/src/debug.ts index 43bdee58..70a627e9 100644 --- a/packages/extension/src/debug.ts +++ b/packages/extension/src/debug.ts @@ -3,6 +3,7 @@ import type { ExtensionWorkerProcess } from './api/types' import type { WsConnectionMetadata } from './api/ws' import type { ExtensionDiagnostic } from './diagnostic' import type { TestTree } from './testTree' +import crypto from 'node:crypto' import { createServer } from 'node:http' import { pathToFileURL } from 'node:url' import getPort from 'get-port' @@ -14,8 +15,12 @@ import { getConfig } from './config' import { workerPath } from './constants' import { log } from './log' import { TestRunner } from './runner' +import { getTestData, TestCase, TestFile, TestFolder, TestSuite } from './testTreeData' import { findNode } from './utils' +const DebugSessionName = 'Vitest' +const BrowserDebugSessionName = 'Vitest_Browser' + export async function debugTests( controller: vscode.TestController, tree: TestTree, @@ -40,13 +45,22 @@ export async function debugTests( log.info('[DEBUG]', 'Starting debugging session', runtimeExecutable, ...(runtimeArgs || [])) + const debugId = crypto.randomUUID() + const browserDebug = getBrowserDebugInfo(controller, request) + + const skipFiles = [ + ...(config.debugExclude || []), + '**/@vitest/{runner,utils}/*', + ] + const debugConfig = { - __name: 'Vitest', + __name: DebugSessionName, + __vitestId: debugId, type: config.shellType === 'terminal' ? 'node-terminal' : 'pwa-node', request: 'launch', name: 'Debug Tests', autoAttachChildProcesses: true, - skipFiles: config.debugExclude, + skipFiles, ...( config.debugOutFiles?.length ? { outFiles: config.debugOutFiles } @@ -114,7 +128,14 @@ export async function debugTests( ws => onWsConnection( ws, pkg, - true, + browserDebug + ? { + browser: browserDebug.browser, + // wdio support this only since Vitest beta-13 + port: config.debuggerPort ?? 9229, + host: 'localhost', + } + : true, config.shellType, false, async (metadata) => { @@ -137,6 +158,57 @@ export async function debugTests( await metadata.rpc.close() }) + if (browserDebug) { + const browserAttachConfig = { + __name: BrowserDebugSessionName, + __parentId: debugId, + request: 'attach', + name: `Debug Tests (${browserDebug.browser})`, + address: 'localhost', + port: config.debuggerPort ?? 9229, + ...( + config.debugOutFiles?.length + ? { outFiles: config.debugOutFiles } + : {} + ), + smartStep: true, + skipFiles, + cwd: pkg.cwd, + type: browserDebug.browser === 'edge' ? 'msedge' : 'chrome', + } + let parentSession: vscode.DebugSession | undefined + for (const session of debugManager.sessions.values()) { + if (session.configuration.__vitestId === debugId) { + parentSession = session + } + } + vscode.debug.startDebugging( + pkg.folder, + browserAttachConfig, + { + parentSession, + // this is required for the "restart" button to work + // TODO: but it still doesn't work + lifecycleManagedByParent: true, + compact: true, + }, + ).then( + (fullfilled) => { + metadata.rpc.onBrowserDebug(fullfilled).catch(() => {}) + if (fullfilled) { + log.info('[DEBUG] Secondary debug launch config started') + } + else { + log.error('[DEBUG] Secondary debug launch config failed') + } + }, + (error) => { + metadata.rpc.onBrowserDebug(false).catch(() => {}) + log.error('[DEBUG] Browser debugger failed to launch', error.message) + }, + ) + } + await runner.runTests(request, token) deferredPromise.resolve() @@ -165,14 +237,18 @@ export async function debugTests( const parent = session.parentSession // dispose all test runners - if (parent && parent.configuration.__name === 'Vitest') { + if ( + session.configuration.__name !== BrowserDebugSessionName + && parent + && parent.configuration.__name === DebugSessionName + ) { disposables.reverse().forEach(d => d.dispose()) disposables.length = 0 } }) const onDidTerminate = vscode.debug.onDidTerminateDebugSession((session) => { - if (session.configuration.__name !== 'Vitest') + if (session.configuration.__name !== DebugSessionName) return server.close() onDidTerminate.dispose() @@ -251,7 +327,7 @@ export class DebugManager { constructor() { vscode.debug.onDidStartDebugSession((session) => { - if (session.configuration.__name === 'Vitest') { + if (session.configuration.__name === DebugSessionName) { this.sessions.add(session) } }) @@ -261,3 +337,61 @@ export class DebugManager { }) } } + +function getBrowserDebugInfo(controller: vscode.TestController, request: vscode.TestRunRequest) { + let provider: string | undefined + let browser: string | undefined + + function traverse(testItem: vscode.TestItem) { + const data = getTestData(testItem) + + if (data instanceof TestFile) { + if (request.exclude?.includes(testItem)) { + return + } + + const options = data.metadata.browser + if (!options) { + return + } + // this can actually be supported, but should we? + if (provider && provider !== options.provider) { + throw new Error(`Cannot mix both "playwright" and "webdriverio" tests together.`) + } + + if (options.provider === 'playwright' && options.name !== 'chromium') { + throw new Error( + `VSCode can only debug tests running in the "chromium" browser. ${testItem.label} runs in ${options.name} instead.`, + ) + } + if (options.provider === 'webdriverio' && options.name !== 'chrome' && options.name !== 'edge') { + throw new Error( + `VSCode can only debug tests running in the "chrome" or "edge" browser. ${testItem.label} runs in ${options.name} instead.`, + ) + } + if (options.provider === 'preview') { + throw new Error(`Cannot debug tests running in the "preview" provider. Choose either "playwright" or "webdriverio" to be able to debug tests.`) + } + + provider = options.provider + browser = options.name + } + else if (data instanceof TestFolder) { + testItem.children.forEach(traverse) + } + else if (data instanceof TestCase || data instanceof TestSuite) { + if (testItem.parent) { + traverse(testItem.parent) + } + } + } + + if (request.include) { + request.include.forEach(traverse) + } + else { + controller.items.forEach(traverse) + } + + return provider && browser ? { provider, browser } : null +} diff --git a/packages/extension/src/extension.ts b/packages/extension/src/extension.ts index fd0cbb8f..1401a3d6 100644 --- a/packages/extension/src/extension.ts +++ b/packages/extension/src/extension.ts @@ -196,7 +196,9 @@ class VitestExtension { request, token, this.debugManager, - ) + ).catch((error) => { + vscode.window.showErrorMessage(error.message) + }) } this.runProfiles.set(`${api.id}:debug`, debugProfile) diff --git a/packages/extension/src/testTree.ts b/packages/extension/src/testTree.ts index e8f0accb..d725f430 100644 --- a/packages/extension/src/testTree.ts +++ b/packages/extension/src/testTree.ts @@ -1,5 +1,7 @@ import type { RunnerTask, RunnerTestFile } from 'vitest' +import type { ExtensionTestFileSpecification } from 'vitest-vscode-shared' import type { VitestFolderAPI } from './api' +import type { TestFileMetadata } from './testTreeData' import { realpathSync } from 'node:fs' import { resolve } from 'node:path' import { basename, dirname, normalize } from 'pathe' @@ -71,13 +73,13 @@ export class TestTree extends vscode.Disposable { } } - async discoverAllTestFiles(api: VitestFolderAPI, files: [project: string, file: string][]) { + async discoverAllTestFiles(api: VitestFolderAPI, files: ExtensionTestFileSpecification[]) { const folderItem = this.folderItems.get(normalize(api.workspaceFolder.uri.fsPath)) if (folderItem) folderItem.busy = false - for (const [project, file] of files) - this.getOrCreateFileTestItem(api, project, file) + for (const [file, metadata] of files) + this.getOrCreateFileTestItem(api, metadata, file) return files } @@ -139,7 +141,8 @@ export class TestTree extends vscode.Disposable { return folderItem } - getOrCreateFileTestItem(api: VitestFolderAPI, project: string, file: string) { + getOrCreateFileTestItem(api: VitestFolderAPI, metadata: TestFileMetadata, file: string) { + const project = metadata.project const normalizedFile = normalize(file) const fileId = `${normalizedFile}${project}` const cached = this.fileItems.get(fileId) @@ -164,7 +167,7 @@ export class TestTree extends vscode.Disposable { parentItem, normalizedFile, api, - project, + metadata, ) parentItem.children.add(testFileItem) this.fileItems.set(fileId, testFileItem) @@ -216,7 +219,7 @@ export class TestTree extends vscode.Disposable { return folderItem } - async watchTestFilesInWorkspace(api: VitestFolderAPI, testFiles: [prject: string, file: string][]) { + async watchTestFilesInWorkspace(api: VitestFolderAPI, testFiles: ExtensionTestFileSpecification[]) { await this.discoverAllTestFiles(api, testFiles) this.watcher.watchTestFilesInWorkspace(api) } @@ -298,7 +301,13 @@ export class TestTree extends vscode.Disposable { } collectFile(api: VitestFolderAPI, file: RunnerTestFile) { - const fileTestItem = this.getOrCreateFileTestItem(api, file.projectName || '', file.filepath) + const normalizedFile = normalize(file.filepath) + const fileId = `${normalizedFile}${file.projectName || ''}` + const fileTestItem = this.fileItems.get(fileId) + if (!fileTestItem) { + log.error(`Cannot find a file test item for ${file.filepath} in "${file.projectName || 'core'}" project.`) + return + } fileTestItem.error = undefined this.flatTestItems.set(file.id, fileTestItem) const data = getTestData(fileTestItem) as TestFile diff --git a/packages/extension/src/testTreeData.ts b/packages/extension/src/testTreeData.ts index 9e8d4c05..f718f494 100644 --- a/packages/extension/src/testTreeData.ts +++ b/packages/extension/src/testTreeData.ts @@ -47,17 +47,28 @@ export class TestFolder extends BaseTestData { } } +export interface TestFileMetadata { + project: string + pool: string + browser?: { + provider: string + name: string + } +} + export class TestFile extends BaseTestData { public readonly type = 'file' + public readonly project: string private constructor( item: vscode.TestItem, parent: vscode.TestItem, public readonly filepath: string, public readonly api: VitestFolderAPI, - public readonly project: string, + public readonly metadata: TestFileMetadata, ) { super(item, parent) + this.project = metadata.project } public static register( @@ -65,9 +76,9 @@ export class TestFile extends BaseTestData { parent: vscode.TestItem, filepath: string, api: VitestFolderAPI, - project: string, + metadata: TestFileMetadata, ) { - return addTestData(item, new TestFile(item, parent, filepath, api, project)) + return addTestData(item, new TestFile(item, parent, filepath, api, metadata)) } } diff --git a/packages/extension/src/worker/browserSetupFile.ts b/packages/extension/src/worker/browserSetupFile.ts new file mode 100644 index 00000000..db904fb9 --- /dev/null +++ b/packages/extension/src/worker/browserSetupFile.ts @@ -0,0 +1,7 @@ +import { commands, server } from '@vitest/browser/context' + +if (server.config.inspector.enabled) { + // @ts-expect-error __vscode_waitForDebugger is not defined + // eslint-disable-next-line antfu/no-top-level-await + await commands.__vscode_waitForDebugger() +} diff --git a/packages/extension/src/worker/index.ts b/packages/extension/src/worker/index.ts index 9b0910c9..88260619 100644 --- a/packages/extension/src/worker/index.ts +++ b/packages/extension/src/worker/index.ts @@ -53,7 +53,7 @@ emitter.on('message', async function onMessage(message: any) { ) worker.initRpc(rpc) reporter.initRpc(rpc) - emitter.ready(configs, workspaceSource) + emitter.ready(configs, workspaceSource, isOld) } catch (err: any) { emitter.error(err) diff --git a/packages/shared/src/emitter.ts b/packages/shared/src/emitter.ts index 1f06a010..186e5c1c 100644 --- a/packages/shared/src/emitter.ts +++ b/packages/shared/src/emitter.ts @@ -8,8 +8,8 @@ abstract class WorkerEventEmitter { abstract on(event: string, listener: (...args: any[]) => void): void abstract off(event: string, listener: (...args: any[]) => void): void - ready(configs: string[], workspaceSource: string | false) { - this.sendWorkerEvent({ type: 'ready', configs, workspaceSource }) + ready(configs: string[], workspaceSource: string | false, legacy: boolean) { + this.sendWorkerEvent({ type: 'ready', configs, workspaceSource, legacy }) } error(err: any) { diff --git a/packages/shared/src/index.ts b/packages/shared/src/index.ts index 5b8f31e9..51804ff1 100644 --- a/packages/shared/src/index.ts +++ b/packages/shared/src/index.ts @@ -14,8 +14,22 @@ export type ExtensionTestSpecification = [ file: string, ] +export interface ExtensionTestFileMetadata { + project: string + pool: string + browser?: { + provider: string + name: string + } +} + +export type ExtensionTestFileSpecification = [ + file: string, + ExtensionTestFileMetadata, +] + export interface ExtensionWorkerTransport { - getFiles: () => Promise + getFiles: () => Promise collectTests: (testFile: ExtensionTestSpecification[]) => Promise cancelRun: () => Promise // accepts files with the project or folders (project doesn't matter for them) @@ -35,6 +49,8 @@ export interface ExtensionWorkerTransport { onFilesChanged: (files: string[]) => void initRpc: (rpc: VitestWorkerRPC) => void + + onBrowserDebug: (fulfilled: boolean) => void } export interface ExtensionWorkerEvents { @@ -62,14 +78,23 @@ export interface WorkerInitMetadata { hasShellIntegration: boolean pnpApi?: string pnpLoader?: string - setupFilePath: string + setupFilePaths: { + watcher: string + browserDebug: string + } finalCoverageFileName: string } +export interface WorkerRunnerDebugOptions { + browser: string + port: number + host: string +} + export interface WorkerRunnerOptions { type: 'init' meta: WorkerInitMetadata - debug: boolean + debug?: WorkerRunnerDebugOptions | boolean astCollect: boolean } @@ -77,6 +102,7 @@ export interface EventReady { type: 'ready' configs: string[] workspaceSource: string | false + legacy: boolean } export interface EventDebug { diff --git a/packages/worker-legacy/package.json b/packages/worker-legacy/package.json index 6d4a3cea..74cc617e 100644 --- a/packages/worker-legacy/package.json +++ b/packages/worker-legacy/package.json @@ -3,6 +3,7 @@ "version": "0.0.0", "private": true, "dependencies": { + "@vitest/utils": "catalog:", "vitest": "$vitest", "vitest-vscode-shared": "workspace:*" } diff --git a/packages/worker-legacy/src/index.ts b/packages/worker-legacy/src/index.ts index 35d1b909..6aebdf33 100644 --- a/packages/worker-legacy/src/index.ts +++ b/packages/worker-legacy/src/index.ts @@ -12,7 +12,12 @@ export async function initVitest( ) { const meta = data.meta const reporter = new VSCodeReporter({ - setupFilePath: meta.setupFilePath, + setupFilePaths: [ + typeof data.debug === 'object' && data.debug.browser + ? meta.setupFilePaths.browserDebug + : null, + meta.setupFilePaths.watcher, + ].filter(v => v != null), }) let stdout: Writable | undefined @@ -123,6 +128,19 @@ export async function initVitest( } as any, } }, + configureVitest(context) { + const options = context.project.config.browser + if (options?.enabled && typeof data.debug === 'object') { + context.project.config.setupFiles.push(meta.setupFilePaths.browserDebug) + context.vitest.config.inspector = { + enabled: true, + port: data.debug.port, + host: data.debug.host, + waitForDebugger: false, + } + context.project.config.inspector = context.vitest.config.inspector + } + }, }, ], }, @@ -151,7 +169,7 @@ export async function initVitest( createWorker() { return new ExtensionWorker( vitest, - data.debug, + !!data.debug, data.astCollect, emitter, data.meta.finalCoverageFileName, diff --git a/packages/worker-legacy/src/reporter.ts b/packages/worker-legacy/src/reporter.ts index 47674e69..88484ec3 100644 --- a/packages/worker-legacy/src/reporter.ts +++ b/packages/worker-legacy/src/reporter.ts @@ -1,7 +1,7 @@ import type { BirpcReturn } from 'birpc' import type { RunnerTestFile, TaskResultPack, UserConsoleLog } from 'vitest' import type { ExtensionWorkerEvents, ExtensionWorkerTransport } from 'vitest-vscode-shared' -import type { Vitest as VitestCore, WorkspaceProject } from 'vitest/node' +import type { BrowserCommand, Vitest as VitestCore, WorkspaceProject } from 'vitest/node' import type { Reporter } from 'vitest/reporters' import { Console } from 'node:console' import { nextTick } from 'node:process' @@ -10,16 +10,16 @@ import { parseErrorStacktrace } from '@vitest/utils/source-map' import { ExtensionWorker } from './worker' interface VSCodeReporterOptions { - setupFilePath: string + setupFilePaths: string[] } export class VSCodeReporter implements Reporter { public rpc!: BirpcReturn private vitest!: VitestCore - private setupFilePath: string + private setupFilePaths: string[] constructor(options: VSCodeReporterOptions) { - this.setupFilePath = options.setupFilePath + this.setupFilePaths = options.setupFilePaths } private get collecting(): boolean { @@ -29,38 +29,40 @@ export class VSCodeReporter implements Reporter { onInit(vitest: VitestCore) { this.vitest = vitest const server = vitest.server.config.server - if (!server.fs.allow.includes(this.setupFilePath)) - server.fs.allow.push(this.setupFilePath) - vitest.projects.forEach((project) => { - project.config.setupFiles = [ - ...project.config.setupFiles || [], - this.setupFilePath, - ] - const server = project.server.config.server - if (!server.fs.allow.includes(this.setupFilePath)) - server.fs.allow.push(this.setupFilePath) - // @ts-expect-error internal, Vitest 3 - if (project._initBrowserProvider) { - this.overrideInitBrowserProvider(project, '_initBrowserProvider') - } - // @ts-expect-error internal, Vitest 2 - else if (project.initBrowserProvider) { - this.overrideInitBrowserProvider(project, 'initBrowserProvider') - } - const browser = project.browser as any - if (!browser) { - return - } - const config = 'vite' in browser ? browser.vite.config.server : browser.config.server - if (!config.fs.allow.includes(this.setupFilePath)) - config.fs.allow.push(this.setupFilePath) + this.setupFilePaths.forEach((setupFile) => { + if (!server.fs.allow.includes(setupFile)) + server.fs.allow.push(setupFile) + vitest.projects.forEach((project) => { + project.config.setupFiles = [ + ...project.config.setupFiles || [], + setupFile, + ] + const server = project.server.config.server + if (!server.fs.allow.includes(setupFile)) + server.fs.allow.push(setupFile) + // @ts-expect-error internal, Vitest 3 + if (project._initBrowserProvider) { + this.overrideInitBrowserProvider(project, '_initBrowserProvider') + } + // @ts-expect-error internal, Vitest 2 + else if (project.initBrowserProvider) { + this.overrideInitBrowserProvider(project, 'initBrowserProvider') + } + const browser = project.browser as any + if (!browser) { + return + } + const config = 'vite' in browser ? browser.vite.config.server : browser.config.server + if (!config.fs.allow.includes(setupFile)) + config.fs.allow.push(setupFile) + }) }) } overrideInitBrowserProvider(project: WorkspaceProject, name: string) { // @ts-expect-error internal const original = project[name].bind(project) - const setupFilePath = this.setupFilePath + const setupFilePaths = this.setupFilePaths // @ts-expect-error internal project[name] = async function _initBrowserProvider(this: WorkspaceProject) { await original() @@ -68,9 +70,28 @@ export class VSCodeReporter implements Reporter { return } const config = this.browser!.vite.config - if (!config.server.fs.allow.includes(setupFilePath)) { - config.server.fs.allow.push(setupFilePath) + setupFilePaths.forEach((setupFile) => { + if (!config.server.fs.allow.includes(setupFile)) { + config.server.fs.allow.push(setupFile) + } + }) + const __vscode_waitForDebugger: BrowserCommand<[]> = () => { + return new Promise((resolve, reject) => { + ExtensionWorker.emitter.on('onBrowserDebug', (fullfilled) => { + if (fullfilled) { + resolve() + } + else { + reject(new Error(`Browser Debugger failed to connect.`)) + } + }) + }) + } + if (!('parent' in this.browser) || !('commands' in (this.browser.parent as any))) { + return } + // @ts-expect-error private "parent" property + this.browser!.parent.commands.__vscode_waitForDebugger = __vscode_waitForDebugger } } diff --git a/packages/extension/src/worker/setupFile.ts b/packages/worker-legacy/src/setupFile.ts similarity index 100% rename from packages/extension/src/worker/setupFile.ts rename to packages/worker-legacy/src/setupFile.ts diff --git a/packages/worker-legacy/src/worker.ts b/packages/worker-legacy/src/worker.ts index cd3453c0..22fe2b48 100644 --- a/packages/worker-legacy/src/worker.ts +++ b/packages/worker-legacy/src/worker.ts @@ -1,4 +1,8 @@ -import type { ExtensionTestSpecification, ExtensionWorkerTransport } from 'vitest-vscode-shared' +import type { + ExtensionTestFileSpecification, + ExtensionTestSpecification, + ExtensionWorkerTransport, +} from 'vitest-vscode-shared' import type { Reporter, ResolvedConfig, @@ -7,6 +11,7 @@ import type { WorkspaceProject, } from 'vitest/node' import type { WorkerWSEventEmitter } from '../../shared/src/emitter' +import EventEmitter from 'node:events' import { readFileSync } from 'node:fs' import mm from 'micromatch' import { relative } from 'pathe' @@ -21,6 +26,8 @@ export class ExtensionWorker implements ExtensionWorkerTransport { private readonly watcher: ExtensionWorkerWatcher private readonly coverage: ExtensionCoverageManager + public static emitter = new EventEmitter() + public static COLLECT_NAME_PATTERN = '$a' constructor( @@ -174,14 +181,29 @@ export class ExtensionWorker implements ExtensionWorkerTransport { return this.vitest.cancelCurrentRun('keyboard-input') } - public async getFiles(): Promise<[project: string, file: string][]> { + public async getFiles(): Promise { // reset cached test files list this.vitest.projects.forEach((project) => { // testFilesList is private (project as any).testFilesList = null }) const files = await this.globTestSpecifications() - return files.map(spec => [spec[0].config.name || '', spec[1]]) + return files.map((spec) => { + const config = spec[0].config + return [ + spec[1], + { + project: config.name || '', + pool: config.pool, + browser: config.browser?.enabled + ? { + provider: config.browser.provider || 'preview', + name: config.browser.name, + } + : undefined, + }, + ] + }) } private async globTestSpecifications(filters?: string[]): Promise { @@ -399,4 +421,8 @@ export class ExtensionWorker implements ExtensionWorkerTransport { initRpc() { // ignore } + + onBrowserDebug(fulfilled: boolean) { + ExtensionWorker.emitter.emit('onBrowserDebug', fulfilled) + } } diff --git a/packages/worker/src/index.ts b/packages/worker/src/index.ts index e2530fe9..5e400fe9 100644 --- a/packages/worker/src/index.ts +++ b/packages/worker/src/index.ts @@ -16,13 +16,13 @@ export async function initVitest( ) { const meta = data.meta const reporter = new VSCodeReporter({ - setupFilePath: meta.setupFilePath, + setupFilePaths: meta.setupFilePaths, }) let stdout: Writable | undefined let stderr: Writable | undefined - if (meta.shellType === 'terminal' && !meta.hasShellIntegration) { + if ((meta.shellType === 'terminal' && !meta.hasShellIntegration) || data.debug != null) { stdout = new Writable({ write(chunk, __, callback) { const log = chunk.toString() @@ -70,7 +70,6 @@ export async function initVitest( : {} const cliOptions: TestUserConfig = { config: meta.configFile, - ...(meta.workspaceFile ? { workspace: meta.workspaceFile } : {}), ...args, ...options, watch: true, @@ -139,6 +138,19 @@ export async function initVitest( } as any, } }, + configureVitest(context) { + const options = context.project.config.browser + if (options?.enabled && typeof data.debug === 'object') { + context.project.config.setupFiles.push(meta.setupFilePaths.browserDebug) + context.vitest.config.inspector = { + enabled: true, + port: data.debug.port, + host: data.debug.host, + waitForDebugger: false, + } + context.project.config.inspector = context.vitest.config.inspector + } + }, }, ], }, @@ -164,7 +176,7 @@ export async function initVitest( createWorker() { return new ExtensionWorker( vitest, - data.debug, + !!data.debug, emitter, ) }, diff --git a/packages/worker/src/reporter.ts b/packages/worker/src/reporter.ts index b8969333..5023dbff 100644 --- a/packages/worker/src/reporter.ts +++ b/packages/worker/src/reporter.ts @@ -1,6 +1,7 @@ import type { RunnerTaskResultPack, UserConsoleLog } from 'vitest' -import type { VitestWorkerRPC } from 'vitest-vscode-shared' +import type { VitestWorkerRPC, WorkerInitMetadata } from 'vitest-vscode-shared' import type { + BrowserCommand, Reporter, RunnerTestFile, TestModule, @@ -9,19 +10,20 @@ import type { Vite, Vitest as VitestCore, } from 'vitest/node' +import { ExtensionWorker } from './worker' interface VSCodeReporterOptions { - setupFilePath: string + setupFilePaths: WorkerInitMetadata['setupFilePaths'] } export class VSCodeReporter implements Reporter { public rpc!: VitestWorkerRPC private vitest!: VitestCore - private setupFilePath: string + private setupFilePaths: WorkerInitMetadata['setupFilePaths'] constructor(options: VSCodeReporterOptions) { - this.setupFilePath = options.setupFilePath + this.setupFilePaths = options.setupFilePaths } onInit(vitest: VitestCore) { @@ -38,6 +40,22 @@ export class VSCodeReporter implements Reporter { onBrowserInit(project: TestProject) { const config = project.browser!.vite.config this.ensureSetupFileIsAllowed(config) + + const __vscode_waitForDebugger: BrowserCommand<[]> = () => { + return new Promise((resolve, reject) => { + ExtensionWorker.emitter.on('onBrowserDebug', (fullfilled) => { + if (fullfilled) { + resolve() + } + else { + reject(new Error(`Browser Debugger failed to connect.`)) + } + }) + }) + } + // TODO: move this command init to configureVitest when Vitest 4 is out + // @ts-expect-error private "parent" property + project.browser!.parent.commands.__vscode_waitForDebugger = __vscode_waitForDebugger } onUserConsoleLog(log: UserConsoleLog) { @@ -88,9 +106,11 @@ export class VSCodeReporter implements Reporter { } ensureSetupFileIsAllowed(config: Vite.ResolvedConfig) { - if (!config.server.fs.allow.includes(this.setupFilePath)) { - config.server.fs.allow.push(this.setupFilePath) - } + ;[this.setupFilePaths.browserDebug].forEach((filepath) => { + if (!config.server.fs.allow.includes(filepath)) { + config.server.fs.allow.push(filepath) + } + }) } toJSON() { diff --git a/packages/worker/src/runner.ts b/packages/worker/src/runner.ts index 91a10f09..3661136f 100644 --- a/packages/worker/src/runner.ts +++ b/packages/worker/src/runner.ts @@ -1,4 +1,4 @@ -import type { ExtensionTestSpecification, VitestWorkerRPC, WorkerWSEventEmitter } from 'vitest-vscode-shared' +import type { ExtensionTestFileSpecification, ExtensionTestSpecification, VitestWorkerRPC, WorkerWSEventEmitter } from 'vitest-vscode-shared' import type { TestSpecification, Vitest as VitestCore } from 'vitest/node' export class ExtensionWorkerRunner { @@ -10,10 +10,25 @@ export class ExtensionWorkerRunner { private emitter: WorkerWSEventEmitter, ) {} - async getFiles(): Promise { + async getFiles(): Promise { this.vitest.clearSpecificationsCache() const specifications = await this.vitest.globTestSpecifications() - return specifications.map(spec => [spec.project.name, spec.moduleId]) + return specifications.map((spec) => { + const config = spec.project.config + return [ + spec.moduleId, + { + project: spec.project.name, + pool: config.pool, + browser: config.browser?.enabled + ? { + provider: config.browser.provider?.name || 'preview', + name: config.browser.name, + } + : undefined, + }, + ] + }) } async collectTests(testFiles: ExtensionTestSpecification[]): Promise { diff --git a/packages/worker/src/worker.ts b/packages/worker/src/worker.ts index 52548d2e..c7ff03bb 100644 --- a/packages/worker/src/worker.ts +++ b/packages/worker/src/worker.ts @@ -1,10 +1,12 @@ import type { + ExtensionTestFileSpecification, ExtensionTestSpecification, ExtensionWorkerTransport, VitestWorkerRPC, WorkerWSEventEmitter, } from 'vitest-vscode-shared' import type { Vitest as VitestCore } from 'vitest/node' +import EventEmitter from 'node:events' import { ExtensionCoverageManager } from './coverage' import { ExtensionWorkerRunner } from './runner' import { ExtensionWorkerWatcher } from './watcher' @@ -14,17 +16,19 @@ export class ExtensionWorker implements ExtensionWorkerTransport { private readonly coverage: ExtensionCoverageManager private readonly runner: ExtensionWorkerRunner + static emitter = new EventEmitter() + constructor( public readonly vitest: VitestCore, debug = false, - emitter: WorkerWSEventEmitter, + ws: WorkerWSEventEmitter, ) { - this.runner = new ExtensionWorkerRunner(vitest, debug, emitter) + this.runner = new ExtensionWorkerRunner(vitest, debug, ws) this.watcher = new ExtensionWorkerWatcher(vitest, this.runner) this.coverage = new ExtensionCoverageManager(vitest) } - async getFiles(): Promise { + async getFiles(): Promise { return this.runner.getFiles() } @@ -98,4 +102,8 @@ export class ExtensionWorker implements ExtensionWorkerTransport { initRpc(rpc: VitestWorkerRPC) { this.runner.initRpc(rpc) } + + onBrowserDebug(fulfilled: boolean) { + ExtensionWorker.emitter.emit('onBrowserDebug', fulfilled) + } } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 6cac75f0..66ecbfcc 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -7,31 +7,32 @@ settings: catalogs: default: '@vitest/coverage-v8': - specifier: ^4.0.0-beta.8 - version: 4.0.0-beta.8 - '@vitest/utils': - specifier: ^4.0.0-beta.8 - version: 4.0.0-beta.8 + specifier: ^4.0.0-beta.12 + version: 4.0.0-beta.12 vite: specifier: ^7.1.0 version: 7.1.2 overrides: - '@vitest/browser': ^4.0.0-beta.8 - '@vitest/coverage': ^4.0.0-beta.8 - '@vitest/runner': ^4.0.0-beta.8 - vitest: ^4.0.0-beta.8 + '@vitest/browser': ^4.0.0-beta.12 + '@vitest/coverage': ^4.0.0-beta.12 + '@vitest/runner': ^4.0.0-beta.12 + '@vitest/utils': ^4.0.0-beta.12 + vitest: ^4.0.0-beta.12 vitest-vscode-extension>@vitest/browser: ^3.2.0 vitest-vscode-extension>@vitest/coverage: ^3.2.0 vitest-vscode-extension>@vitest/runner: ^3.2.0 + vitest-vscode-extension>@vitest/utils: ^3.2.0 vitest-vscode-extension>vitest: ^3.2.0 vitest-vscode-shared>@vitest/browser: ^3.2.0 vitest-vscode-shared>@vitest/coverage: ^3.2.0 vitest-vscode-shared>@vitest/runner: ^3.2.0 + vitest-vscode-shared>@vitest/utils: ^3.2.0 vitest-vscode-shared>vitest: ^3.2.0 vitest-vscode-worker-legacy>@vitest/browser: ^3.2.0 vitest-vscode-worker-legacy>@vitest/coverage: ^3.2.0 vitest-vscode-worker-legacy>@vitest/runner: ^3.2.0 + vitest-vscode-worker-legacy>@vitest/utils: ^3.2.0 vitest-vscode-worker-legacy>vitest: ^3.2.0 importers: @@ -40,7 +41,7 @@ importers: devDependencies: '@antfu/eslint-config': specifier: ^4.14.1 - version: 4.14.1(@vue/compiler-sfc@3.5.16)(eslint@9.28.0(jiti@2.4.2))(typescript@5.8.3)(vitest@4.0.0-beta.8) + version: 4.14.1(@vue/compiler-sfc@3.5.16)(eslint@9.28.0(jiti@2.4.2))(typescript@5.8.3)(vitest@4.0.0-beta.12) '@playwright/test': specifier: ^1.42.1 version: 1.52.0 @@ -72,11 +73,11 @@ importers: specifier: ^8.5.10 version: 8.18.1 '@vitest/runner': - specifier: ^4.0.0-beta.8 - version: 4.0.0-beta.8 + specifier: ^4.0.0-beta.12 + version: 4.0.0-beta.12 '@vitest/utils': - specifier: 'catalog:' - version: 4.0.0-beta.8 + specifier: ^4.0.0-beta.12 + version: 4.0.0-beta.12 '@vscode/test-cli': specifier: ^0.0.6 version: 0.0.6 @@ -153,8 +154,8 @@ importers: specifier: ^5.6.2 version: 5.8.3 vitest: - specifier: ^4.0.0-beta.8 - version: 4.0.0-beta.8(@types/debug@4.1.12)(@types/node@24.0.0)(@vitest/browser@4.0.0-beta.8)(happy-dom@15.11.7)(jiti@2.4.2)(jsdom@26.1.0)(msw@2.10.2(@types/node@24.0.0)(typescript@5.8.3))(tsx@4.19.4)(yaml@2.8.0) + specifier: ^4.0.0-beta.12 + version: 4.0.0-beta.12(@types/debug@4.1.12)(@types/node@24.0.0)(@vitest/browser@4.0.0-beta.12)(happy-dom@15.11.7)(jiti@2.4.2)(jsdom@26.1.0)(msw@2.10.2(@types/node@24.0.0)(typescript@5.8.3))(tsx@4.19.4)(yaml@2.8.0) which: specifier: ^4.0.0 version: 4.0.0 @@ -164,9 +165,12 @@ importers: packages/extension: dependencies: + '@vitest/browser': + specifier: ^3.2.0 + version: 3.2.4(msw@2.10.2(@types/node@24.0.0)(typescript@5.8.3))(playwright@1.52.0)(vite@7.1.2(@types/node@24.0.0)(jiti@2.4.2)(tsx@4.19.4)(yaml@2.8.0))(vitest@3.2.4) vitest: specifier: ^3.2.0 - version: 3.2.4(@types/debug@4.1.12)(@types/node@24.0.0)(@vitest/browser@4.0.0-beta.8)(happy-dom@15.11.7)(jiti@2.4.2)(jsdom@26.1.0)(msw@2.10.2(@types/node@24.0.0)(typescript@5.8.3))(tsx@4.19.4)(yaml@2.8.0) + version: 3.2.4(@types/debug@4.1.12)(@types/node@24.0.0)(@vitest/browser@3.2.4)(happy-dom@15.11.7)(jiti@2.4.2)(jsdom@26.1.0)(msw@2.10.2(@types/node@24.0.0)(typescript@5.8.3))(tsx@4.19.4)(yaml@2.8.0) vitest-vscode-shared: specifier: workspace:* version: link:../shared @@ -178,25 +182,28 @@ importers: version: 2.4.0 vitest: specifier: ^3.2.0 - version: 3.2.4(@types/debug@4.1.12)(@types/node@24.0.0)(@vitest/browser@4.0.0-beta.8)(happy-dom@15.11.7)(jiti@2.4.2)(jsdom@26.1.0)(msw@2.10.2(@types/node@24.0.0)(typescript@5.8.3))(tsx@4.19.4)(yaml@2.8.0) + version: 3.2.4(@types/debug@4.1.12)(@types/node@24.0.0)(@vitest/browser@4.0.0-beta.12)(happy-dom@15.11.7)(jiti@2.4.2)(jsdom@26.1.0)(msw@2.10.2(@types/node@24.0.0)(typescript@5.8.3))(tsx@4.19.4)(yaml@2.8.0) packages/worker: devDependencies: '@vitest/utils': - specifier: 'catalog:' - version: 4.0.0-beta.8 + specifier: ^4.0.0-beta.12 + version: 4.0.0-beta.12 vitest: - specifier: ^4.0.0-beta.8 - version: 4.0.0-beta.8(@types/debug@4.1.12)(@types/node@24.0.0)(@vitest/browser@4.0.0-beta.8)(happy-dom@15.11.7)(jiti@2.4.2)(jsdom@26.1.0)(msw@2.10.2(@types/node@24.0.0)(typescript@5.8.3))(tsx@4.19.4)(yaml@2.8.0) + specifier: ^4.0.0-beta.12 + version: 4.0.0-beta.12(@types/debug@4.1.12)(@types/node@24.0.0)(@vitest/browser@4.0.0-beta.12)(happy-dom@15.11.7)(jiti@2.4.2)(jsdom@26.1.0)(msw@2.10.2(@types/node@24.0.0)(typescript@5.8.3))(tsx@4.19.4)(yaml@2.8.0) vitest-vscode-shared: specifier: workspace:* version: link:../shared packages/worker-legacy: dependencies: + '@vitest/utils': + specifier: ^3.2.0 + version: 3.2.4 vitest: specifier: ^3.2.0 - version: 3.2.4(@types/debug@4.1.12)(@types/node@24.0.0)(@vitest/browser@4.0.0-beta.8)(happy-dom@15.11.7)(jiti@2.4.2)(jsdom@26.1.0)(msw@2.10.2(@types/node@24.0.0)(typescript@5.8.3))(tsx@4.19.4)(yaml@2.8.0) + version: 3.2.4(@types/debug@4.1.12)(@types/node@24.0.0)(@vitest/browser@4.0.0-beta.12)(happy-dom@15.11.7)(jiti@2.4.2)(jsdom@26.1.0)(msw@2.10.2(@types/node@24.0.0)(typescript@5.8.3))(tsx@4.19.4)(yaml@2.8.0) vitest-vscode-shared: specifier: workspace:* version: link:../shared @@ -209,13 +216,13 @@ importers: devDependencies: '@vitest/coverage-v8': specifier: 'catalog:' - version: 4.0.0-beta.8(@vitest/browser@4.0.0-beta.8)(vitest@4.0.0-beta.8) + version: 4.0.0-beta.12(@vitest/browser@4.0.0-beta.12)(vitest@4.0.0-beta.12) vite: specifier: 'catalog:' version: 7.1.2(@types/node@24.0.0)(jiti@2.4.2)(tsx@4.19.4)(yaml@2.8.0) vitest: - specifier: ^4.0.0-beta.8 - version: 4.0.0-beta.8(@types/debug@4.1.12)(@types/node@24.0.0)(@vitest/browser@4.0.0-beta.8)(happy-dom@15.11.7)(jiti@2.4.2)(jsdom@26.1.0)(msw@2.10.2(@types/node@24.0.0)(typescript@5.8.3))(tsx@4.19.4)(yaml@2.8.0) + specifier: ^4.0.0-beta.12 + version: 4.0.0-beta.12(@types/debug@4.1.12)(@types/node@24.0.0)(@vitest/browser@4.0.0-beta.12)(happy-dom@15.11.7)(jiti@2.4.2)(jsdom@26.1.0)(msw@2.10.2(@types/node@24.0.0)(typescript@5.8.3))(tsx@4.19.4)(yaml@2.8.0) samples/basic: dependencies: @@ -225,28 +232,28 @@ importers: devDependencies: '@vitest/coverage-v8': specifier: 'catalog:' - version: 4.0.0-beta.8(@vitest/browser@4.0.0-beta.8)(vitest@4.0.0-beta.8) + version: 4.0.0-beta.12(@vitest/browser@4.0.0-beta.12)(vitest@4.0.0-beta.12) vite: specifier: 'catalog:' version: 7.1.2(@types/node@24.0.0)(jiti@2.4.2)(tsx@4.19.4)(yaml@2.8.0) vitest: - specifier: ^4.0.0-beta.8 - version: 4.0.0-beta.8(@types/debug@4.1.12)(@types/node@24.0.0)(@vitest/browser@4.0.0-beta.8)(happy-dom@15.11.7)(jiti@2.4.2)(jsdom@26.1.0)(msw@2.10.2(@types/node@24.0.0)(typescript@5.8.3))(tsx@4.19.4)(yaml@2.8.0) + specifier: ^4.0.0-beta.12 + version: 4.0.0-beta.12(@types/debug@4.1.12)(@types/node@24.0.0)(@vitest/browser@4.0.0-beta.12)(happy-dom@15.11.7)(jiti@2.4.2)(jsdom@26.1.0)(msw@2.10.2(@types/node@24.0.0)(typescript@5.8.3))(tsx@4.19.4)(yaml@2.8.0) samples/basic-v4: devDependencies: '@vitest/browser': - specifier: ^4.0.0-beta.8 - version: 4.0.0-beta.8(msw@2.10.2(@types/node@24.0.0)(typescript@5.8.3))(playwright@1.52.0)(vite@7.1.2(@types/node@24.0.0)(jiti@2.4.2)(tsx@4.19.4)(yaml@2.8.0))(vitest@4.0.0-beta.8) + specifier: ^4.0.0-beta.12 + version: 4.0.0-beta.12(msw@2.10.2(@types/node@24.0.0)(typescript@5.8.3))(playwright@1.52.0)(vite@7.1.2(@types/node@24.0.0)(jiti@2.4.2)(tsx@4.19.4)(yaml@2.8.0))(vitest@4.0.0-beta.12) '@vitest/coverage-v8': specifier: 'catalog:' - version: 4.0.0-beta.8(@vitest/browser@4.0.0-beta.8)(vitest@4.0.0-beta.8) + version: 4.0.0-beta.12(@vitest/browser@4.0.0-beta.12)(vitest@4.0.0-beta.12) vite: specifier: 'catalog:' version: 7.1.2(@types/node@24.0.0)(jiti@2.4.2)(tsx@4.19.4)(yaml@2.8.0) vitest: - specifier: ^4.0.0-beta.8 - version: 4.0.0-beta.8(@types/debug@4.1.12)(@types/node@24.0.0)(@vitest/browser@4.0.0-beta.8)(happy-dom@15.11.7)(jiti@2.4.2)(jsdom@26.1.0)(msw@2.10.2(@types/node@24.0.0)(typescript@5.8.3))(tsx@4.19.4)(yaml@2.8.0) + specifier: ^4.0.0-beta.12 + version: 4.0.0-beta.12(@types/debug@4.1.12)(@types/node@24.0.0)(@vitest/browser@4.0.0-beta.12)(happy-dom@15.11.7)(jiti@2.4.2)(jsdom@26.1.0)(msw@2.10.2(@types/node@24.0.0)(typescript@5.8.3))(tsx@4.19.4)(yaml@2.8.0) samples/browser: dependencies: @@ -255,11 +262,11 @@ importers: version: 0.2.19 devDependencies: '@vitest/browser': - specifier: ^4.0.0-beta.8 - version: 4.0.0-beta.8(msw@2.10.2(@types/node@24.0.0)(typescript@5.8.3))(playwright@1.52.0)(vite@7.1.2(@types/node@24.0.0)(jiti@2.4.2)(tsx@4.19.4)(yaml@2.8.0))(vitest@4.0.0-beta.8) + specifier: ^4.0.0-beta.12 + version: 4.0.0-beta.12(msw@2.10.2(@types/node@24.0.0)(typescript@5.8.3))(playwright@1.52.0)(vite@7.1.2(@types/node@24.0.0)(jiti@2.4.2)(tsx@4.19.4)(yaml@2.8.0))(vitest@4.0.0-beta.12) '@vitest/coverage-v8': specifier: 'catalog:' - version: 4.0.0-beta.8(@vitest/browser@4.0.0-beta.8)(vitest@4.0.0-beta.8) + version: 4.0.0-beta.12(@vitest/browser@4.0.0-beta.12)(vitest@4.0.0-beta.12) playwright: specifier: ^1.47.0 version: 1.52.0 @@ -267,20 +274,20 @@ importers: specifier: 'catalog:' version: 7.1.2(@types/node@24.0.0)(jiti@2.4.2)(tsx@4.19.4)(yaml@2.8.0) vitest: - specifier: ^4.0.0-beta.8 - version: 4.0.0-beta.8(@types/debug@4.1.12)(@types/node@24.0.0)(@vitest/browser@4.0.0-beta.8)(happy-dom@15.11.7)(jiti@2.4.2)(jsdom@26.1.0)(msw@2.10.2(@types/node@24.0.0)(typescript@5.8.3))(tsx@4.19.4)(yaml@2.8.0) + specifier: ^4.0.0-beta.12 + version: 4.0.0-beta.12(@types/debug@4.1.12)(@types/node@24.0.0)(@vitest/browser@4.0.0-beta.12)(happy-dom@15.11.7)(jiti@2.4.2)(jsdom@26.1.0)(msw@2.10.2(@types/node@24.0.0)(typescript@5.8.3))(tsx@4.19.4)(yaml@2.8.0) samples/continuous: devDependencies: vitest: - specifier: ^4.0.0-beta.8 - version: 4.0.0-beta.8(@types/debug@4.1.12)(@types/node@24.0.0)(@vitest/browser@4.0.0-beta.8)(happy-dom@15.11.7)(jiti@2.4.2)(jsdom@26.1.0)(msw@2.10.2(@types/node@24.0.0)(typescript@5.8.3))(tsx@4.19.4)(yaml@2.8.0) + specifier: ^4.0.0-beta.12 + version: 4.0.0-beta.12(@types/debug@4.1.12)(@types/node@24.0.0)(@vitest/browser@4.0.0-beta.12)(happy-dom@15.11.7)(jiti@2.4.2)(jsdom@26.1.0)(msw@2.10.2(@types/node@24.0.0)(typescript@5.8.3))(tsx@4.19.4)(yaml@2.8.0) samples/e2e: devDependencies: vitest: - specifier: ^4.0.0-beta.8 - version: 4.0.0-beta.8(@types/debug@4.1.12)(@types/node@24.0.0)(@vitest/browser@4.0.0-beta.8)(happy-dom@15.11.7)(jiti@2.4.2)(jsdom@26.1.0)(msw@2.10.2(@types/node@24.0.0)(typescript@5.8.3))(tsx@4.19.4)(yaml@2.8.0) + specifier: ^4.0.0-beta.12 + version: 4.0.0-beta.12(@types/debug@4.1.12)(@types/node@24.0.0)(@vitest/browser@4.0.0-beta.12)(happy-dom@15.11.7)(jiti@2.4.2)(jsdom@26.1.0)(msw@2.10.2(@types/node@24.0.0)(typescript@5.8.3))(tsx@4.19.4)(yaml@2.8.0) samples/imba: devDependencies: @@ -292,7 +299,7 @@ importers: version: 6.6.3 imba: specifier: ^2.0.0-alpha.235 - version: 2.0.0-alpha.247(@testing-library/dom@9.3.4)(@testing-library/jest-dom@6.6.3)(picomatch@4.0.3)(vite-node@3.2.4(@types/node@24.0.0)(jiti@2.4.2)(tsx@4.19.4)(yaml@2.8.0))(vite@7.1.2(@types/node@24.0.0)(jiti@2.4.2)(tsx@4.19.4)(yaml@2.8.0))(vitest@4.0.0-beta.8) + version: 2.0.0-alpha.247(@testing-library/dom@9.3.4)(@testing-library/jest-dom@6.6.3)(picomatch@4.0.3)(vite-node@3.2.4(@types/node@24.0.0)(jiti@2.4.2)(tsx@4.19.4)(yaml@2.8.0))(vite@7.1.2(@types/node@24.0.0)(jiti@2.4.2)(tsx@4.19.4)(yaml@2.8.0))(vitest@4.0.0-beta.12) jsdom: specifier: ^24.0.0 version: 24.1.3 @@ -301,13 +308,13 @@ importers: version: 7.1.2(@types/node@24.0.0)(jiti@2.4.2)(tsx@4.19.4)(yaml@2.8.0) vite-plugin-imba: specifier: ^0.10.3 - version: 0.10.3(imba@2.0.0-alpha.247(@testing-library/dom@9.3.4)(@testing-library/jest-dom@6.6.3)(picomatch@4.0.3)(vite-node@3.2.4(@types/node@24.0.0)(jiti@2.4.2)(tsx@4.19.4)(yaml@2.8.0))(vite@7.1.2(@types/node@24.0.0)(jiti@2.4.2)(tsx@4.19.4)(yaml@2.8.0))(vitest@4.0.0-beta.8))(vite@7.1.2(@types/node@24.0.0)(jiti@2.4.2)(tsx@4.19.4)(yaml@2.8.0)) + version: 0.10.3(imba@2.0.0-alpha.247(@testing-library/dom@9.3.4)(@testing-library/jest-dom@6.6.3)(picomatch@4.0.3)(vite-node@3.2.4(@types/node@24.0.0)(jiti@2.4.2)(tsx@4.19.4)(yaml@2.8.0))(vite@7.1.2(@types/node@24.0.0)(jiti@2.4.2)(tsx@4.19.4)(yaml@2.8.0))(vitest@4.0.0-beta.12))(vite@7.1.2(@types/node@24.0.0)(jiti@2.4.2)(tsx@4.19.4)(yaml@2.8.0)) vitest: - specifier: ^4.0.0-beta.8 - version: 4.0.0-beta.8(@types/debug@4.1.12)(@types/node@24.0.0)(@vitest/browser@4.0.0-beta.8)(happy-dom@15.11.7)(jiti@2.4.2)(jsdom@24.1.3)(msw@2.10.2(@types/node@24.0.0)(typescript@5.8.3))(tsx@4.19.4)(yaml@2.8.0) + specifier: ^4.0.0-beta.12 + version: 4.0.0-beta.12(@types/debug@4.1.12)(@types/node@24.0.0)(@vitest/browser@4.0.0-beta.12)(happy-dom@15.11.7)(jiti@2.4.2)(jsdom@24.1.3)(msw@2.10.2(@types/node@24.0.0)(typescript@5.8.3))(tsx@4.19.4)(yaml@2.8.0) vitest-github-actions-reporter-temp: specifier: ^0.8.3 - version: 0.8.3(vitest@4.0.0-beta.8) + version: 0.8.3(vitest@4.0.0-beta.12) samples/in-source: devDependencies: @@ -315,20 +322,20 @@ importers: specifier: 'catalog:' version: 7.1.2(@types/node@24.0.0)(jiti@2.4.2)(tsx@4.19.4)(yaml@2.8.0) vitest: - specifier: ^4.0.0-beta.8 - version: 4.0.0-beta.8(@types/debug@4.1.12)(@types/node@24.0.0)(@vitest/browser@4.0.0-beta.8)(happy-dom@15.11.7)(jiti@2.4.2)(jsdom@26.1.0)(msw@2.10.2(@types/node@24.0.0)(typescript@5.8.3))(tsx@4.19.4)(yaml@2.8.0) + specifier: ^4.0.0-beta.12 + version: 4.0.0-beta.12(@types/debug@4.1.12)(@types/node@24.0.0)(@vitest/browser@4.0.0-beta.12)(happy-dom@15.11.7)(jiti@2.4.2)(jsdom@26.1.0)(msw@2.10.2(@types/node@24.0.0)(typescript@5.8.3))(tsx@4.19.4)(yaml@2.8.0) samples/monorepo-vitest-workspace: devDependencies: '@vitest/coverage-v8': specifier: 'catalog:' - version: 4.0.0-beta.8(@vitest/browser@4.0.0-beta.8)(vitest@4.0.0-beta.8) + version: 4.0.0-beta.12(@vitest/browser@4.0.0-beta.12)(vitest@4.0.0-beta.12) happy-dom: specifier: ^15.7.4 version: 15.11.7 vitest: - specifier: ^4.0.0-beta.8 - version: 4.0.0-beta.8(@types/debug@4.1.12)(@types/node@24.0.0)(@vitest/browser@4.0.0-beta.8)(happy-dom@15.11.7)(jiti@2.4.2)(jsdom@26.1.0)(msw@2.10.2(@types/node@24.0.0)(typescript@5.8.3))(tsx@4.19.4)(yaml@2.8.0) + specifier: ^4.0.0-beta.12 + version: 4.0.0-beta.12(@types/debug@4.1.12)(@types/node@24.0.0)(@vitest/browser@4.0.0-beta.12)(happy-dom@15.11.7)(jiti@2.4.2)(jsdom@26.1.0)(msw@2.10.2(@types/node@24.0.0)(typescript@5.8.3))(tsx@4.19.4)(yaml@2.8.0) samples/monorepo-vitest-workspace/packages/react: dependencies: @@ -383,20 +390,20 @@ importers: samples/multiple-configs: dependencies: vitest: - specifier: ^4.0.0-beta.8 - version: 4.0.0-beta.8(@types/debug@4.1.12)(@types/node@24.0.0)(@vitest/browser@4.0.0-beta.8)(happy-dom@15.11.7)(jiti@2.4.2)(jsdom@26.1.0)(msw@2.10.2(@types/node@24.0.0)(typescript@5.8.3))(tsx@4.19.4)(yaml@2.8.0) + specifier: ^4.0.0-beta.12 + version: 4.0.0-beta.12(@types/debug@4.1.12)(@types/node@24.0.0)(@vitest/browser@4.0.0-beta.12)(happy-dom@15.11.7)(jiti@2.4.2)(jsdom@26.1.0)(msw@2.10.2(@types/node@24.0.0)(typescript@5.8.3))(tsx@4.19.4)(yaml@2.8.0) samples/no-config: devDependencies: vitest: - specifier: ^4.0.0-beta.8 - version: 4.0.0-beta.8(@types/debug@4.1.12)(@types/node@24.0.0)(@vitest/browser@4.0.0-beta.8)(happy-dom@15.11.7)(jiti@2.4.2)(jsdom@26.1.0)(msw@2.10.2(@types/node@24.0.0)(typescript@5.8.3))(tsx@4.19.4)(yaml@2.8.0) + specifier: ^4.0.0-beta.12 + version: 4.0.0-beta.12(@types/debug@4.1.12)(@types/node@24.0.0)(@vitest/browser@4.0.0-beta.12)(happy-dom@15.11.7)(jiti@2.4.2)(jsdom@26.1.0)(msw@2.10.2(@types/node@24.0.0)(typescript@5.8.3))(tsx@4.19.4)(yaml@2.8.0) samples/readme: devDependencies: vitest: - specifier: ^4.0.0-beta.8 - version: 4.0.0-beta.8(@types/debug@4.1.12)(@types/node@24.0.0)(@vitest/browser@4.0.0-beta.8)(happy-dom@15.11.7)(jiti@2.4.2)(jsdom@26.1.0)(msw@2.10.2(@types/node@24.0.0)(typescript@5.8.3))(tsx@4.19.4)(yaml@2.8.0) + specifier: ^4.0.0-beta.12 + version: 4.0.0-beta.12(@types/debug@4.1.12)(@types/node@24.0.0)(@vitest/browser@4.0.0-beta.12)(happy-dom@15.11.7)(jiti@2.4.2)(jsdom@26.1.0)(msw@2.10.2(@types/node@24.0.0)(typescript@5.8.3))(tsx@4.19.4)(yaml@2.8.0) samples/vue: dependencies: @@ -409,7 +416,7 @@ importers: version: 5.2.4(vite@7.1.2(@types/node@24.0.0)(jiti@2.4.2)(tsx@4.19.4)(yaml@2.8.0))(vue@3.5.16(typescript@5.8.3)) '@vitest/coverage-v8': specifier: 'catalog:' - version: 4.0.0-beta.8(@vitest/browser@4.0.0-beta.8)(vitest@4.0.0-beta.8) + version: 4.0.0-beta.12(@vitest/browser@4.0.0-beta.12)(vitest@4.0.0-beta.12) '@vue/test-utils': specifier: ^2.4.5 version: 2.4.6 @@ -420,8 +427,8 @@ importers: specifier: 'catalog:' version: 7.1.2(@types/node@24.0.0)(jiti@2.4.2)(tsx@4.19.4)(yaml@2.8.0) vitest: - specifier: ^4.0.0-beta.8 - version: 4.0.0-beta.8(@types/debug@4.1.12)(@types/node@24.0.0)(@vitest/browser@4.0.0-beta.8)(happy-dom@14.7.1)(jiti@2.4.2)(jsdom@26.1.0)(msw@2.10.2(@types/node@24.0.0)(typescript@5.8.3))(tsx@4.19.4)(yaml@2.8.0) + specifier: ^4.0.0-beta.12 + version: 4.0.0-beta.12(@types/debug@4.1.12)(@types/node@24.0.0)(@vitest/browser@4.0.0-beta.12)(happy-dom@14.7.1)(jiti@2.4.2)(jsdom@26.1.0)(msw@2.10.2(@types/node@24.0.0)(typescript@5.8.3))(tsx@4.19.4)(yaml@2.8.0) packages: @@ -1016,9 +1023,15 @@ packages: '@jridgewell/sourcemap-codec@1.5.0': resolution: {integrity: sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==} + '@jridgewell/sourcemap-codec@1.5.5': + resolution: {integrity: sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==} + '@jridgewell/trace-mapping@0.3.25': resolution: {integrity: sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==} + '@jridgewell/trace-mapping@0.3.31': + resolution: {integrity: sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==} + '@mswjs/interceptors@0.39.2': resolution: {integrity: sha512-RuzCup9Ct91Y7V79xwCb146RaBRHZ7NBbrIUySumd1rpKqHL5OonaqrGIbug5hNwP/fRyxFMA6ISgw4FTtYFYg==} engines: {node: '>=18'} @@ -1619,12 +1632,27 @@ packages: vite: ^5.0.0 || ^6.0.0 vue: ^3.2.25 - '@vitest/browser@4.0.0-beta.8': - resolution: {integrity: sha512-xFMdlTkOT5ml2YYkWIxryH/UQjerLdBA81GeiIoOdxxbupFLzQ+z27XU4uqzzmliHx/BTzG6Hb9XfWbvsjmlZA==} + '@vitest/browser@3.2.4': + resolution: {integrity: sha512-tJxiPrWmzH8a+w9nLKlQMzAKX/7VjFs50MWgcAj7p9XQ7AQ9/35fByFYptgPELyLw+0aixTnC4pUWV+APcZ/kw==} + peerDependencies: + playwright: '*' + safaridriver: '*' + vitest: ^4.0.0-beta.12 + webdriverio: ^7.0.0 || ^8.0.0 || ^9.0.0 + peerDependenciesMeta: + playwright: + optional: true + safaridriver: + optional: true + webdriverio: + optional: true + + '@vitest/browser@4.0.0-beta.12': + resolution: {integrity: sha512-PqkO+3uqkZI8mUovRqYRqWW0tIeJGm13gGQwQwuKXCYgmRynR+035raMQDdIT6FkqWjSr5qg5ewG0GSVSSHe1w==} peerDependencies: playwright: '*' safaridriver: '*' - vitest: ^4.0.0-beta.8 + vitest: ^4.0.0-beta.12 webdriverio: ^7.0.0 || ^8.0.0 || ^9.0.0 peerDependenciesMeta: playwright: @@ -1634,11 +1662,11 @@ packages: webdriverio: optional: true - '@vitest/coverage-v8@4.0.0-beta.8': - resolution: {integrity: sha512-vd8D6P/PWtHXjH5Sot8PuGKchYC7Uns46Dpr1fg57kD8SOdXJybxtg/EdYvD5/OUW2q0iQCFes79WbH+LelwaA==} + '@vitest/coverage-v8@4.0.0-beta.12': + resolution: {integrity: sha512-ar+nlPjwm2skYS3hkOiaXk8fBqVF93LWpLSTwyi8SQmBKxFj2iWjHV50qw65wbG4ESkJUU3fEA3mXQQhvSQ3kQ==} peerDependencies: - '@vitest/browser': ^4.0.0-beta.8 - vitest: ^4.0.0-beta.8 + '@vitest/browser': ^4.0.0-beta.12 + vitest: ^4.0.0-beta.12 peerDependenciesMeta: '@vitest/browser': optional: true @@ -1648,7 +1676,7 @@ packages: peerDependencies: eslint: '>= 8.57.0' typescript: '>= 5.0.0' - vitest: ^4.0.0-beta.8 + vitest: ^4.0.0-beta.12 peerDependenciesMeta: typescript: optional: true @@ -1658,8 +1686,8 @@ packages: '@vitest/expect@3.2.4': resolution: {integrity: sha512-Io0yyORnB6sikFlt8QW5K7slY4OjqNX9jmJQ02QDda8lyM6B5oNgVWoSoKPac8/kgnCUzuHQKrSLtu/uOqqrig==} - '@vitest/expect@4.0.0-beta.8': - resolution: {integrity: sha512-40DZ7nl5AkASkDNaVR7TqsbeJCs5D+dyQNM5cIvgjG3KK+ATeWxtXJbmRNqgdbq+FL3v/pchnrJM1R9BFkTdUQ==} + '@vitest/expect@4.0.0-beta.12': + resolution: {integrity: sha512-3r4Gk7Cb7YPNaOETcmlFez3+1opQdKaU5cRnk3hLk13UbYsXxYuqp1wi689kwPa6Yp6BZtbddDIk/D6fPdwcdg==} '@vitest/mocker@3.2.4': resolution: {integrity: sha512-46ryTE9RZO/rfDd7pEqFl7etuyzekzEhUbTW3BvmeO/BcCMEgq59BKhek3dXDWgAj4oMK6OZi+vRr1wPW6qjEQ==} @@ -1672,8 +1700,8 @@ packages: vite: optional: true - '@vitest/mocker@4.0.0-beta.8': - resolution: {integrity: sha512-a5ynR/Fsrciuq17i8lzS5NH3ICxwFZMlQ4bXPzGV+KlIcVHu20a/8q6KekqUaVBxCbmohORLFXFx9IptHS9gXA==} + '@vitest/mocker@4.0.0-beta.12': + resolution: {integrity: sha512-UVlIb5A0Qf9ZBBOB1MJNRVmNNbn4EyMhjS+XSR1DBBiTxlCFMXjt2UdncH+s04DIwWdv4obFceffjepw9CPK1w==} peerDependencies: msw: ^2.4.9 vite: ^6.0.0 || ^7.0.0-0 @@ -1686,29 +1714,29 @@ packages: '@vitest/pretty-format@3.2.4': resolution: {integrity: sha512-IVNZik8IVRJRTr9fxlitMKeJeXFFFN0JaB9PHPGQ8NKQbGpfjlTx9zO4RefN8gp7eqjNy8nyK3NZmBzOPeIxtA==} - '@vitest/pretty-format@4.0.0-beta.8': - resolution: {integrity: sha512-sr5HPeeRff4gTpDwI2Kvz8dS2CmDCCZ1PRu3IOeLTcSJjhEWmk3IJILjqaA8yyj+QzWjnqAxr2rmZNpO0h/5Vw==} + '@vitest/pretty-format@4.0.0-beta.12': + resolution: {integrity: sha512-zIlDOlEBxUn62/TFum2sQ2/vwQLBIYMdEDM6hMVGIn+MwDD/N0dXmpjDAuG5HDA9K3okF3624x+Einusxlio+Q==} - '@vitest/runner@4.0.0-beta.8': - resolution: {integrity: sha512-m7jrT+KMEgONclBI7y3ptUD+/uhRzzHLblws84fo+WesCjS8WT8q7RoPMgqymj5kmzIF5sTh6NOvrNEE5LaLCQ==} + '@vitest/runner@4.0.0-beta.12': + resolution: {integrity: sha512-MVIvqTKcMFgfT65pHPpCVGPftXC3hT2Ovbmu0bGnEKNI7yirE3pgf5X4ZY3f5oAHjIOyggAcxkmCDNlzdl01+w==} '@vitest/snapshot@3.2.4': resolution: {integrity: sha512-dEYtS7qQP2CjU27QBC5oUOxLE/v5eLkGqPE0ZKEIDGMs4vKWe7IjgLOeauHsR0D5YuuycGRO5oSRXnwnmA78fQ==} - '@vitest/snapshot@4.0.0-beta.8': - resolution: {integrity: sha512-2hzc/ksGlZ8Rcg11VD/AhTwSaPEsdtrNA+TCV4w6tuZ7I2X+XJXimfk/Cehz5zMgfFuV8tFmGimb/BpyIbNiMg==} + '@vitest/snapshot@4.0.0-beta.12': + resolution: {integrity: sha512-vizO/9xz6I9b1AdwTGsrG9KiYkXicRKbLo9WMnJnYd8GJHbM+SnMS1NKBgn2uMbpG1fQoiOarjr6yEGPVoJZOw==} '@vitest/spy@3.2.4': resolution: {integrity: sha512-vAfasCOe6AIK70iP5UD11Ac4siNUNJ9i/9PZ3NKx07sG6sUxeag1LWdNrMWeKKYBLlzuK+Gn65Yd5nyL6ds+nw==} - '@vitest/spy@4.0.0-beta.8': - resolution: {integrity: sha512-WfHF35GCf5xx3B1oRrhWMVAfcBBYO4WHAYLbeeaZ1ZSW5/VBXJ/M37bLxRRKnXcgffwcsWA7xpjWnL0dQ1q5NA==} + '@vitest/spy@4.0.0-beta.12': + resolution: {integrity: sha512-PICUKy+sYYGCZoAGsTaUJsQnxZVpfvewSLOfmqdVoVKpicbBb+gMtJA2CR8vGhGLc4Uh/bMrr0vNRmQOA+U7jg==} '@vitest/utils@3.2.4': resolution: {integrity: sha512-fB2V0JFrQSMsCo9HiSq3Ezpdv4iYaXRG1Sx8edX3MwxfyNn83mKiGzOcH+Fkxt4MHxr3y42fQi1oeAInqgX2QA==} - '@vitest/utils@4.0.0-beta.8': - resolution: {integrity: sha512-+eV3yrDooGMnHHVQ1aqzPJIBlxEsaQg/5BVFRSkbBgfiKqM9HZbqYK736s0D8tfdMLOjeB+7u7Tw0emd/h3MlQ==} + '@vitest/utils@4.0.0-beta.12': + resolution: {integrity: sha512-3cP3XmmaLhyuQ5OXirsPB2B5/ZBfkqujBuFmuxi+C5710vz7h6wp9Y+eQqIYDloMHaIe1dVJTm+Q3klpNXqPrg==} '@vscode/test-cli@0.0.6': resolution: {integrity: sha512-4i61OUv5PQr3GxhHOuUgHdgBDfIO/kXTPCsEyFiMaY4SOqQTgkTmyZLagHehjOgCfsXdcrJa3zgQ7zoc+Dh6hQ==} @@ -1908,8 +1936,8 @@ packages: resolution: {integrity: sha512-Izi8RQcffqCeNVgFigKli1ssklIbpHnCYc6AknXGYoB6grJqyeby7jv12JUQgmTAnIDnbck1uxksT4dzN3PWBA==} engines: {node: '>=12'} - ast-v8-to-istanbul@0.3.3: - resolution: {integrity: sha512-MuXMrSLVVoA6sYN/6Hke18vMzrT4TZNbZIj/hvh0fnYFpO+/kFXcLIaiPwXXWaQUPg4yJD8fj+lfJ7/1EBconw==} + ast-v8-to-istanbul@0.3.5: + resolution: {integrity: sha512-9SdXjNheSiE8bALAQCQQuT6fgQaoxJh7IRYrRGZ8/9nv8WhJeC1aXAwN8TbaOssGOukUvyvnkgD9+Yuykvl1aA==} astral-regex@2.0.0: resolution: {integrity: sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==} @@ -2065,6 +2093,10 @@ packages: resolution: {integrity: sha512-5nFxhUrX0PqtyogoYOA8IPswy5sZFTOsBFl/9bNsmDLgsxYTzSZQJDPppDnZPTQbzSEm0hqGjWPzRemQCYbD6A==} engines: {node: '>=18'} + chai@6.0.1: + resolution: {integrity: sha512-/JOoU2//6p5vCXh00FpNgtlw0LjvhGttaWc+y7wpW9yjBm3ys0dI8tSKZxIOgNruz5J0RleccatSIC3uxEZP0g==} + engines: {node: '>=18'} + chalk@3.0.0: resolution: {integrity: sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==} engines: {node: '>=8'} @@ -2266,6 +2298,15 @@ packages: supports-color: optional: true + debug@4.4.3: + resolution: {integrity: sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==} + engines: {node: '>=6.0'} + peerDependencies: + supports-color: '*' + peerDependenciesMeta: + supports-color: + optional: true + decamelize@4.0.0: resolution: {integrity: sha512-9iE1PgSik9HeIIw2JO94IidnE3eBoQrFJ3w7sFuzSX4DpmZ3v5sZpUiV5Swcf6mQEF+Y0ru8Neo+p+nyh2J+hQ==} engines: {node: '>=10'} @@ -2836,6 +2877,15 @@ packages: picomatch: optional: true + fdir@6.5.0: + resolution: {integrity: sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==} + engines: {node: '>=12.0.0'} + peerDependencies: + picomatch: ^3 || ^4 + peerDependenciesMeta: + picomatch: + optional: true + figures@6.1.0: resolution: {integrity: sha512-d+l3qxjSesT4V7v2fh+QnmFnUWv9lSpjarhShNTgBOfA0ttejbQUAlHLitbjkoRiDulW0OPoQPYIGhIC8ohejg==} engines: {node: '>=18'} @@ -3152,7 +3202,7 @@ packages: '@testing-library/jest-dom': '*' vite: '*' vite-node: '*' - vitest: ^4.0.0-beta.8 + vitest: ^4.0.0-beta.12 peerDependenciesMeta: '@testing-library/dom': optional: true @@ -3374,6 +3424,10 @@ packages: resolution: {integrity: sha512-BewmUXImeuRk2YY0PVbxgKAysvhRPUQE0h5QRM++nVWyubKGV0l8qQ5op8+B2DOmwSe63Jivj0BjkPQVf8fP5g==} engines: {node: '>=8'} + istanbul-reports@3.2.0: + resolution: {integrity: sha512-HGYWWS/ehqTV3xN10i23tkPkpH46MLCIMFNCaaKNavAXTF1RkqxawEPtnjnGZ6XKSInBKkiOA5BKS+aZiY3AvA==} + engines: {node: '>=8'} + istanbul-to-vscode@2.1.0: resolution: {integrity: sha512-Z5dUFUxYtVc2aCyp/ewCHdOF8v9cTEPFOgtAuZcMiAWDsjv9zgoKLYxd9Y6BvkoxK3Fc+ihc4qd7zfmHsmOo0w==} @@ -3640,6 +3694,9 @@ packages: magic-string@0.30.17: resolution: {integrity: sha512-sNPKHvyjVf7gyjwS4xGTaW/mCnF8wnjtifKBEhxfZ7E/S8tQ0rssrwGNn6q8JH/ohItJfSQp9mBtQYuTlH5QnA==} + magic-string@0.30.19: + resolution: {integrity: sha512-2N21sPY9Ws53PZvsEpVtNuSW+ScYbQdp4b9qUaL+9QkHUrGFKo56Lg9Emg5s9V/qrtNBmiR01sYhUOwu3H+VOw==} + magicast@0.3.5: resolution: {integrity: sha512-L0WhttDl+2BOsybvEOLK7fW3UA0OQ0IQ2d6Zl2x/a6vVRs3bAY0ECOSHHeL5jD+SbOpOCUEi0y1DgHEn9Qn1AQ==} @@ -4562,8 +4619,8 @@ packages: simple-get@4.0.1: resolution: {integrity: sha512-brv7p5WgH0jmQJr1ZDDfKDOSeWWg+OVypG99A/5vYGPqJ6pxiaHLy8nxtFjBA7oMa01ebA9gfh1uMCFqOuXxvA==} - sirv@3.0.1: - resolution: {integrity: sha512-FoqMu0NCGBLCcAkS1qA+XJIQTR6/JHfQXl+uGteNCQ76T91DMUjPa9xfmeqMY3z80nLSg9yQmNjK0Px6RWsH/A==} + sirv@3.0.2: + resolution: {integrity: sha512-2wcC/oGxHis/BoHkkPwldgiPSYcpZK3JU28WoMVv55yHJgcZ8rlXvuG9iZggz+sU1d4bRgIGASwyWqjxu3FM0g==} engines: {node: '>=18'} sisteransi@1.0.5: @@ -4683,9 +4740,6 @@ packages: resolution: {integrity: sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==} engines: {node: '>=8'} - strip-literal@3.0.0: - resolution: {integrity: sha512-TcccoMhJOM3OebGhSBEmp3UZ2SfDMZUEBdRA/9ynfLi8yYajyWX3JiXArcJt4Umh4vISpspkQIY8ZZoCqjbviA==} - structured-source@4.0.0: resolution: {integrity: sha512-qGzRFNJDjFieQkl/sVOI2dUjHKRyL9dAJi2gCPGJLbJHBIkyOHxjuocpIEfbLioX+qSJpvbYdT49/YCdMznKxA==} @@ -4786,14 +4840,26 @@ packages: resolution: {integrity: sha512-tX5e7OM1HnYr2+a2C/4V0htOcSQcoSTH9KgJnVvNm5zm/cyEWKJ7j7YutsH9CxMdtOkkLFy2AHrMci9IM8IPZQ==} engines: {node: '>=12.0.0'} + tinyglobby@0.2.15: + resolution: {integrity: sha512-j2Zq4NyQYG5XMST4cbs02Ak8iJUdxRM0XI5QyxXuZOzKOINmWurp3smXu3y5wDcJrptwpSjgXHzIQxR0omXljQ==} + engines: {node: '>=12.0.0'} + tinypool@1.1.1: resolution: {integrity: sha512-Zba82s87IFq9A9XmjiX5uZA/ARWDrB03OHlq+Vw1fSdt0I+4/Kutwy8BP4Y/y/aORMo61FQ0vIb5j44vSo5Pkg==} engines: {node: ^18.0.0 || >=20.0.0} + tinypool@2.0.0: + resolution: {integrity: sha512-/RX9RzeH2xU5ADE7n2Ykvmi9ED3FBGPAjw9u3zucrNNaEBIO0HPSYgL0NT7+3p147ojeSdaVu08F6hjpv31HJg==} + engines: {node: ^20.0.0 || >=22.0.0} + tinyrainbow@2.0.0: resolution: {integrity: sha512-op4nsTR47R6p0vMUUoYl/a+ljLFVtlfaXkLQmqfLR1qHma1h/ysYk4hEXZ880bf2CYgTskvTa/e196Vd5dDQXw==} engines: {node: '>=14.0.0'} + tinyrainbow@3.0.3: + resolution: {integrity: sha512-PSkbLUoxOFRzJYjjxHJt9xro7D+iilgMX/C9lawzVuYiIdcihh9DXmVibBe8lmcFrRi/VzlPjBxbN7rH24q8/Q==} + engines: {node: '>=14.0.0'} + tinyspy@4.0.3: resolution: {integrity: sha512-t2T/WLB2WRgZ9EpE4jgPJ9w+i66UZfDc8wHh0xrwiRNN+UwH98GIJkTeZqX9rg0i0ptwzqW+uYeIF0T4F8LR7A==} engines: {node: '>=14.0.0'} @@ -5059,7 +5125,7 @@ packages: resolution: {integrity: sha512-JnBZW20iSnt9cwadfeL1E5UXmsSucsCWNC2mvppjPOXAXdS76WvwQW2VKahoAuyB5iQOREVO3pkzmID+yK6orQ==} engines: {node: '>=14'} peerDependencies: - vitest: ^4.0.0-beta.8 + vitest: ^4.0.0-beta.12 vitest@3.2.4: resolution: {integrity: sha512-LUCP5ev3GURDysTWiP47wRRUpLKMOfPh+yKTx3kVIEiu5KOMeqzpnYNsKyOoVrULivR8tLcks4+lga33Whn90A==} @@ -5069,7 +5135,7 @@ packages: '@edge-runtime/vm': '*' '@types/debug': ^4.1.12 '@types/node': ^18.0.0 || ^20.0.0 || >=22.0.0 - '@vitest/browser': ^4.0.0-beta.8 + '@vitest/browser': ^4.0.0-beta.12 '@vitest/ui': 3.2.4 happy-dom: '*' jsdom: '*' @@ -5089,16 +5155,16 @@ packages: jsdom: optional: true - vitest@4.0.0-beta.8: - resolution: {integrity: sha512-wN/RDeCd5uXHV6tELw4AJzeP5rxR4YWXN3ems+59ZummmiovNjlfwG+CEZp5GitlxDQu7muoY4VPrSUxPzzKiQ==} - engines: {node: ^18.0.0 || ^20.0.0 || >=22.0.0} + vitest@4.0.0-beta.12: + resolution: {integrity: sha512-q8b6TSUfeypyYQwC2SBOVbArKLWPbuvRqKw+OlZcStTXI3D2SSg9K9iJNugxjk+1H6i4as/6i4VzV6NmN82MZQ==} + engines: {node: ^20.0.0 || ^22.0.0 || >=24.0.0} hasBin: true peerDependencies: '@edge-runtime/vm': '*' '@types/debug': ^4.1.12 '@types/node': ^18.0.0 || ^20.0.0 || >=22.0.0 - '@vitest/browser': ^4.0.0-beta.8 - '@vitest/ui': 4.0.0-beta.8 + '@vitest/browser': ^4.0.0-beta.12 + '@vitest/ui': 4.0.0-beta.12 happy-dom: '*' jsdom: '*' peerDependenciesMeta: @@ -5355,7 +5421,7 @@ snapshots: '@jridgewell/gen-mapping': 0.3.8 '@jridgewell/trace-mapping': 0.3.25 - '@antfu/eslint-config@4.14.1(@vue/compiler-sfc@3.5.16)(eslint@9.28.0(jiti@2.4.2))(typescript@5.8.3)(vitest@4.0.0-beta.8)': + '@antfu/eslint-config@4.14.1(@vue/compiler-sfc@3.5.16)(eslint@9.28.0(jiti@2.4.2))(typescript@5.8.3)(vitest@4.0.0-beta.12)': dependencies: '@antfu/install-pkg': 1.1.0 '@clack/prompts': 0.11.0 @@ -5364,7 +5430,7 @@ snapshots: '@stylistic/eslint-plugin': 5.0.0-beta.3(eslint@9.28.0(jiti@2.4.2))(typescript@5.8.3) '@typescript-eslint/eslint-plugin': 8.34.0(@typescript-eslint/parser@8.34.0(eslint@9.28.0(jiti@2.4.2))(typescript@5.8.3))(eslint@9.28.0(jiti@2.4.2))(typescript@5.8.3) '@typescript-eslint/parser': 8.34.0(eslint@9.28.0(jiti@2.4.2))(typescript@5.8.3) - '@vitest/eslint-plugin': 1.2.1(eslint@9.28.0(jiti@2.4.2))(typescript@5.8.3)(vitest@4.0.0-beta.8) + '@vitest/eslint-plugin': 1.2.1(eslint@9.28.0(jiti@2.4.2))(typescript@5.8.3)(vitest@4.0.0-beta.12) ansis: 4.1.0 cac: 6.7.14 eslint: 9.28.0(jiti@2.4.2) @@ -5929,11 +5995,18 @@ snapshots: '@jridgewell/sourcemap-codec@1.5.0': {} + '@jridgewell/sourcemap-codec@1.5.5': {} + '@jridgewell/trace-mapping@0.3.25': dependencies: '@jridgewell/resolve-uri': 3.1.2 '@jridgewell/sourcemap-codec': 1.5.0 + '@jridgewell/trace-mapping@0.3.31': + dependencies: + '@jridgewell/resolve-uri': 3.1.2 + '@jridgewell/sourcemap-codec': 1.5.0 + '@mswjs/interceptors@0.39.2': dependencies: '@open-draft/deferred-promise': 2.2.0 @@ -6540,18 +6613,37 @@ snapshots: vite: 7.1.2(@types/node@24.0.0)(jiti@2.4.2)(tsx@4.19.4)(yaml@2.8.0) vue: 3.5.16(typescript@5.8.3) - '@vitest/browser@4.0.0-beta.8(msw@2.10.2(@types/node@24.0.0)(typescript@5.8.3))(playwright@1.52.0)(vite@7.1.2(@types/node@24.0.0)(jiti@2.4.2)(tsx@4.19.4)(yaml@2.8.0))(vitest@3.2.4)': + '@vitest/browser@3.2.4(msw@2.10.2(@types/node@24.0.0)(typescript@5.8.3))(playwright@1.52.0)(vite@7.1.2(@types/node@24.0.0)(jiti@2.4.2)(tsx@4.19.4)(yaml@2.8.0))(vitest@3.2.4)': dependencies: '@testing-library/dom': 10.4.1 '@testing-library/user-event': 14.6.1(@testing-library/dom@10.4.1) - '@vitest/mocker': 4.0.0-beta.8(msw@2.10.2(@types/node@24.0.0)(typescript@5.8.3))(vite@7.1.2(@types/node@24.0.0)(jiti@2.4.2)(tsx@4.19.4)(yaml@2.8.0)) - '@vitest/utils': 4.0.0-beta.8 - magic-string: 0.30.17 + '@vitest/mocker': 3.2.4(msw@2.10.2(@types/node@24.0.0)(typescript@5.8.3))(vite@7.1.2(@types/node@24.0.0)(jiti@2.4.2)(tsx@4.19.4)(yaml@2.8.0)) + '@vitest/utils': 4.0.0-beta.12 + magic-string: 0.30.19 + sirv: 3.0.2 + tinyrainbow: 2.0.0 + vitest: 3.2.4(@types/debug@4.1.12)(@types/node@24.0.0)(@vitest/browser@3.2.4)(happy-dom@15.11.7)(jiti@2.4.2)(jsdom@26.1.0)(msw@2.10.2(@types/node@24.0.0)(typescript@5.8.3))(tsx@4.19.4)(yaml@2.8.0) + ws: 8.18.3 + optionalDependencies: + playwright: 1.52.0 + transitivePeerDependencies: + - bufferutil + - msw + - utf-8-validate + - vite + + '@vitest/browser@4.0.0-beta.12(msw@2.10.2(@types/node@24.0.0)(typescript@5.8.3))(playwright@1.52.0)(vite@7.1.2(@types/node@24.0.0)(jiti@2.4.2)(tsx@4.19.4)(yaml@2.8.0))(vitest@3.2.4)': + dependencies: + '@testing-library/dom': 10.4.1 + '@testing-library/user-event': 14.6.1(@testing-library/dom@10.4.1) + '@vitest/mocker': 4.0.0-beta.12(msw@2.10.2(@types/node@24.0.0)(typescript@5.8.3))(vite@7.1.2(@types/node@24.0.0)(jiti@2.4.2)(tsx@4.19.4)(yaml@2.8.0)) + '@vitest/utils': 4.0.0-beta.12 + magic-string: 0.30.19 pixelmatch: 7.1.0 pngjs: 7.0.0 - sirv: 3.0.1 - tinyrainbow: 2.0.0 - vitest: 3.2.4(@types/debug@4.1.12)(@types/node@24.0.0)(@vitest/browser@4.0.0-beta.8)(happy-dom@15.11.7)(jiti@2.4.2)(jsdom@26.1.0)(msw@2.10.2(@types/node@24.0.0)(typescript@5.8.3))(tsx@4.19.4)(yaml@2.8.0) + sirv: 3.0.2 + tinyrainbow: 3.0.3 + vitest: 3.2.4(@types/debug@4.1.12)(@types/node@24.0.0)(@vitest/browser@4.0.0-beta.12)(happy-dom@15.11.7)(jiti@2.4.2)(jsdom@26.1.0)(msw@2.10.2(@types/node@24.0.0)(typescript@5.8.3))(tsx@4.19.4)(yaml@2.8.0) ws: 8.18.3 optionalDependencies: playwright: 1.52.0 @@ -6562,18 +6654,18 @@ snapshots: - vite optional: true - '@vitest/browser@4.0.0-beta.8(msw@2.10.2(@types/node@24.0.0)(typescript@5.8.3))(playwright@1.52.0)(vite@7.1.2(@types/node@24.0.0)(jiti@2.4.2)(tsx@4.19.4)(yaml@2.8.0))(vitest@4.0.0-beta.8)': + '@vitest/browser@4.0.0-beta.12(msw@2.10.2(@types/node@24.0.0)(typescript@5.8.3))(playwright@1.52.0)(vite@7.1.2(@types/node@24.0.0)(jiti@2.4.2)(tsx@4.19.4)(yaml@2.8.0))(vitest@4.0.0-beta.12)': dependencies: '@testing-library/dom': 10.4.1 '@testing-library/user-event': 14.6.1(@testing-library/dom@10.4.1) - '@vitest/mocker': 4.0.0-beta.8(msw@2.10.2(@types/node@24.0.0)(typescript@5.8.3))(vite@7.1.2(@types/node@24.0.0)(jiti@2.4.2)(tsx@4.19.4)(yaml@2.8.0)) - '@vitest/utils': 4.0.0-beta.8 - magic-string: 0.30.17 + '@vitest/mocker': 4.0.0-beta.12(msw@2.10.2(@types/node@24.0.0)(typescript@5.8.3))(vite@7.1.2(@types/node@24.0.0)(jiti@2.4.2)(tsx@4.19.4)(yaml@2.8.0)) + '@vitest/utils': 4.0.0-beta.12 + magic-string: 0.30.19 pixelmatch: 7.1.0 pngjs: 7.0.0 - sirv: 3.0.1 - tinyrainbow: 2.0.0 - vitest: 4.0.0-beta.8(@types/debug@4.1.12)(@types/node@24.0.0)(@vitest/browser@4.0.0-beta.8)(happy-dom@15.11.7)(jiti@2.4.2)(jsdom@26.1.0)(msw@2.10.2(@types/node@24.0.0)(typescript@5.8.3))(tsx@4.19.4)(yaml@2.8.0) + sirv: 3.0.2 + tinyrainbow: 3.0.3 + vitest: 4.0.0-beta.12(@types/debug@4.1.12)(@types/node@24.0.0)(@vitest/browser@4.0.0-beta.12)(happy-dom@15.11.7)(jiti@2.4.2)(jsdom@26.1.0)(msw@2.10.2(@types/node@24.0.0)(typescript@5.8.3))(tsx@4.19.4)(yaml@2.8.0) ws: 8.18.3 optionalDependencies: playwright: 1.52.0 @@ -6583,32 +6675,32 @@ snapshots: - utf-8-validate - vite - '@vitest/coverage-v8@4.0.0-beta.8(@vitest/browser@4.0.0-beta.8)(vitest@4.0.0-beta.8)': + '@vitest/coverage-v8@4.0.0-beta.12(@vitest/browser@4.0.0-beta.12)(vitest@4.0.0-beta.12)': dependencies: '@bcoe/v8-coverage': 1.0.2 - '@vitest/utils': 4.0.0-beta.8 - ast-v8-to-istanbul: 0.3.3 - debug: 4.4.1(supports-color@8.1.1) + '@vitest/utils': 4.0.0-beta.12 + ast-v8-to-istanbul: 0.3.5 + debug: 4.4.3 istanbul-lib-coverage: 3.2.2 istanbul-lib-report: 3.0.1 istanbul-lib-source-maps: 5.0.6 - istanbul-reports: 3.1.7 + istanbul-reports: 3.2.0 magicast: 0.3.5 std-env: 3.9.0 - tinyrainbow: 2.0.0 - vitest: 4.0.0-beta.8(@types/debug@4.1.12)(@types/node@24.0.0)(@vitest/browser@4.0.0-beta.8)(happy-dom@15.11.7)(jiti@2.4.2)(jsdom@26.1.0)(msw@2.10.2(@types/node@24.0.0)(typescript@5.8.3))(tsx@4.19.4)(yaml@2.8.0) + tinyrainbow: 3.0.3 + vitest: 4.0.0-beta.12(@types/debug@4.1.12)(@types/node@24.0.0)(@vitest/browser@4.0.0-beta.12)(happy-dom@15.11.7)(jiti@2.4.2)(jsdom@26.1.0)(msw@2.10.2(@types/node@24.0.0)(typescript@5.8.3))(tsx@4.19.4)(yaml@2.8.0) optionalDependencies: - '@vitest/browser': 4.0.0-beta.8(msw@2.10.2(@types/node@24.0.0)(typescript@5.8.3))(playwright@1.52.0)(vite@7.1.2(@types/node@24.0.0)(jiti@2.4.2)(tsx@4.19.4)(yaml@2.8.0))(vitest@4.0.0-beta.8) + '@vitest/browser': 4.0.0-beta.12(msw@2.10.2(@types/node@24.0.0)(typescript@5.8.3))(playwright@1.52.0)(vite@7.1.2(@types/node@24.0.0)(jiti@2.4.2)(tsx@4.19.4)(yaml@2.8.0))(vitest@4.0.0-beta.12) transitivePeerDependencies: - supports-color - '@vitest/eslint-plugin@1.2.1(eslint@9.28.0(jiti@2.4.2))(typescript@5.8.3)(vitest@4.0.0-beta.8)': + '@vitest/eslint-plugin@1.2.1(eslint@9.28.0(jiti@2.4.2))(typescript@5.8.3)(vitest@4.0.0-beta.12)': dependencies: '@typescript-eslint/utils': 8.34.0(eslint@9.28.0(jiti@2.4.2))(typescript@5.8.3) eslint: 9.28.0(jiti@2.4.2) optionalDependencies: typescript: 5.8.3 - vitest: 4.0.0-beta.8(@types/debug@4.1.12)(@types/node@24.0.0)(@vitest/browser@4.0.0-beta.8)(happy-dom@15.11.7)(jiti@2.4.2)(jsdom@26.1.0)(msw@2.10.2(@types/node@24.0.0)(typescript@5.8.3))(tsx@4.19.4)(yaml@2.8.0) + vitest: 4.0.0-beta.12(@types/debug@4.1.12)(@types/node@24.0.0)(@vitest/browser@4.0.0-beta.12)(happy-dom@15.11.7)(jiti@2.4.2)(jsdom@26.1.0)(msw@2.10.2(@types/node@24.0.0)(typescript@5.8.3))(tsx@4.19.4)(yaml@2.8.0) transitivePeerDependencies: - supports-color @@ -6616,17 +6708,17 @@ snapshots: dependencies: '@types/chai': 5.2.2 '@vitest/spy': 3.2.4 - '@vitest/utils': 3.2.4 + '@vitest/utils': 4.0.0-beta.12 chai: 5.2.1 tinyrainbow: 2.0.0 - '@vitest/expect@4.0.0-beta.8': + '@vitest/expect@4.0.0-beta.12': dependencies: '@types/chai': 5.2.2 - '@vitest/spy': 4.0.0-beta.8 - '@vitest/utils': 4.0.0-beta.8 - chai: 5.2.1 - tinyrainbow: 2.0.0 + '@vitest/spy': 4.0.0-beta.12 + '@vitest/utils': 4.0.0-beta.12 + chai: 6.0.1 + tinyrainbow: 3.0.3 '@vitest/mocker@3.2.4(msw@2.10.2(@types/node@24.0.0)(typescript@5.8.3))(vite@7.1.2(@types/node@24.0.0)(jiti@2.4.2)(tsx@4.19.4)(yaml@2.8.0))': dependencies: @@ -6637,11 +6729,11 @@ snapshots: msw: 2.10.2(@types/node@24.0.0)(typescript@5.8.3) vite: 7.1.2(@types/node@24.0.0)(jiti@2.4.2)(tsx@4.19.4)(yaml@2.8.0) - '@vitest/mocker@4.0.0-beta.8(msw@2.10.2(@types/node@24.0.0)(typescript@5.8.3))(vite@7.1.2(@types/node@24.0.0)(jiti@2.4.2)(tsx@4.19.4)(yaml@2.8.0))': + '@vitest/mocker@4.0.0-beta.12(msw@2.10.2(@types/node@24.0.0)(typescript@5.8.3))(vite@7.1.2(@types/node@24.0.0)(jiti@2.4.2)(tsx@4.19.4)(yaml@2.8.0))': dependencies: - '@vitest/spy': 4.0.0-beta.8 + '@vitest/spy': 4.0.0-beta.12 estree-walker: 3.0.3 - magic-string: 0.30.17 + magic-string: 0.30.19 optionalDependencies: msw: 2.10.2(@types/node@24.0.0)(typescript@5.8.3) vite: 7.1.2(@types/node@24.0.0)(jiti@2.4.2)(tsx@4.19.4)(yaml@2.8.0) @@ -6650,15 +6742,14 @@ snapshots: dependencies: tinyrainbow: 2.0.0 - '@vitest/pretty-format@4.0.0-beta.8': + '@vitest/pretty-format@4.0.0-beta.12': dependencies: - tinyrainbow: 2.0.0 + tinyrainbow: 3.0.3 - '@vitest/runner@4.0.0-beta.8': + '@vitest/runner@4.0.0-beta.12': dependencies: - '@vitest/utils': 4.0.0-beta.8 + '@vitest/utils': 4.0.0-beta.12 pathe: 2.0.3 - strip-literal: 3.0.0 '@vitest/snapshot@3.2.4': dependencies: @@ -6666,17 +6757,17 @@ snapshots: magic-string: 0.30.17 pathe: 2.0.3 - '@vitest/snapshot@4.0.0-beta.8': + '@vitest/snapshot@4.0.0-beta.12': dependencies: - '@vitest/pretty-format': 4.0.0-beta.8 - magic-string: 0.30.17 + '@vitest/pretty-format': 4.0.0-beta.12 + magic-string: 0.30.19 pathe: 2.0.3 '@vitest/spy@3.2.4': dependencies: tinyspy: 4.0.3 - '@vitest/spy@4.0.0-beta.8': {} + '@vitest/spy@4.0.0-beta.12': {} '@vitest/utils@3.2.4': dependencies: @@ -6684,11 +6775,10 @@ snapshots: loupe: 3.2.0 tinyrainbow: 2.0.0 - '@vitest/utils@4.0.0-beta.8': + '@vitest/utils@4.0.0-beta.12': dependencies: - '@vitest/pretty-format': 4.0.0-beta.8 - loupe: 3.2.0 - tinyrainbow: 2.0.0 + '@vitest/pretty-format': 4.0.0-beta.12 + tinyrainbow: 3.0.3 '@vscode/test-cli@0.0.6': dependencies: @@ -6935,9 +7025,9 @@ snapshots: assertion-error@2.0.1: {} - ast-v8-to-istanbul@0.3.3: + ast-v8-to-istanbul@0.3.5: dependencies: - '@jridgewell/trace-mapping': 0.3.25 + '@jridgewell/trace-mapping': 0.3.31 estree-walker: 3.0.3 js-tokens: 9.0.1 @@ -7134,6 +7224,8 @@ snapshots: loupe: 3.2.0 pathval: 2.0.0 + chai@6.0.1: {} + chalk@3.0.0: dependencies: ansi-styles: 4.3.0 @@ -7358,6 +7450,10 @@ snapshots: optionalDependencies: supports-color: 8.1.1 + debug@4.4.3: + dependencies: + ms: 2.1.3 + decamelize@4.0.0: {} decimal.js@10.5.0: {} @@ -8019,6 +8115,10 @@ snapshots: optionalDependencies: picomatch: 4.0.3 + fdir@6.5.0(picomatch@4.0.3): + optionalDependencies: + picomatch: 4.0.3 + figures@6.1.0: dependencies: is-unicode-supported: 2.1.0 @@ -8355,7 +8455,7 @@ snapshots: ignore@7.0.5: {} - imba@2.0.0-alpha.247(@testing-library/dom@9.3.4)(@testing-library/jest-dom@6.6.3)(picomatch@4.0.3)(vite-node@3.2.4(@types/node@24.0.0)(jiti@2.4.2)(tsx@4.19.4)(yaml@2.8.0))(vite@7.1.2(@types/node@24.0.0)(jiti@2.4.2)(tsx@4.19.4)(yaml@2.8.0))(vitest@4.0.0-beta.8): + imba@2.0.0-alpha.247(@testing-library/dom@9.3.4)(@testing-library/jest-dom@6.6.3)(picomatch@4.0.3)(vite-node@3.2.4(@types/node@24.0.0)(jiti@2.4.2)(tsx@4.19.4)(yaml@2.8.0))(vite@7.1.2(@types/node@24.0.0)(jiti@2.4.2)(tsx@4.19.4)(yaml@2.8.0))(vitest@4.0.0-beta.12): dependencies: '@antfu/install-pkg': 0.1.1 chokidar: 3.6.0 @@ -8375,7 +8475,7 @@ snapshots: '@testing-library/jest-dom': 6.6.3 vite: 7.1.2(@types/node@24.0.0)(jiti@2.4.2)(tsx@4.19.4)(yaml@2.8.0) vite-node: 3.2.4(@types/node@24.0.0)(jiti@2.4.2)(tsx@4.19.4)(yaml@2.8.0) - vitest: 4.0.0-beta.8(@types/debug@4.1.12)(@types/node@24.0.0)(@vitest/browser@4.0.0-beta.8)(happy-dom@15.11.7)(jiti@2.4.2)(jsdom@24.1.3)(msw@2.10.2(@types/node@24.0.0)(typescript@5.8.3))(tsx@4.19.4)(yaml@2.8.0) + vitest: 4.0.0-beta.12(@types/debug@4.1.12)(@types/node@24.0.0)(@vitest/browser@4.0.0-beta.12)(happy-dom@15.11.7)(jiti@2.4.2)(jsdom@24.1.3)(msw@2.10.2(@types/node@24.0.0)(typescript@5.8.3))(tsx@4.19.4)(yaml@2.8.0) transitivePeerDependencies: - picomatch - supports-color @@ -8549,7 +8649,7 @@ snapshots: istanbul-lib-source-maps@5.0.6: dependencies: '@jridgewell/trace-mapping': 0.3.25 - debug: 4.4.1(supports-color@8.1.1) + debug: 4.4.3 istanbul-lib-coverage: 3.2.2 transitivePeerDependencies: - supports-color @@ -8559,6 +8659,11 @@ snapshots: html-escaper: 2.0.2 istanbul-lib-report: 3.0.1 + istanbul-reports@3.2.0: + dependencies: + html-escaper: 2.0.2 + istanbul-lib-report: 3.0.1 + istanbul-to-vscode@2.1.0: dependencies: '@types/istanbul-lib-coverage': 2.0.6 @@ -8846,6 +8951,10 @@ snapshots: dependencies: '@jridgewell/sourcemap-codec': 1.5.0 + magic-string@0.30.19: + dependencies: + '@jridgewell/sourcemap-codec': 1.5.5 + magicast@0.3.5: dependencies: '@babel/parser': 7.27.5 @@ -10042,7 +10151,7 @@ snapshots: simple-concat: 1.0.1 optional: true - sirv@3.0.1: + sirv@3.0.2: dependencies: '@polka/url': 1.0.0-next.29 mrmime: 2.0.1 @@ -10158,10 +10267,6 @@ snapshots: strip-json-comments@3.1.1: {} - strip-literal@3.0.0: - dependencies: - js-tokens: 9.0.1 - structured-source@4.0.0: dependencies: boundary: 2.0.0 @@ -10295,10 +10400,19 @@ snapshots: fdir: 6.4.6(picomatch@4.0.3) picomatch: 4.0.3 + tinyglobby@0.2.15: + dependencies: + fdir: 6.5.0(picomatch@4.0.3) + picomatch: 4.0.3 + tinypool@1.1.1: {} + tinypool@2.0.0: {} + tinyrainbow@2.0.0: {} + tinyrainbow@3.0.3: {} + tinyspy@4.0.3: {} tldts-core@6.1.86: {} @@ -10514,14 +10628,14 @@ snapshots: - tsx - yaml - vite-plugin-imba@0.10.3(imba@2.0.0-alpha.247(@testing-library/dom@9.3.4)(@testing-library/jest-dom@6.6.3)(picomatch@4.0.3)(vite-node@3.2.4(@types/node@24.0.0)(jiti@2.4.2)(tsx@4.19.4)(yaml@2.8.0))(vite@7.1.2(@types/node@24.0.0)(jiti@2.4.2)(tsx@4.19.4)(yaml@2.8.0))(vitest@4.0.0-beta.8))(vite@7.1.2(@types/node@24.0.0)(jiti@2.4.2)(tsx@4.19.4)(yaml@2.8.0)): + vite-plugin-imba@0.10.3(imba@2.0.0-alpha.247(@testing-library/dom@9.3.4)(@testing-library/jest-dom@6.6.3)(picomatch@4.0.3)(vite-node@3.2.4(@types/node@24.0.0)(jiti@2.4.2)(tsx@4.19.4)(yaml@2.8.0))(vite@7.1.2(@types/node@24.0.0)(jiti@2.4.2)(tsx@4.19.4)(yaml@2.8.0))(vitest@4.0.0-beta.12))(vite@7.1.2(@types/node@24.0.0)(jiti@2.4.2)(tsx@4.19.4)(yaml@2.8.0)): dependencies: '@rollup/pluginutils': 4.2.1 cross-env: 7.0.3 debug: 4.4.1(supports-color@8.1.1) deepmerge: 4.3.1 diff: 5.2.0 - imba: 2.0.0-alpha.247(@testing-library/dom@9.3.4)(@testing-library/jest-dom@6.6.3)(picomatch@4.0.3)(vite-node@3.2.4(@types/node@24.0.0)(jiti@2.4.2)(tsx@4.19.4)(yaml@2.8.0))(vite@7.1.2(@types/node@24.0.0)(jiti@2.4.2)(tsx@4.19.4)(yaml@2.8.0))(vitest@4.0.0-beta.8) + imba: 2.0.0-alpha.247(@testing-library/dom@9.3.4)(@testing-library/jest-dom@6.6.3)(picomatch@4.0.3)(vite-node@3.2.4(@types/node@24.0.0)(jiti@2.4.2)(tsx@4.19.4)(yaml@2.8.0))(vite@7.1.2(@types/node@24.0.0)(jiti@2.4.2)(tsx@4.19.4)(yaml@2.8.0))(vitest@4.0.0-beta.12) kleur: 4.1.5 magic-string: 0.26.7 vite: 7.1.2(@types/node@24.0.0)(jiti@2.4.2)(tsx@4.19.4)(yaml@2.8.0) @@ -10543,22 +10657,22 @@ snapshots: tsx: 4.19.4 yaml: 2.8.0 - vitest-github-actions-reporter-temp@0.8.3(vitest@4.0.0-beta.8): + vitest-github-actions-reporter-temp@0.8.3(vitest@4.0.0-beta.12): dependencies: '@actions/core': 1.11.1 source-map-js: 1.2.1 - vitest: 4.0.0-beta.8(@types/debug@4.1.12)(@types/node@24.0.0)(@vitest/browser@4.0.0-beta.8)(happy-dom@15.11.7)(jiti@2.4.2)(jsdom@24.1.3)(msw@2.10.2(@types/node@24.0.0)(typescript@5.8.3))(tsx@4.19.4)(yaml@2.8.0) + vitest: 4.0.0-beta.12(@types/debug@4.1.12)(@types/node@24.0.0)(@vitest/browser@4.0.0-beta.12)(happy-dom@15.11.7)(jiti@2.4.2)(jsdom@24.1.3)(msw@2.10.2(@types/node@24.0.0)(typescript@5.8.3))(tsx@4.19.4)(yaml@2.8.0) - vitest@3.2.4(@types/debug@4.1.12)(@types/node@24.0.0)(@vitest/browser@4.0.0-beta.8)(happy-dom@15.11.7)(jiti@2.4.2)(jsdom@26.1.0)(msw@2.10.2(@types/node@24.0.0)(typescript@5.8.3))(tsx@4.19.4)(yaml@2.8.0): + vitest@3.2.4(@types/debug@4.1.12)(@types/node@24.0.0)(@vitest/browser@3.2.4)(happy-dom@15.11.7)(jiti@2.4.2)(jsdom@26.1.0)(msw@2.10.2(@types/node@24.0.0)(typescript@5.8.3))(tsx@4.19.4)(yaml@2.8.0): dependencies: '@types/chai': 5.2.2 '@vitest/expect': 3.2.4 '@vitest/mocker': 3.2.4(msw@2.10.2(@types/node@24.0.0)(typescript@5.8.3))(vite@7.1.2(@types/node@24.0.0)(jiti@2.4.2)(tsx@4.19.4)(yaml@2.8.0)) '@vitest/pretty-format': 3.2.4 - '@vitest/runner': 4.0.0-beta.8 + '@vitest/runner': 4.0.0-beta.12 '@vitest/snapshot': 3.2.4 '@vitest/spy': 3.2.4 - '@vitest/utils': 3.2.4 + '@vitest/utils': 4.0.0-beta.12 chai: 5.2.1 debug: 4.4.1(supports-color@8.1.1) expect-type: 1.2.2 @@ -10577,7 +10691,7 @@ snapshots: optionalDependencies: '@types/debug': 4.1.12 '@types/node': 24.0.0 - '@vitest/browser': 4.0.0-beta.8(msw@2.10.2(@types/node@24.0.0)(typescript@5.8.3))(playwright@1.52.0)(vite@7.1.2(@types/node@24.0.0)(jiti@2.4.2)(tsx@4.19.4)(yaml@2.8.0))(vitest@3.2.4) + '@vitest/browser': 3.2.4(msw@2.10.2(@types/node@24.0.0)(typescript@5.8.3))(playwright@1.52.0)(vite@7.1.2(@types/node@24.0.0)(jiti@2.4.2)(tsx@4.19.4)(yaml@2.8.0))(vitest@3.2.4) happy-dom: 15.11.7 jsdom: 26.1.0 transitivePeerDependencies: @@ -10594,19 +10708,18 @@ snapshots: - tsx - yaml - vitest@4.0.0-beta.8(@types/debug@4.1.12)(@types/node@24.0.0)(@vitest/browser@4.0.0-beta.8)(happy-dom@14.7.1)(jiti@2.4.2)(jsdom@26.1.0)(msw@2.10.2(@types/node@24.0.0)(typescript@5.8.3))(tsx@4.19.4)(yaml@2.8.0): + vitest@3.2.4(@types/debug@4.1.12)(@types/node@24.0.0)(@vitest/browser@4.0.0-beta.12)(happy-dom@15.11.7)(jiti@2.4.2)(jsdom@26.1.0)(msw@2.10.2(@types/node@24.0.0)(typescript@5.8.3))(tsx@4.19.4)(yaml@2.8.0): dependencies: '@types/chai': 5.2.2 - '@vitest/expect': 4.0.0-beta.8 - '@vitest/mocker': 4.0.0-beta.8(msw@2.10.2(@types/node@24.0.0)(typescript@5.8.3))(vite@7.1.2(@types/node@24.0.0)(jiti@2.4.2)(tsx@4.19.4)(yaml@2.8.0)) - '@vitest/pretty-format': 4.0.0-beta.8 - '@vitest/runner': 4.0.0-beta.8 - '@vitest/snapshot': 4.0.0-beta.8 - '@vitest/spy': 4.0.0-beta.8 - '@vitest/utils': 4.0.0-beta.8 + '@vitest/expect': 3.2.4 + '@vitest/mocker': 3.2.4(msw@2.10.2(@types/node@24.0.0)(typescript@5.8.3))(vite@7.1.2(@types/node@24.0.0)(jiti@2.4.2)(tsx@4.19.4)(yaml@2.8.0)) + '@vitest/pretty-format': 3.2.4 + '@vitest/runner': 4.0.0-beta.12 + '@vitest/snapshot': 3.2.4 + '@vitest/spy': 3.2.4 + '@vitest/utils': 4.0.0-beta.12 chai: 5.2.1 debug: 4.4.1(supports-color@8.1.1) - es-module-lexer: 1.7.0 expect-type: 1.2.2 magic-string: 0.30.17 pathe: 2.0.3 @@ -10618,11 +10731,55 @@ snapshots: tinypool: 1.1.1 tinyrainbow: 2.0.0 vite: 7.1.2(@types/node@24.0.0)(jiti@2.4.2)(tsx@4.19.4)(yaml@2.8.0) + vite-node: 3.2.4(@types/node@24.0.0)(jiti@2.4.2)(tsx@4.19.4)(yaml@2.8.0) + why-is-node-running: 2.3.0 + optionalDependencies: + '@types/debug': 4.1.12 + '@types/node': 24.0.0 + '@vitest/browser': 4.0.0-beta.12(msw@2.10.2(@types/node@24.0.0)(typescript@5.8.3))(playwright@1.52.0)(vite@7.1.2(@types/node@24.0.0)(jiti@2.4.2)(tsx@4.19.4)(yaml@2.8.0))(vitest@3.2.4) + happy-dom: 15.11.7 + jsdom: 26.1.0 + transitivePeerDependencies: + - jiti + - less + - lightningcss + - msw + - sass + - sass-embedded + - stylus + - sugarss + - supports-color + - terser + - tsx + - yaml + + vitest@4.0.0-beta.12(@types/debug@4.1.12)(@types/node@24.0.0)(@vitest/browser@4.0.0-beta.12)(happy-dom@14.7.1)(jiti@2.4.2)(jsdom@26.1.0)(msw@2.10.2(@types/node@24.0.0)(typescript@5.8.3))(tsx@4.19.4)(yaml@2.8.0): + dependencies: + '@vitest/expect': 4.0.0-beta.12 + '@vitest/mocker': 4.0.0-beta.12(msw@2.10.2(@types/node@24.0.0)(typescript@5.8.3))(vite@7.1.2(@types/node@24.0.0)(jiti@2.4.2)(tsx@4.19.4)(yaml@2.8.0)) + '@vitest/pretty-format': 4.0.0-beta.12 + '@vitest/runner': 4.0.0-beta.12 + '@vitest/snapshot': 4.0.0-beta.12 + '@vitest/spy': 4.0.0-beta.12 + '@vitest/utils': 4.0.0-beta.12 + debug: 4.4.3 + es-module-lexer: 1.7.0 + expect-type: 1.2.2 + magic-string: 0.30.19 + pathe: 2.0.3 + picomatch: 4.0.3 + std-env: 3.9.0 + tinybench: 2.9.0 + tinyexec: 0.3.2 + tinyglobby: 0.2.15 + tinypool: 2.0.0 + tinyrainbow: 3.0.3 + vite: 7.1.2(@types/node@24.0.0)(jiti@2.4.2)(tsx@4.19.4)(yaml@2.8.0) why-is-node-running: 2.3.0 optionalDependencies: '@types/debug': 4.1.12 '@types/node': 24.0.0 - '@vitest/browser': 4.0.0-beta.8(msw@2.10.2(@types/node@24.0.0)(typescript@5.8.3))(playwright@1.52.0)(vite@7.1.2(@types/node@24.0.0)(jiti@2.4.2)(tsx@4.19.4)(yaml@2.8.0))(vitest@4.0.0-beta.8) + '@vitest/browser': 4.0.0-beta.12(msw@2.10.2(@types/node@24.0.0)(typescript@5.8.3))(playwright@1.52.0)(vite@7.1.2(@types/node@24.0.0)(jiti@2.4.2)(tsx@4.19.4)(yaml@2.8.0))(vitest@4.0.0-beta.12) happy-dom: 14.7.1 jsdom: 26.1.0 transitivePeerDependencies: @@ -10639,35 +10796,33 @@ snapshots: - tsx - yaml - vitest@4.0.0-beta.8(@types/debug@4.1.12)(@types/node@24.0.0)(@vitest/browser@4.0.0-beta.8)(happy-dom@15.11.7)(jiti@2.4.2)(jsdom@24.1.3)(msw@2.10.2(@types/node@24.0.0)(typescript@5.8.3))(tsx@4.19.4)(yaml@2.8.0): + vitest@4.0.0-beta.12(@types/debug@4.1.12)(@types/node@24.0.0)(@vitest/browser@4.0.0-beta.12)(happy-dom@15.11.7)(jiti@2.4.2)(jsdom@24.1.3)(msw@2.10.2(@types/node@24.0.0)(typescript@5.8.3))(tsx@4.19.4)(yaml@2.8.0): dependencies: - '@types/chai': 5.2.2 - '@vitest/expect': 4.0.0-beta.8 - '@vitest/mocker': 4.0.0-beta.8(msw@2.10.2(@types/node@24.0.0)(typescript@5.8.3))(vite@7.1.2(@types/node@24.0.0)(jiti@2.4.2)(tsx@4.19.4)(yaml@2.8.0)) - '@vitest/pretty-format': 4.0.0-beta.8 - '@vitest/runner': 4.0.0-beta.8 - '@vitest/snapshot': 4.0.0-beta.8 - '@vitest/spy': 4.0.0-beta.8 - '@vitest/utils': 4.0.0-beta.8 - chai: 5.2.1 - debug: 4.4.1(supports-color@8.1.1) + '@vitest/expect': 4.0.0-beta.12 + '@vitest/mocker': 4.0.0-beta.12(msw@2.10.2(@types/node@24.0.0)(typescript@5.8.3))(vite@7.1.2(@types/node@24.0.0)(jiti@2.4.2)(tsx@4.19.4)(yaml@2.8.0)) + '@vitest/pretty-format': 4.0.0-beta.12 + '@vitest/runner': 4.0.0-beta.12 + '@vitest/snapshot': 4.0.0-beta.12 + '@vitest/spy': 4.0.0-beta.12 + '@vitest/utils': 4.0.0-beta.12 + debug: 4.4.3 es-module-lexer: 1.7.0 expect-type: 1.2.2 - magic-string: 0.30.17 + magic-string: 0.30.19 pathe: 2.0.3 picomatch: 4.0.3 std-env: 3.9.0 tinybench: 2.9.0 tinyexec: 0.3.2 - tinyglobby: 0.2.14 - tinypool: 1.1.1 - tinyrainbow: 2.0.0 + tinyglobby: 0.2.15 + tinypool: 2.0.0 + tinyrainbow: 3.0.3 vite: 7.1.2(@types/node@24.0.0)(jiti@2.4.2)(tsx@4.19.4)(yaml@2.8.0) why-is-node-running: 2.3.0 optionalDependencies: '@types/debug': 4.1.12 '@types/node': 24.0.0 - '@vitest/browser': 4.0.0-beta.8(msw@2.10.2(@types/node@24.0.0)(typescript@5.8.3))(playwright@1.52.0)(vite@7.1.2(@types/node@24.0.0)(jiti@2.4.2)(tsx@4.19.4)(yaml@2.8.0))(vitest@4.0.0-beta.8) + '@vitest/browser': 4.0.0-beta.12(msw@2.10.2(@types/node@24.0.0)(typescript@5.8.3))(playwright@1.52.0)(vite@7.1.2(@types/node@24.0.0)(jiti@2.4.2)(tsx@4.19.4)(yaml@2.8.0))(vitest@4.0.0-beta.12) happy-dom: 15.11.7 jsdom: 24.1.3 transitivePeerDependencies: @@ -10684,35 +10839,33 @@ snapshots: - tsx - yaml - vitest@4.0.0-beta.8(@types/debug@4.1.12)(@types/node@24.0.0)(@vitest/browser@4.0.0-beta.8)(happy-dom@15.11.7)(jiti@2.4.2)(jsdom@26.1.0)(msw@2.10.2(@types/node@24.0.0)(typescript@5.8.3))(tsx@4.19.4)(yaml@2.8.0): + vitest@4.0.0-beta.12(@types/debug@4.1.12)(@types/node@24.0.0)(@vitest/browser@4.0.0-beta.12)(happy-dom@15.11.7)(jiti@2.4.2)(jsdom@26.1.0)(msw@2.10.2(@types/node@24.0.0)(typescript@5.8.3))(tsx@4.19.4)(yaml@2.8.0): dependencies: - '@types/chai': 5.2.2 - '@vitest/expect': 4.0.0-beta.8 - '@vitest/mocker': 4.0.0-beta.8(msw@2.10.2(@types/node@24.0.0)(typescript@5.8.3))(vite@7.1.2(@types/node@24.0.0)(jiti@2.4.2)(tsx@4.19.4)(yaml@2.8.0)) - '@vitest/pretty-format': 4.0.0-beta.8 - '@vitest/runner': 4.0.0-beta.8 - '@vitest/snapshot': 4.0.0-beta.8 - '@vitest/spy': 4.0.0-beta.8 - '@vitest/utils': 4.0.0-beta.8 - chai: 5.2.1 - debug: 4.4.1(supports-color@8.1.1) + '@vitest/expect': 4.0.0-beta.12 + '@vitest/mocker': 4.0.0-beta.12(msw@2.10.2(@types/node@24.0.0)(typescript@5.8.3))(vite@7.1.2(@types/node@24.0.0)(jiti@2.4.2)(tsx@4.19.4)(yaml@2.8.0)) + '@vitest/pretty-format': 4.0.0-beta.12 + '@vitest/runner': 4.0.0-beta.12 + '@vitest/snapshot': 4.0.0-beta.12 + '@vitest/spy': 4.0.0-beta.12 + '@vitest/utils': 4.0.0-beta.12 + debug: 4.4.3 es-module-lexer: 1.7.0 expect-type: 1.2.2 - magic-string: 0.30.17 + magic-string: 0.30.19 pathe: 2.0.3 picomatch: 4.0.3 std-env: 3.9.0 tinybench: 2.9.0 tinyexec: 0.3.2 - tinyglobby: 0.2.14 - tinypool: 1.1.1 - tinyrainbow: 2.0.0 + tinyglobby: 0.2.15 + tinypool: 2.0.0 + tinyrainbow: 3.0.3 vite: 7.1.2(@types/node@24.0.0)(jiti@2.4.2)(tsx@4.19.4)(yaml@2.8.0) why-is-node-running: 2.3.0 optionalDependencies: '@types/debug': 4.1.12 '@types/node': 24.0.0 - '@vitest/browser': 4.0.0-beta.8(msw@2.10.2(@types/node@24.0.0)(typescript@5.8.3))(playwright@1.52.0)(vite@7.1.2(@types/node@24.0.0)(jiti@2.4.2)(tsx@4.19.4)(yaml@2.8.0))(vitest@4.0.0-beta.8) + '@vitest/browser': 4.0.0-beta.12(msw@2.10.2(@types/node@24.0.0)(typescript@5.8.3))(playwright@1.52.0)(vite@7.1.2(@types/node@24.0.0)(jiti@2.4.2)(tsx@4.19.4)(yaml@2.8.0))(vitest@4.0.0-beta.12) happy-dom: 15.11.7 jsdom: 26.1.0 transitivePeerDependencies: diff --git a/pnpm-workspace.yaml b/pnpm-workspace.yaml index c0e317bd..81ff6fe6 100644 --- a/pnpm-workspace.yaml +++ b/pnpm-workspace.yaml @@ -5,10 +5,10 @@ packages: - samples/monorepo-vitest-workspace/packages/* catalog: - '@vitest/browser': ^4.0.0-beta.8 - '@vitest/coverage-istanbul': ^4.0.0-beta.8 - '@vitest/coverage-v8': ^4.0.0-beta.8 - '@vitest/runner': ^4.0.0-beta.8 - '@vitest/utils': ^4.0.0-beta.8 + '@vitest/browser': ^4.0.0-beta.12 + '@vitest/coverage-istanbul': ^4.0.0-beta.12 + '@vitest/coverage-v8': ^4.0.0-beta.12 + '@vitest/runner': ^4.0.0-beta.12 + '@vitest/utils': ^4.0.0-beta.12 vite: ^7.1.0 vitest: ^3.2.2 diff --git a/samples/browser/vitest.config.ts b/samples/browser/vitest.config.ts index e6036e3f..388253a2 100644 --- a/samples/browser/vitest.config.ts +++ b/samples/browser/vitest.config.ts @@ -4,18 +4,25 @@ import { defineConfig } from 'vitest/config' -export default defineConfig({ - esbuild: { - target: 'es2020', - }, - test: { - include: ['test/**/*.test.ts'], - exclude: ['test/ignored.test.ts'], - browser: { - enabled: true, - name: 'chromium', - headless: true, - provider: 'playwright' - } - }, +export default defineConfig(async () => { + const provider: any = process.env.TEST_LEGACY !== 'true' + ? (await import('@vitest/browser/providers/playwright')).playwright() + : 'playwright' + return { + esbuild: { + target: 'es2020', + }, + test: { + include: ['test/**/*.test.ts'], + exclude: ['test/ignored.test.ts'], + browser: { + enabled: true, + headless: true, + provider, + instances: [ + { browser: 'chromium' }, + ], + } + }, + } }) diff --git a/test/e2e/discovery.test.ts b/test/e2e/discovery.test.ts deleted file mode 100644 index d3e449f6..00000000 --- a/test/e2e/discovery.test.ts +++ /dev/null @@ -1,78 +0,0 @@ -import { resolve } from 'node:path' -import type { RunnerTestCase, RunnerTestSuite } from 'vitest' -import { describe, expect, it, onTestFinished } from 'vitest' -import { createVitest } from 'vitest/node' -import { astCollectTests } from '../../packages/worker-legacy/src/collect' - -const variableFixture = 'test-from-vitest-variable.ts' - -describe('can discover tests', () => { - it.for([ - 'todo-import-suite.ts', - 'todo-globals-suite.ts', - variableFixture, - ])('can discover todo tests inside a suite in %s', async (fixture) => { - const vitest = await createVitest('test', { config: false }) - onTestFinished(() => vitest.close()) - const file = await astCollectTests( - vitest.getRootProject(), - resolve(`test/e2e/fixtures/collect/${fixture}`), - ) - expect(file.filepath).toBe(resolve(`test/e2e/fixtures/collect/${fixture}`)) - expect(file.name).toBe(`test/e2e/fixtures/collect/${fixture}`) - - expect(file.tasks).toHaveLength(1) - const suite = file.tasks[0] as RunnerTestSuite - expect(suite.name).toBe('TicketDetailBottomBar') - expect(suite.mode).toBe('run') - expect(suite.location).toMatchObject({ - line: 3, - column: 0, - }) - expect(suite.tasks).toHaveLength(2) - - const [testTask, suiteTask] = suite.tasks as [RunnerTestCase, RunnerTestSuite] - expect(testTask.name).toBe('emits %s event when button is clicked') - expect((testTask as any).dynamic).toBe(true) - expect(testTask.mode).toBe('run') - expect(testTask.location).toMatchObject({ - line: 4, - column: variableFixture === fixture ? 38 : 31, // TODO: should it be 5 instead? since we only care about "line", ignore for now - }) - - expect(suiteTask.name).toBe('Drafts') - expect(suiteTask.mode).toBe('skip') - expect(suiteTask.location).toMatchObject({ - line: 10, - column: 2, - }) - expect(suiteTask.tasks).toHaveLength(2) - - const [todo1, todo2] = suiteTask.tasks as RunnerTestCase[] - expect(todo1.name).toBe('should not display draft information if ticket has no draft') - expect(todo1.mode).toBe('todo') - expect(todo1.location).toMatchObject({ - line: 11, - column: 4, - }) - - expect(todo2.name).toBe('should display draft information if ticket has a draft') - expect(todo2.mode).toBe('todo') - expect(todo2.location).toMatchObject({ - line: 12, - column: 4, - }) - }) - - it('identifiers as names', async () => { - const vitest = await createVitest('test', { config: false }) - onTestFinished(() => vitest.close()) - const file = await astCollectTests( - vitest.getRootProject(), - resolve(`test/e2e/fixtures/collect/method-names.ts`), - ) - - expect(file.tasks[0].name).toBe('MathClass') - expect((file.tasks[0] as RunnerTestSuite).tasks[0].name).toBe('MathClass.add') - }) -}) diff --git a/test/e2e/fixtures/collect/math-class.ts b/test/e2e/fixtures/collect/math-class.ts deleted file mode 100644 index 8a47c171..00000000 --- a/test/e2e/fixtures/collect/math-class.ts +++ /dev/null @@ -1,5 +0,0 @@ -export class MathClass { - static add(a: number, b: number): number { - return a + b - } -} diff --git a/test/e2e/fixtures/collect/method-names.ts b/test/e2e/fixtures/collect/method-names.ts deleted file mode 100644 index fd2faa0f..00000000 --- a/test/e2e/fixtures/collect/method-names.ts +++ /dev/null @@ -1,12 +0,0 @@ -import { describe, expect, it } from 'vitest' -import { MathClass } from './math-class' - -describe(MathClass, () => { - describe(MathClass.add, () => { - it('adds 2 + 2', () => { - const expected = 4 - const actual = MathClass.add(2, 2) - expect(actual).toBe(expected) - }) - }) -}) diff --git a/test/e2e/fixtures/collect/test-from-vitest-variable.ts b/test/e2e/fixtures/collect/test-from-vitest-variable.ts deleted file mode 100644 index ae85860c..00000000 --- a/test/e2e/fixtures/collect/test-from-vitest-variable.ts +++ /dev/null @@ -1,14 +0,0 @@ -import { Vitest } from './vitest' - -Vitest.describe('TicketDetailBottomBar', () => { - Vitest.it.each(['submit', 'discard'])( - 'emits %s event when button is clicked', - async (eventName) => { - }, - ) - - Vitest.describe('Drafts', () => { - Vitest.it.todo('should not display draft information if ticket has no draft') - Vitest.it.todo('should display draft information if ticket has a draft') - }) -}) diff --git a/test/e2e/fixtures/collect/todo-globals-suite.ts b/test/e2e/fixtures/collect/todo-globals-suite.ts deleted file mode 100644 index c7b73e94..00000000 --- a/test/e2e/fixtures/collect/todo-globals-suite.ts +++ /dev/null @@ -1,14 +0,0 @@ -// @ts-nocheck - -describe('TicketDetailBottomBar', () => { - it.each(['submit', 'discard'])( - 'emits %s event when button is clicked', - async (eventName) => { - }, - ) - - describe('Drafts', () => { - it.todo('should not display draft information if ticket has no draft') - it.todo('should display draft information if ticket has a draft') - }) -}) diff --git a/test/e2e/fixtures/collect/todo-import-suite.ts b/test/e2e/fixtures/collect/todo-import-suite.ts deleted file mode 100644 index 6c54fd41..00000000 --- a/test/e2e/fixtures/collect/todo-import-suite.ts +++ /dev/null @@ -1,14 +0,0 @@ -import { describe, it } from 'vitest' - -describe('TicketDetailBottomBar', () => { - it.each(['submit', 'discard'])( - 'emits %s event when button is clicked', - async (eventName) => { - }, - ) - - describe('Drafts', () => { - it.todo('should not display draft information if ticket has no draft') - it.todo('should display draft information if ticket has a draft') - }) -}) diff --git a/test/e2e/fixtures/collect/vitest.ts b/test/e2e/fixtures/collect/vitest.ts deleted file mode 100644 index 3914830a..00000000 --- a/test/e2e/fixtures/collect/vitest.ts +++ /dev/null @@ -1 +0,0 @@ -export * as Vitest from 'vitest' diff --git a/test/unit/TestData.test.ts b/test/unit/TestData.test.ts index b8112214..f217bec2 100644 --- a/test/unit/TestData.test.ts +++ b/test/unit/TestData.test.ts @@ -26,7 +26,7 @@ describe('TestData', () => { folderItem, filepath, null as any, // not used yet - '', + { project: '', pool: 'trheads' }, ) const suiteItem = ctrl.createTestItem( `${filepath}_1`, diff --git a/tsup.config.ts b/tsup.config.ts index 66b0bcae..d165c63d 100644 --- a/tsup.config.ts +++ b/tsup.config.ts @@ -23,8 +23,13 @@ export default defineConfig([ format: 'cjs', }, { - entry: ['./packages/extension/src/worker/setupFile.ts'], + entry: ['./packages/worker-legacy/src/setupFile.ts'], external: ['vitest'], format: 'esm', }, + { + entry: ['./packages/extension/src/worker/browserSetupFile.ts'], + external: ['vitest', '@vitest/browser/context'], + format: 'esm', + }, ])