chore: add reuse context to internal test suite (#9359)

This commit is contained in:
Max Schmitt 2021-10-07 23:01:08 +02:00 committed by GitHub
parent 3781faeaaa
commit b10140d9c2
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 37 additions and 15 deletions

View file

@ -35,7 +35,7 @@ type WorkerAndFileFixtures = PlaywrightWorkerArgs & PlaywrightWorkerOptions & {
_reuseBrowserContext: ReuseBrowserContextStorage,
};
class ReuseBrowserContextStorage {
export class ReuseBrowserContextStorage {
private _browserContext?: BrowserContext;
private _uniqueOrigins = new Set<string>();
private _options?: BrowserContextOptions;
@ -54,18 +54,25 @@ class ReuseBrowserContextStorage {
private async _createNewContext(browser: Browser): Promise<BrowserContext> {
this._browserContext = await browser.newContext();
this._options = (this._browserContext as any)._options;
this._browserContext.on('page', page => page.on('framenavigated', frame => {
if (this._pauseNavigationEventCollection)
return;
this._uniqueOrigins.add(new URL(frame.url()).origin);
}));
this._browserContext.on('page', page => {
page.on('framenavigated', frame => {
if (this._pauseNavigationEventCollection)
return;
const origin = new URL(frame.url()).origin;
if (origin !== 'null') // 'chrome-error://chromewebdata/'
this._uniqueOrigins.add(origin);
});
page.on('crash', () => {
this._browserContext?.close().then(() => {});
this._browserContext = undefined;
});
});
return this._browserContext;
}
async _refurbishExistingContext(newContextOptions: BrowserContextOptions): Promise<BrowserContext> {
assert(this._browserContext);
const pages = this._browserContext.pages();
const page = pages[0];
const page = this._browserContext.pages().length > 0 ? this._browserContext.pages()[0] : await this._browserContext.newPage();
this._pauseNavigationEventCollection = true;
try {
const initialOrigin = new URL(page.url()).origin;
@ -78,8 +85,8 @@ class ReuseBrowserContextStorage {
await page.evaluate(() => window.sessionStorage.clear());
}
await page.unroute('**/*');
await Promise.all(pages.slice(1).map(page => page.close()));
await page.goto('about:blank');
await Promise.all(this._browserContext.pages().slice(1).map(page => page.close()));
await this._browserContext.clearCookies();
await this._applyNewContextOptions(page, newContextOptions);
} finally {
@ -90,14 +97,16 @@ class ReuseBrowserContextStorage {
private async _applyNewContextOptions(page: Page, newOptions: BrowserContextOptions) {
assert(this._options);
const currentViewport = page.viewportSize();
const newViewport = newOptions.viewport === undefined ? { width: 1280, height: 720 } : newOptions.viewport;
if (
(
this._options.viewport?.width !== newOptions.viewport?.width ||
this._options.viewport?.height !== newOptions.viewport?.height
currentViewport?.width !== newViewport?.width ||
currentViewport?.height !== newViewport?.height
) &&
(newOptions.viewport?.height && newOptions.viewport?.width)
(newViewport?.height && newViewport?.width)
)
await page.setViewportSize({ width: newOptions.viewport?.width, height: newOptions.viewport?.height });
await page.setViewportSize(newViewport);
this._options = newOptions;
}

View file

@ -17,6 +17,7 @@
import type { Fixtures } from './test-runner';
import type { Browser, BrowserContext, BrowserContextOptions, BrowserType, LaunchOptions, Page } from '../../index';
import { removeFolders } from '../../lib/utils/utils';
import { ReuseBrowserContextStorage } from '../../lib/test/index';
import * as path from 'path';
import * as fs from 'fs';
import * as os from 'os';
@ -34,6 +35,7 @@ export type PlaywrightWorkerFixtures = {
browserOptions: LaunchOptions;
browser: Browser;
browserVersion: string;
_reuseBrowserContext: ReuseBrowserContextStorage,
};
type PlaywrightTestOptions = {
hasTouch: BrowserContextOptions['hasTouch'];
@ -80,6 +82,8 @@ export const playwrightFixtures: Fixtures<PlaywrightTestOptions & PlaywrightTest
await run(browser.version());
}, { scope: 'worker' } ],
_reuseBrowserContext: [new ReuseBrowserContextStorage(), { scope: 'worker' }],
createUserDataDir: async ({}, run) => {
const dirs: string[] = [];
// We do not put user data dir in testOutputPath,
@ -180,11 +184,20 @@ export const playwrightFixtures: Fixtures<PlaywrightTestOptions & PlaywrightTest
}));
},
context: async ({ contextFactory }, run) => {
context: async ({ contextFactory, browser, _reuseBrowserContext, contextOptions }, run) => {
if (_reuseBrowserContext.isEnabled()) {
const context = await _reuseBrowserContext.obtainContext(browser, contextOptions);
await run(context);
return;
}
await run(await contextFactory());
},
page: async ({ context }, run) => {
page: async ({ context, _reuseBrowserContext }, run) => {
if (_reuseBrowserContext.isEnabled()) {
await run(await _reuseBrowserContext.obtainPage());
return;
}
await run(await context.newPage());
},
};