mirror of
https://github.com/microsoft/playwright.git
synced 2025-01-05 19:04:43 +03:00
chore: reuse context in the innerloop mode (#15719)
This commit is contained in:
parent
a198b6d753
commit
55cd3928b7
@ -40,7 +40,8 @@
|
||||
"test-types": "node utils/generate_types/ && npx -p typescript@3.7.5 tsc -p utils/generate_types/test/tsconfig.json && tsc -p ./tests/",
|
||||
"roll": "node utils/roll_browser.js",
|
||||
"check-deps": "node utils/check_deps.js",
|
||||
"build-android-driver": "./utils/build_android_driver.sh"
|
||||
"build-android-driver": "./utils/build_android_driver.sh",
|
||||
"innerloop": "playwright launch-server --browser=chromium --config=utils/innerloop-server.config.json"
|
||||
},
|
||||
"workspaces": [
|
||||
"packages/*"
|
||||
|
@ -69,6 +69,7 @@ export abstract class Browser extends SdkObject {
|
||||
_defaultContext: BrowserContext | null = null;
|
||||
private _startedClosing = false;
|
||||
readonly _idToVideo = new Map<string, { context: BrowserContext, artifact: Artifact }>();
|
||||
private _contextForReuse: { context: BrowserContext, hash: string } | undefined;
|
||||
|
||||
constructor(options: BrowserOptions) {
|
||||
super(options.rootSdkObject, 'browser');
|
||||
@ -90,6 +91,17 @@ export abstract class Browser extends SdkObject {
|
||||
return context;
|
||||
}
|
||||
|
||||
async newContextForReuse(params: channels.BrowserNewContextForReuseParams, metadata: CallMetadata): Promise<{ context: BrowserContext, needsReset: boolean }> {
|
||||
const hash = BrowserContext.reusableContextHash(params);
|
||||
if (!this._contextForReuse || hash !== this._contextForReuse.hash || !this._contextForReuse.context.canResetForReuse()) {
|
||||
if (this._contextForReuse)
|
||||
await this._contextForReuse.context.close(metadata);
|
||||
this._contextForReuse = { context: await this.newContext(metadata, params), hash };
|
||||
return { context: this._contextForReuse.context, needsReset: false };
|
||||
}
|
||||
return { context: this._contextForReuse.context, needsReset: true };
|
||||
}
|
||||
|
||||
_downloadCreated(page: Page, uuid: string, url: string, suggestedFilename?: string) {
|
||||
const download = new Download(page, this.options.downloadsPath || '', uuid, url, suggestedFilename);
|
||||
this._downloads.set(uuid, download);
|
||||
|
@ -30,7 +30,6 @@ import { Selectors } from '../selectors';
|
||||
|
||||
export class BrowserDispatcher extends Dispatcher<Browser, channels.BrowserChannel> implements channels.BrowserChannel {
|
||||
_type_Browser = true;
|
||||
private _contextForReuse: { context: BrowserContext, hash: string } | undefined;
|
||||
|
||||
constructor(scope: DispatcherScope, browser: Browser) {
|
||||
super(scope, browser, 'Browser', { version: browser.version(), name: browser.options.name }, true);
|
||||
@ -47,22 +46,8 @@ export class BrowserDispatcher extends Dispatcher<Browser, channels.BrowserChann
|
||||
return { context: new BrowserContextDispatcher(this._scope, context) };
|
||||
}
|
||||
|
||||
/**
|
||||
* Used for inner loop scenarios where user would like to preserve the browser window, opened page and devtools instance.
|
||||
*/
|
||||
async newContextForReuse(params: channels.BrowserNewContextForReuseParams, metadata: CallMetadata): Promise<channels.BrowserNewContextForReuseResult> {
|
||||
const hash = BrowserContext.reusableContextHash(params);
|
||||
if (!this._contextForReuse || hash !== this._contextForReuse.hash || !this._contextForReuse.context.canResetForReuse()) {
|
||||
if (this._contextForReuse)
|
||||
await this._contextForReuse.context.close(metadata);
|
||||
this._contextForReuse = { context: await this._object.newContext(metadata, params), hash };
|
||||
} else {
|
||||
const oldContextDispatcher = existingDispatcher<BrowserContextDispatcher>(this._contextForReuse.context);
|
||||
oldContextDispatcher._dispose();
|
||||
await this._contextForReuse.context.resetForReuse(metadata, params);
|
||||
}
|
||||
const context = new BrowserContextDispatcher(this._scope, this._contextForReuse.context);
|
||||
return { context };
|
||||
return newContextForReuse(this._object, this._scope, params, metadata);
|
||||
}
|
||||
|
||||
async close(): Promise<void> {
|
||||
@ -118,8 +103,8 @@ export class ConnectedBrowserDispatcher extends Dispatcher<Browser, channels.Bro
|
||||
return { context: new BrowserContextDispatcher(this._scope, context) };
|
||||
}
|
||||
|
||||
newContextForReuse(params: channels.BrowserNewContextForReuseParams, metadata?: channels.Metadata | undefined): Promise<channels.BrowserNewContextForReuseResult> {
|
||||
throw new Error('Method not implemented.');
|
||||
async newContextForReuse(params: channels.BrowserNewContextForReuseParams, metadata: CallMetadata): Promise<channels.BrowserNewContextForReuseResult> {
|
||||
return newContextForReuse(this._object, this._scope, params, metadata);
|
||||
}
|
||||
|
||||
async close(): Promise<void> {
|
||||
@ -155,3 +140,14 @@ export class ConnectedBrowserDispatcher extends Dispatcher<Browser, channels.Bro
|
||||
await Promise.all(Array.from(this._contexts).map(context => context.close(serverSideCallMetadata())));
|
||||
}
|
||||
}
|
||||
|
||||
async function newContextForReuse(browser: Browser, scope: DispatcherScope, params: channels.BrowserNewContextForReuseParams, metadata: CallMetadata): Promise<channels.BrowserNewContextForReuseResult> {
|
||||
const { context, needsReset } = await browser.newContextForReuse(params, metadata);
|
||||
if (needsReset) {
|
||||
const oldContextDispatcher = existingDispatcher<BrowserContextDispatcher>(context);
|
||||
oldContextDispatcher._dispose();
|
||||
await context.resetForReuse(metadata, params);
|
||||
}
|
||||
const contextDispatcher = new BrowserContextDispatcher(scope, context);
|
||||
return { context: contextDispatcher };
|
||||
}
|
||||
|
5
utils/innerloop-server.config.json
Normal file
5
utils/innerloop-server.config.json
Normal file
@ -0,0 +1,5 @@
|
||||
{
|
||||
"port": 3333,
|
||||
"wsPath": "/",
|
||||
"headless": false
|
||||
}
|
Loading…
Reference in New Issue
Block a user