From 626c357e214d3d25087a089cdacc7699322fb431 Mon Sep 17 00:00:00 2001 From: Charles Lyding <19598772+clydin@users.noreply.github.com> Date: Wed, 5 Nov 2025 16:19:47 -0500 Subject: [PATCH] fix(@angular/build): add webcontainer support for Vitest browser provider Currently, Vitest's browser providers (playwright, webdriverio) are not compatible with webcontainer environments. This change introduces detection for webcontainers and and automatically configures the Vitest unit test builder to use the `@vitest/browser-preview` provider when running within a webcontainer. This ensures that browser-based unit tests can execute correctly in webcontainer environments, providing a more consistent development experience across different platforms. The user is notified when the webcontainer environment is detected and the preview provider is activated. Dependency checks are also updated to ensure the correct `@vitest/browser-preview` package is installed when needed. --- .../runners/vitest/browser-provider.ts | 15 ++++++++++++--- .../unit-test/runners/vitest/index.ts | 19 +++++++++++++++---- 2 files changed, 27 insertions(+), 7 deletions(-) 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) {