diff --git a/packages/vitest/src/node/browser/playwright.ts b/packages/vitest/src/node/browser/playwright.ts index 7bda5ed11f70..3c8feb3f121d 100644 --- a/packages/vitest/src/node/browser/playwright.ts +++ b/packages/vitest/src/node/browser/playwright.ts @@ -2,6 +2,7 @@ import type { Page } from 'playwright' import type { BrowserProvider, BrowserProviderOptions } from '../../types/browser' import { ensurePackageInstalled } from '../pkg' import type { WorkspaceProject } from '../workspace' +import type { Awaitable } from '../../types' export const playwrightBrowsers = ['firefox', 'webkit', 'chromium'] as const export type PlaywrightBrowser = typeof playwrightBrowsers[number] @@ -49,6 +50,13 @@ export class PlaywrightBrowserProvider implements BrowserProvider { return this.cachedBrowser } + catchError(cb: (error: Error) => Awaitable) { + this.cachedBrowser?.on('pageerror', cb) + return () => { + this.cachedBrowser?.off('pageerror', cb) + } + } + async openPage(url: string) { const browserInstance = await this.openBrowser() await browserInstance.goto(url) diff --git a/packages/vitest/src/node/browser/webdriver.ts b/packages/vitest/src/node/browser/webdriver.ts index 7c8634dd2765..5939df299e4c 100644 --- a/packages/vitest/src/node/browser/webdriver.ts +++ b/packages/vitest/src/node/browser/webdriver.ts @@ -1,4 +1,5 @@ import type { Browser } from 'webdriverio' +import type { Awaitable } from '@vitest/utils' import type { BrowserProvider, BrowserProviderOptions } from '../../types/browser' import { ensurePackageInstalled } from '../pkg' import type { WorkspaceProject } from '../workspace' @@ -70,6 +71,11 @@ export class WebdriverBrowserProvider implements BrowserProvider { await browserInstance.url(url) } + // TODO + catchError(_cb: (error: Error) => Awaitable) { + return () => {} + } + async close() { await Promise.all([ this.stopSafari(), diff --git a/packages/vitest/src/node/pools/browser.ts b/packages/vitest/src/node/pools/browser.ts index 3fa8cc76a6e1..eeb31c665d40 100644 --- a/packages/vitest/src/node/pools/browser.ts +++ b/packages/vitest/src/node/pools/browser.ts @@ -8,10 +8,23 @@ import type { BrowserProvider } from '../../types/browser' export function createBrowserPool(ctx: Vitest): ProcessPool { const providers = new Set() - const waitForTest = (id: string) => { + const waitForTest = async (provider: BrowserProvider, id: string) => { const defer = createDefer() ctx.state.browserTestPromises.set(id, defer) - return defer + const off = provider.catchError((error) => { + if (id !== 'no-isolate') { + Object.defineProperty(error, 'VITEST_TEST_PATH', { + value: id, + }) + } + defer.reject(error) + }) + try { + return await defer + } + finally { + off() + } } const runTests = async (project: WorkspaceProject, files: string[]) => { @@ -40,7 +53,7 @@ export function createBrowserPool(ctx: Vitest): ProcessPool { url.searchParams.append('path', path) url.searchParams.set('id', path) await provider.openPage(url.toString()) - await waitForTest(path) + await waitForTest(provider, path) } } else { @@ -48,7 +61,7 @@ export function createBrowserPool(ctx: Vitest): ProcessPool { url.searchParams.set('id', 'no-isolate') paths.forEach(path => url.searchParams.append('path', path)) await provider.openPage(url.toString()) - await waitForTest('no-isolate') + await waitForTest(provider, 'no-isolate') } } diff --git a/packages/vitest/src/types/browser.ts b/packages/vitest/src/types/browser.ts index 72254997112c..9cc8616cf863 100644 --- a/packages/vitest/src/types/browser.ts +++ b/packages/vitest/src/types/browser.ts @@ -11,6 +11,7 @@ export interface BrowserProvider { getSupportedBrowsers(): readonly string[] initialize(ctx: WorkspaceProject, options: BrowserProviderOptions): Awaitable openPage(url: string): Awaitable + catchError(cb: (error: Error) => Awaitable): () => Awaitable close(): Awaitable }