chore: add reuse context to internal test suite (#9359)
This commit is contained in:
parent
3781faeaaa
commit
b10140d9c2
|
|
@ -35,7 +35,7 @@ type WorkerAndFileFixtures = PlaywrightWorkerArgs & PlaywrightWorkerOptions & {
|
||||||
_reuseBrowserContext: ReuseBrowserContextStorage,
|
_reuseBrowserContext: ReuseBrowserContextStorage,
|
||||||
};
|
};
|
||||||
|
|
||||||
class ReuseBrowserContextStorage {
|
export class ReuseBrowserContextStorage {
|
||||||
private _browserContext?: BrowserContext;
|
private _browserContext?: BrowserContext;
|
||||||
private _uniqueOrigins = new Set<string>();
|
private _uniqueOrigins = new Set<string>();
|
||||||
private _options?: BrowserContextOptions;
|
private _options?: BrowserContextOptions;
|
||||||
|
|
@ -54,18 +54,25 @@ class ReuseBrowserContextStorage {
|
||||||
private async _createNewContext(browser: Browser): Promise<BrowserContext> {
|
private async _createNewContext(browser: Browser): Promise<BrowserContext> {
|
||||||
this._browserContext = await browser.newContext();
|
this._browserContext = await browser.newContext();
|
||||||
this._options = (this._browserContext as any)._options;
|
this._options = (this._browserContext as any)._options;
|
||||||
this._browserContext.on('page', page => page.on('framenavigated', frame => {
|
this._browserContext.on('page', page => {
|
||||||
if (this._pauseNavigationEventCollection)
|
page.on('framenavigated', frame => {
|
||||||
return;
|
if (this._pauseNavigationEventCollection)
|
||||||
this._uniqueOrigins.add(new URL(frame.url()).origin);
|
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;
|
return this._browserContext;
|
||||||
}
|
}
|
||||||
|
|
||||||
async _refurbishExistingContext(newContextOptions: BrowserContextOptions): Promise<BrowserContext> {
|
async _refurbishExistingContext(newContextOptions: BrowserContextOptions): Promise<BrowserContext> {
|
||||||
assert(this._browserContext);
|
assert(this._browserContext);
|
||||||
const pages = this._browserContext.pages();
|
const page = this._browserContext.pages().length > 0 ? this._browserContext.pages()[0] : await this._browserContext.newPage();
|
||||||
const page = pages[0];
|
|
||||||
this._pauseNavigationEventCollection = true;
|
this._pauseNavigationEventCollection = true;
|
||||||
try {
|
try {
|
||||||
const initialOrigin = new URL(page.url()).origin;
|
const initialOrigin = new URL(page.url()).origin;
|
||||||
|
|
@ -78,8 +85,8 @@ class ReuseBrowserContextStorage {
|
||||||
await page.evaluate(() => window.sessionStorage.clear());
|
await page.evaluate(() => window.sessionStorage.clear());
|
||||||
}
|
}
|
||||||
await page.unroute('**/*');
|
await page.unroute('**/*');
|
||||||
await Promise.all(pages.slice(1).map(page => page.close()));
|
|
||||||
await page.goto('about:blank');
|
await page.goto('about:blank');
|
||||||
|
await Promise.all(this._browserContext.pages().slice(1).map(page => page.close()));
|
||||||
await this._browserContext.clearCookies();
|
await this._browserContext.clearCookies();
|
||||||
await this._applyNewContextOptions(page, newContextOptions);
|
await this._applyNewContextOptions(page, newContextOptions);
|
||||||
} finally {
|
} finally {
|
||||||
|
|
@ -90,14 +97,16 @@ class ReuseBrowserContextStorage {
|
||||||
|
|
||||||
private async _applyNewContextOptions(page: Page, newOptions: BrowserContextOptions) {
|
private async _applyNewContextOptions(page: Page, newOptions: BrowserContextOptions) {
|
||||||
assert(this._options);
|
assert(this._options);
|
||||||
|
const currentViewport = page.viewportSize();
|
||||||
|
const newViewport = newOptions.viewport === undefined ? { width: 1280, height: 720 } : newOptions.viewport;
|
||||||
if (
|
if (
|
||||||
(
|
(
|
||||||
this._options.viewport?.width !== newOptions.viewport?.width ||
|
currentViewport?.width !== newViewport?.width ||
|
||||||
this._options.viewport?.height !== newOptions.viewport?.height
|
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;
|
this._options = newOptions;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -17,6 +17,7 @@
|
||||||
import type { Fixtures } from './test-runner';
|
import type { Fixtures } from './test-runner';
|
||||||
import type { Browser, BrowserContext, BrowserContextOptions, BrowserType, LaunchOptions, Page } from '../../index';
|
import type { Browser, BrowserContext, BrowserContextOptions, BrowserType, LaunchOptions, Page } from '../../index';
|
||||||
import { removeFolders } from '../../lib/utils/utils';
|
import { removeFolders } from '../../lib/utils/utils';
|
||||||
|
import { ReuseBrowserContextStorage } from '../../lib/test/index';
|
||||||
import * as path from 'path';
|
import * as path from 'path';
|
||||||
import * as fs from 'fs';
|
import * as fs from 'fs';
|
||||||
import * as os from 'os';
|
import * as os from 'os';
|
||||||
|
|
@ -34,6 +35,7 @@ export type PlaywrightWorkerFixtures = {
|
||||||
browserOptions: LaunchOptions;
|
browserOptions: LaunchOptions;
|
||||||
browser: Browser;
|
browser: Browser;
|
||||||
browserVersion: string;
|
browserVersion: string;
|
||||||
|
_reuseBrowserContext: ReuseBrowserContextStorage,
|
||||||
};
|
};
|
||||||
type PlaywrightTestOptions = {
|
type PlaywrightTestOptions = {
|
||||||
hasTouch: BrowserContextOptions['hasTouch'];
|
hasTouch: BrowserContextOptions['hasTouch'];
|
||||||
|
|
@ -80,6 +82,8 @@ export const playwrightFixtures: Fixtures<PlaywrightTestOptions & PlaywrightTest
|
||||||
await run(browser.version());
|
await run(browser.version());
|
||||||
}, { scope: 'worker' } ],
|
}, { scope: 'worker' } ],
|
||||||
|
|
||||||
|
_reuseBrowserContext: [new ReuseBrowserContextStorage(), { scope: 'worker' }],
|
||||||
|
|
||||||
createUserDataDir: async ({}, run) => {
|
createUserDataDir: async ({}, run) => {
|
||||||
const dirs: string[] = [];
|
const dirs: string[] = [];
|
||||||
// We do not put user data dir in testOutputPath,
|
// 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());
|
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());
|
await run(await context.newPage());
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue