diff --git a/packages/playwright-core/src/client/browserType.ts b/packages/playwright-core/src/client/browserType.ts index 06672cc64e..567fdc3c76 100644 --- a/packages/playwright-core/src/client/browserType.ts +++ b/packages/playwright-core/src/client/browserType.ts @@ -49,7 +49,7 @@ export class BrowserType extends ChannelOwner imple _defaultContextOptions?: BrowserContextOptions; _defaultContextTimeout?: number; _defaultContextNavigationTimeout?: number; - private _defaultLaunchOptions?: LaunchOptions; + _defaultLaunchOptions?: LaunchOptions; static from(browserType: channels.BrowserTypeChannel): BrowserType { return (browserType as any)._object; diff --git a/packages/playwright-core/src/client/playwright.ts b/packages/playwright-core/src/client/playwright.ts index 9933ce15de..eb476542fb 100644 --- a/packages/playwright-core/src/client/playwright.ts +++ b/packages/playwright-core/src/client/playwright.ts @@ -73,4 +73,16 @@ export class Playwright extends ChannelOwner { static from(channel: channels.PlaywrightChannel): Playwright { return (channel as any)._object; } + + _browserTypes(): BrowserType[] { + return [this.chromium, this.firefox, this.webkit, this._bidiChromium, this._bidiFirefox]; + } + + _allContexts() { + return this._browserTypes().flatMap(type => [...type._contexts]); + } + + _allPages() { + return this._allContexts().flatMap(context => context.pages()); + } } diff --git a/packages/playwright/src/index.ts b/packages/playwright/src/index.ts index 83913c18dc..370a7040d9 100644 --- a/packages/playwright/src/index.ts +++ b/packages/playwright/src/index.ts @@ -24,6 +24,7 @@ import type { TestInfoImpl, TestStepInternal } from './worker/testInfo'; import { rootTestType } from './common/testType'; import type { ContextReuseMode } from './common/config'; import type { ApiCallData, ClientInstrumentation, ClientInstrumentationListener } from '../../playwright-core/src/client/clientInstrumentation'; +import type { Playwright as PlaywrightImpl } from '../../playwright-core/src/client/playwright'; import { currentTestInfo } from './common/globals'; export { expect } from './matchers/expect'; export const _baseTest: TestType<{}, {}> = rootTestType.test; @@ -50,6 +51,7 @@ type TestFixtures = PlaywrightTestArgs & PlaywrightTestOptions & { }; type WorkerFixtures = PlaywrightWorkerArgs & PlaywrightWorkerOptions & { + playwright: PlaywrightImpl; _browserOptions: LaunchOptions; _optionContextReuseMode: ContextReuseMode, _optionConnectOptions: PlaywrightWorkerOptions['connectOptions'], @@ -83,11 +85,11 @@ const playwrightFixtures: Fixtures = ({ options.channel = channel; options.tracesDir = tracing().tracesDir(); - for (const browserType of [playwright.chromium, playwright.firefox, playwright.webkit, playwright._bidiChromium, playwright._bidiFirefox]) - (browserType as any)._defaultLaunchOptions = options; + for (const browserType of playwright._browserTypes()) + browserType._defaultLaunchOptions = options; await use(options); - for (const browserType of [playwright.chromium, playwright.firefox, playwright.webkit, playwright._bidiChromium, playwright._bidiFirefox]) - (browserType as any)._defaultLaunchOptions = undefined; + for (const browserType of playwright._browserTypes()) + browserType._defaultLaunchOptions = undefined; }, { scope: 'worker', auto: true, box: true }], browser: [async ({ playwright, browserName, _browserOptions, connectOptions, _reuseContext }, use, testInfo) => { @@ -230,20 +232,21 @@ const playwrightFixtures: Fixtures = ({ testInfo.snapshotSuffix = process.platform; if (debugMode()) (testInfo as TestInfoImpl)._setDebugMode(); - for (const browserType of [playwright.chromium, playwright.firefox, playwright.webkit]) { - (browserType as any)._defaultContextOptions = _combinedContextOptions; - (browserType as any)._defaultContextTimeout = actionTimeout || 0; - (browserType as any)._defaultContextNavigationTimeout = navigationTimeout || 0; + + for (const browserType of playwright._browserTypes()) { + browserType._defaultContextOptions = _combinedContextOptions; + browserType._defaultContextTimeout = actionTimeout || 0; + browserType._defaultContextNavigationTimeout = navigationTimeout || 0; } - (playwright.request as any)._defaultContextOptions = { ..._combinedContextOptions }; - (playwright.request as any)._defaultContextOptions.tracesDir = tracing().tracesDir(); - (playwright.request as any)._defaultContextOptions.timeout = actionTimeout || 0; + playwright.request._defaultContextOptions = { ..._combinedContextOptions }; + playwright.request._defaultContextOptions.tracesDir = tracing().tracesDir(); + playwright.request._defaultContextOptions.timeout = actionTimeout || 0; await use(); - (playwright.request as any)._defaultContextOptions = undefined; - for (const browserType of [playwright.chromium, playwright.firefox, playwright.webkit]) { - (browserType as any)._defaultContextOptions = undefined; - (browserType as any)._defaultContextTimeout = undefined; - (browserType as any)._defaultContextNavigationTimeout = undefined; + playwright.request._defaultContextOptions = undefined; + for (const browserType of playwright._browserTypes()) { + browserType._defaultContextOptions = undefined; + browserType._defaultContextTimeout = undefined; + browserType._defaultContextNavigationTimeout = undefined; } }, { auto: 'all-hooks-included', title: 'context configuration', box: true } as any], @@ -451,7 +454,6 @@ const playwrightFixtures: Fixtures = ({ }); type ScreenshotOption = PlaywrightWorkerOptions['screenshot'] | undefined; -type Playwright = PlaywrightWorkerArgs['playwright']; function normalizeVideoMode(video: VideoMode | 'retry-with-video' | { mode: VideoMode } | undefined): VideoMode { if (!video) @@ -525,7 +527,7 @@ function connectOptionsFromEnv() { class ArtifactsRecorder { private _testInfo!: TestInfoImpl; - private _playwright: Playwright; + private _playwright: PlaywrightImpl; private _artifactsDir: string; private _screenshotMode: ScreenshotMode; private _screenshotOptions: { mode: ScreenshotMode } & Pick | undefined; @@ -536,7 +538,7 @@ class ArtifactsRecorder { private _screenshottedSymbol: symbol; private _startedCollectingArtifacts: symbol; - constructor(playwright: Playwright, artifactsDir: string, screenshot: ScreenshotOption) { + constructor(playwright: PlaywrightImpl, artifactsDir: string, screenshot: ScreenshotOption) { this._playwright = playwright; this._artifactsDir = artifactsDir; this._screenshotMode = normalizeScreenshotMode(screenshot); @@ -678,11 +680,7 @@ class ArtifactsRecorder { } private async _screenshotOnTestFailure() { - const contexts: BrowserContext[] = []; - for (const browserType of [this._playwright.chromium, this._playwright.firefox, this._playwright.webkit]) - contexts.push(...(browserType as any)._contexts); - const pages = contexts.map(ctx => ctx.pages()).flat(); - await Promise.all(pages.map(page => this._screenshotPage(page, false))); + await Promise.all(this._playwright._allPages().map(page => this._screenshotPage(page, false))); } private async _startTraceChunkOnContextCreation(tracing: Tracing) {