diff --git a/packages/angular/build/src/builders/unit-test/runners/vitest/browser-provider.ts b/packages/angular/build/src/builders/unit-test/runners/vitest/browser-provider.ts index be2fc3da22f7..da1827790794 100644 --- a/packages/angular/build/src/builders/unit-test/runners/vitest/browser-provider.ts +++ b/packages/angular/build/src/builders/unit-test/runners/vitest/browser-provider.ts @@ -18,12 +18,16 @@ export interface BrowserConfiguration { function findBrowserProvider( projectResolver: NodeJS.RequireResolve, ): BrowserBuiltinProvider | undefined { + const requiresPreview = !!process.versions.webcontainer; + // One of these must be installed in the project to use browser testing - const vitestBuiltinProviders = ['playwright', 'webdriverio'] as const; + const vitestBuiltinProviders = requiresPreview + ? (['preview'] as const) + : (['playwright', 'webdriverio', 'preview'] as const); for (const providerName of vitestBuiltinProviders) { try { - projectResolver(providerName); + projectResolver(`@vitest/browser-${providerName}`); return providerName; } catch {} @@ -102,13 +106,18 @@ export async function setupBrowserConfiguration( } const isCI = !!process.env['CI']; - const headless = isCI || browsers.some((name) => name.toLowerCase().includes('headless')); + let headless = isCI || browsers.some((name) => name.toLowerCase().includes('headless')); + if (providerName === 'preview') { + // `preview` provider does not support headless mode + headless = false; + } const browser = { enabled: true, provider, headless, ui: !headless, + isolate: debug, viewport, instances: browsers.map((browserName) => ({ browser: normalizeBrowserName(browserName), diff --git a/packages/angular/build/src/builders/unit-test/runners/vitest/index.ts b/packages/angular/build/src/builders/unit-test/runners/vitest/index.ts index a36b75331388..6ff67a56563c 100644 --- a/packages/angular/build/src/builders/unit-test/runners/vitest/index.ts +++ b/packages/angular/build/src/builders/unit-test/runners/vitest/index.ts @@ -23,10 +23,15 @@ const VitestTestRunner: TestRunner = { checker.check('vitest'); if (options.browsers?.length) { - checker.checkAny( - ['playwright', 'webdriverio'], - 'The "browsers" option requires either "playwright" or "webdriverio" to be installed.', - ); + if (process.versions.webcontainer) { + checker.check('@vitest/browser-preview'); + } else { + checker.checkAny( + ['@vitest/browser-playwright', '@vitest/browser-webdriverio', '@vitest/browser-preview'], + 'The "browsers" option requires either ' + + '"@vitest/browser-playwright", "@vitest/browser-webdriverio", or "@vitest/browser-preview" to be installed.', + ); + } } else { // JSDOM is used when no browsers are specified checker.check('jsdom'); @@ -47,6 +52,12 @@ const VitestTestRunner: TestRunner = { const projectName = context.target?.project; assert(projectName, 'The builder requires a target.'); + if (!!process.versions.webcontainer && options.browsers?.length) { + context.logger.info( + `Webcontainer environment detected. Using '@vitest/browser-preview' for browser-based tests.`, + ); + } + if (typeof options.runnerConfig === 'string') { context.logger.info(`Using Vitest configuration file: ${options.runnerConfig}`); } else if (options.runnerConfig) {