diff --git a/packages/playwright-test/src/mount.ts b/packages/playwright-test/src/mount.ts index 15948df22fed1..322a663cd1b9b 100644 --- a/packages/playwright-test/src/mount.ts +++ b/packages/playwright-test/src/mount.ts @@ -14,35 +14,43 @@ * limitations under the License. */ -import type { Fixtures, Locator, Page, PlaywrightTestArgs, PlaywrightTestOptions, PlaywrightWorkerArgs } from './types'; +import type { Fixtures, Locator, Page, BrowserContextOptions, PlaywrightTestArgs, PlaywrightTestOptions, PlaywrightWorkerArgs } from './types'; let boundCallbacksForMount: Function[] = []; -export const fixtures: Fixtures Promise }, PlaywrightWorkerArgs & { _workerPage: Page }> = { - _workerPage: [async ({ browser }, use) => { - const page = await (browser as any)._wrapApiCall(async () => { - const page = await browser.newPage(); - await page.addInitScript('navigator.serviceWorker.register = () => {}'); - await page.exposeFunction('__pw_dispatch', (ordinal: number, args: any[]) => { - boundCallbacksForMount[ordinal](...args); - }); - return page; - }); - await use(page); - }, { scope: 'worker' }], +export const fixtures: Fixtures Promise }, PlaywrightWorkerArgs & { _ctPage: { page: Page | undefined, hash: string } }> = { + _ctPage: [{ page: undefined, hash: '' }, { scope: 'worker' }], context: async ({ page }, use) => { await use(page.context()); }, - page: async ({ _workerPage, viewport }, use) => { - const page = _workerPage; - await page.goto('about:blank'); - await (page as any)._resetForReuse(); - await (page.context() as any)._resetForReuse(); - await page.setViewportSize(viewport || { width: 1280, height: 800 }); + page: async ({ _ctPage, browser, viewport, playwright }, use) => { + const defaultContextOptions = (playwright.chromium as any)._defaultContextOptions as BrowserContextOptions; + const hash = contextHash(defaultContextOptions); + + if (!_ctPage.page || _ctPage.hash !== hash) { + if (_ctPage.page) + await _ctPage.page.close(); + _ctPage.page = await (browser as any)._wrapApiCall(async () => { + const page = await browser.newPage(); + await page.addInitScript('navigator.serviceWorker.register = () => {}'); + await page.exposeFunction('__pw_dispatch', (ordinal: number, args: any[]) => { + boundCallbacksForMount[ordinal](...args); + }); + return page; + }); + _ctPage.hash = hash; + } else { + await (_ctPage.page as any)._resetForReuse(); + await (_ctPage.page.context() as any)._resetForReuse(); + await _ctPage.page.goto('about:blank'); + await _ctPage.page.setViewportSize(viewport || { width: 1280, height: 800 }); + } + + const page = _ctPage.page!; await page.goto(process.env.PLAYWRIGHT_VITE_COMPONENTS_BASE_URL!); - await use(_workerPage); + await use(page); }, mount: async ({ page }, use) => { @@ -100,3 +108,28 @@ function wrapFunctions(object: any, page: Page, callbacks: Function[]) { } } } + +function contextHash(context: BrowserContextOptions): string { + const hash = { + acceptDownloads: context.acceptDownloads, + bypassCSP: context.bypassCSP, + colorScheme: context.colorScheme, + extraHTTPHeaders: context.extraHTTPHeaders, + forcedColors: context.forcedColors, + geolocation: context.geolocation, + hasTouch: context.hasTouch, + httpCredentials: context.httpCredentials, + ignoreHTTPSErrors: context.ignoreHTTPSErrors, + isMobile: context.isMobile, + javaScriptEnabled: context.javaScriptEnabled, + locale: context.locale, + offline: context.offline, + permissions: context.permissions, + proxy: context.proxy, + storageState: context.storageState, + timezoneId: context.timezoneId, + userAgent: context.userAgent, + deviceScaleFactor: context.deviceScaleFactor, + }; + return JSON.stringify(hash); +}