diff --git a/packages/playwright-core/src/client/browserContext.ts b/packages/playwright-core/src/client/browserContext.ts index 6ceade1fc6..f21347f45b 100644 --- a/packages/playwright-core/src/client/browserContext.ts +++ b/packages/playwright-core/src/client/browserContext.ts @@ -242,11 +242,20 @@ export class BrowserContext extends ChannelOwner await this._channel.addInitScript({ source }); } + async _removeInitScripts() { + await this._channel.removeInitScripts(); + } + async exposeBinding(name: string, callback: (source: structs.BindingSource, ...args: any[]) => any, options: { handle?: boolean } = {}): Promise { await this._channel.exposeBinding({ name, needsHandle: options.handle }); this._bindings.set(name, callback); } + async _removeExposedBindings() { + this._bindings.clear(); + await this._channel.removeExposedBindings(); + } + async exposeFunction(name: string, callback: Function): Promise { await this._channel.exposeBinding({ name }); const binding = (source: structs.BindingSource, ...args: any[]) => callback(...args); @@ -265,6 +274,11 @@ export class BrowserContext extends ChannelOwner await this._disableInterception(); } + async _unrouteAll() { + this._routes = []; + await this._disableInterception(); + } + private async _disableInterception() { await this._channel.setNetworkInterceptionEnabled({ enabled: false }); } @@ -346,6 +360,12 @@ export class BrowserContext extends ChannelOwner }) { await this._channel.recorderSupplementEnable(params); } + + async _resetForReuse() { + await this._unrouteAll(); + await this._removeInitScripts(); + await this._removeExposedBindings(); + } } async function prepareStorageState(options: BrowserContextOptions): Promise { diff --git a/packages/playwright-core/src/client/page.ts b/packages/playwright-core/src/client/page.ts index 84ebf8b6af..4634dd6134 100644 --- a/packages/playwright-core/src/client/page.ts +++ b/packages/playwright-core/src/client/page.ts @@ -329,6 +329,11 @@ export class Page extends ChannelOwner implements api.Page this._bindings.set(name, callback); } + async _removeExposedBindings() { + this._bindings.clear(); + await this._channel.removeExposedBindings(); + } + async setExtraHTTPHeaders(headers: Headers) { validateHeaders(headers); await this._channel.setExtraHTTPHeaders({ headers: headersObjectToArray(headers) }); @@ -449,6 +454,10 @@ export class Page extends ChannelOwner implements api.Page await this._channel.addInitScript({ source }); } + async _removeInitScripts() { + await this._channel.removeInitScripts(); + } + async route(url: URLMatch, handler: RouteHandlerCallback, options: { times?: number } = {}): Promise { this._routes.unshift(new RouteHandler(this._browserContext._options.baseURL, url, handler, options.times)); if (this._routes.length === 1) @@ -461,6 +470,11 @@ export class Page extends ChannelOwner implements api.Page await this._disableInterception(); } + async _unrouteAll() { + this._routes = []; + await this._disableInterception(); + } + private async _disableInterception() { await this._channel.setNetworkInterceptionEnabled({ enabled: false }); } @@ -715,6 +729,12 @@ export class Page extends ChannelOwner implements api.Page } return buffer; } + + async _resetForReuse() { + await this._unrouteAll(); + await this._removeInitScripts(); + await this._removeExposedBindings(); + } } export class BindingCall extends ChannelOwner { diff --git a/packages/playwright-core/src/dispatchers/browserContextDispatcher.ts b/packages/playwright-core/src/dispatchers/browserContextDispatcher.ts index 0a33e146e6..b8197f925e 100644 --- a/packages/playwright-core/src/dispatchers/browserContextDispatcher.ts +++ b/packages/playwright-core/src/dispatchers/browserContextDispatcher.ts @@ -125,6 +125,10 @@ export class BrowserContextDispatcher extends Dispatcher { return { page: lookupDispatcher(await this._context.newPage(metadata)) }; } @@ -169,6 +173,10 @@ export class BrowserContextDispatcher extends Dispatcher { + await this._context.removeInitScripts(); + } + async setNetworkInterceptionEnabled(params: channels.BrowserContextSetNetworkInterceptionEnabledParams): Promise { if (!params.enabled) { await this._context.setRequestInterceptor(undefined); diff --git a/packages/playwright-core/src/dispatchers/pageDispatcher.ts b/packages/playwright-core/src/dispatchers/pageDispatcher.ts index 0676894f2c..f02d86bc2c 100644 --- a/packages/playwright-core/src/dispatchers/pageDispatcher.ts +++ b/packages/playwright-core/src/dispatchers/pageDispatcher.ts @@ -107,6 +107,10 @@ export class PageDispatcher extends Dispatcher imple }); } + async removeExposedBindings() { + await this._page.removeExposedBindings(); + } + async setExtraHTTPHeaders(params: channels.PageSetExtraHTTPHeadersParams, metadata: CallMetadata): Promise { await this._page.setExtraHTTPHeaders(params.headers); } @@ -140,6 +144,10 @@ export class PageDispatcher extends Dispatcher imple await this._page.addInitScript(params.source); } + async removeInitScripts(): Promise { + await this._page.removeInitScripts(); + } + async setNetworkInterceptionEnabled(params: channels.PageSetNetworkInterceptionEnabledParams, metadata: CallMetadata): Promise { if (!params.enabled) { await this._page.setClientRequestInterceptor(undefined); diff --git a/packages/playwright-core/src/protocol/channels.ts b/packages/playwright-core/src/protocol/channels.ts index 79041077ce..546d645ba4 100644 --- a/packages/playwright-core/src/protocol/channels.ts +++ b/packages/playwright-core/src/protocol/channels.ts @@ -1056,11 +1056,13 @@ export interface BrowserContextChannel extends BrowserContextEventTarget, EventT _type_BrowserContext: boolean; addCookies(params: BrowserContextAddCookiesParams, metadata?: Metadata): Promise; addInitScript(params: BrowserContextAddInitScriptParams, metadata?: Metadata): Promise; + removeInitScripts(params?: BrowserContextRemoveInitScriptsParams, metadata?: Metadata): Promise; clearCookies(params?: BrowserContextClearCookiesParams, metadata?: Metadata): Promise; clearPermissions(params?: BrowserContextClearPermissionsParams, metadata?: Metadata): Promise; close(params?: BrowserContextCloseParams, metadata?: Metadata): Promise; cookies(params: BrowserContextCookiesParams, metadata?: Metadata): Promise; exposeBinding(params: BrowserContextExposeBindingParams, metadata?: Metadata): Promise; + removeExposedBindings(params?: BrowserContextRemoveExposedBindingsParams, metadata?: Metadata): Promise; grantPermissions(params: BrowserContextGrantPermissionsParams, metadata?: Metadata): Promise; newPage(params?: BrowserContextNewPageParams, metadata?: Metadata): Promise; setDefaultNavigationTimeoutNoReply(params: BrowserContextSetDefaultNavigationTimeoutNoReplyParams, metadata?: Metadata): Promise; @@ -1131,6 +1133,9 @@ export type BrowserContextAddInitScriptOptions = { }; export type BrowserContextAddInitScriptResult = void; +export type BrowserContextRemoveInitScriptsParams = {}; +export type BrowserContextRemoveInitScriptsOptions = {}; +export type BrowserContextRemoveInitScriptsResult = void; export type BrowserContextClearCookiesParams = {}; export type BrowserContextClearCookiesOptions = {}; export type BrowserContextClearCookiesResult = void; @@ -1157,6 +1162,9 @@ export type BrowserContextExposeBindingOptions = { needsHandle?: boolean, }; export type BrowserContextExposeBindingResult = void; +export type BrowserContextRemoveExposedBindingsParams = {}; +export type BrowserContextRemoveExposedBindingsOptions = {}; +export type BrowserContextRemoveExposedBindingsResult = void; export type BrowserContextGrantPermissionsParams = { permissions: string[], origin?: string, @@ -1337,9 +1345,11 @@ export interface PageChannel extends PageEventTarget, EventTargetChannel { setDefaultTimeoutNoReply(params: PageSetDefaultTimeoutNoReplyParams, metadata?: Metadata): Promise; setFileChooserInterceptedNoReply(params: PageSetFileChooserInterceptedNoReplyParams, metadata?: Metadata): Promise; addInitScript(params: PageAddInitScriptParams, metadata?: Metadata): Promise; + removeInitScripts(params?: PageRemoveInitScriptsParams, metadata?: Metadata): Promise; close(params: PageCloseParams, metadata?: Metadata): Promise; emulateMedia(params: PageEmulateMediaParams, metadata?: Metadata): Promise; exposeBinding(params: PageExposeBindingParams, metadata?: Metadata): Promise; + removeExposedBindings(params?: PageRemoveExposedBindingsParams, metadata?: Metadata): Promise; goBack(params: PageGoBackParams, metadata?: Metadata): Promise; goForward(params: PageGoForwardParams, metadata?: Metadata): Promise; reload(params: PageReloadParams, metadata?: Metadata): Promise; @@ -1439,6 +1449,9 @@ export type PageAddInitScriptOptions = { }; export type PageAddInitScriptResult = void; +export type PageRemoveInitScriptsParams = {}; +export type PageRemoveInitScriptsOptions = {}; +export type PageRemoveInitScriptsResult = void; export type PageCloseParams = { runBeforeUnload?: boolean, }; @@ -1467,6 +1480,9 @@ export type PageExposeBindingOptions = { needsHandle?: boolean, }; export type PageExposeBindingResult = void; +export type PageRemoveExposedBindingsParams = {}; +export type PageRemoveExposedBindingsOptions = {}; +export type PageRemoveExposedBindingsResult = void; export type PageGoBackParams = { timeout?: number, waitUntil?: LifecycleEvent, diff --git a/packages/playwright-core/src/protocol/protocol.yml b/packages/playwright-core/src/protocol/protocol.yml index d8fa47fece..8991944678 100644 --- a/packages/playwright-core/src/protocol/protocol.yml +++ b/packages/playwright-core/src/protocol/protocol.yml @@ -761,6 +761,8 @@ BrowserContext: parameters: source: string + removeInitScripts: + clearCookies: clearPermissions: @@ -782,6 +784,8 @@ BrowserContext: name: string needsHandle: boolean? + removeExposedBindings: + grantPermissions: parameters: permissions: @@ -873,7 +877,6 @@ BrowserContext: returns: writableStream: WritableStream - events: bindingCall: @@ -960,6 +963,8 @@ Page: parameters: source: string + removeInitScripts: + close: parameters: runBeforeUnload: boolean? @@ -1001,6 +1006,8 @@ Page: name: string needsHandle: boolean? + removeExposedBindings: + goBack: parameters: timeout: number? diff --git a/packages/playwright-core/src/protocol/validator.ts b/packages/playwright-core/src/protocol/validator.ts index 15c6e8755b..850a348a1c 100644 --- a/packages/playwright-core/src/protocol/validator.ts +++ b/packages/playwright-core/src/protocol/validator.ts @@ -444,6 +444,7 @@ export function createScheme(tChannel: (name: string) => Validator): Scheme { scheme.BrowserContextAddInitScriptParams = tObject({ source: tString, }); + scheme.BrowserContextRemoveInitScriptsParams = tOptional(tObject({})); scheme.BrowserContextClearCookiesParams = tOptional(tObject({})); scheme.BrowserContextClearPermissionsParams = tOptional(tObject({})); scheme.BrowserContextCloseParams = tOptional(tObject({})); @@ -454,6 +455,7 @@ export function createScheme(tChannel: (name: string) => Validator): Scheme { name: tString, needsHandle: tOptional(tBoolean), }); + scheme.BrowserContextRemoveExposedBindingsParams = tOptional(tObject({})); scheme.BrowserContextGrantPermissionsParams = tObject({ permissions: tArray(tString), origin: tOptional(tString), @@ -519,6 +521,7 @@ export function createScheme(tChannel: (name: string) => Validator): Scheme { scheme.PageAddInitScriptParams = tObject({ source: tString, }); + scheme.PageRemoveInitScriptsParams = tOptional(tObject({})); scheme.PageCloseParams = tObject({ runBeforeUnload: tOptional(tBoolean), }); @@ -532,6 +535,7 @@ export function createScheme(tChannel: (name: string) => Validator): Scheme { name: tString, needsHandle: tOptional(tBoolean), }); + scheme.PageRemoveExposedBindingsParams = tOptional(tObject({})); scheme.PageGoBackParams = tObject({ timeout: tOptional(tNumber), waitUntil: tOptional(tType('LifecycleEvent')), diff --git a/packages/playwright-core/src/server/browserContext.ts b/packages/playwright-core/src/server/browserContext.ts index 180b0632a8..45a6d1a4db 100644 --- a/packages/playwright-core/src/server/browserContext.ts +++ b/packages/playwright-core/src/server/browserContext.ts @@ -163,7 +163,9 @@ export abstract class BrowserContext extends SdkObject { protected abstract doClearPermissions(): Promise; protected abstract doSetHTTPCredentials(httpCredentials?: types.Credentials): Promise; protected abstract doAddInitScript(expression: string): Promise; + protected abstract doRemoveInitScripts(): Promise; protected abstract doExposeBinding(binding: PageBinding): Promise; + protected abstract doRemoveExposedBindings(): Promise; protected abstract doUpdateRequestInterception(): Promise; protected abstract doClose(): Promise; protected abstract onClosePersistent(): void; @@ -190,6 +192,11 @@ export abstract class BrowserContext extends SdkObject { await this.doExposeBinding(binding); } + async removeExposedBindings() { + this._pageBindings.clear(); + await this.doRemoveExposedBindings(); + } + async grantPermissions(permissions: string[], origin?: string) { let resolvedOrigin = '*'; if (origin) { @@ -270,6 +277,11 @@ export abstract class BrowserContext extends SdkObject { await this.doAddInitScript(script); } + async removeInitScripts(): Promise { + this.initScripts.splice(0, this.initScripts.length); + await this.doRemoveInitScripts(); + } + async setRequestInterceptor(handler: network.RouteHandler | undefined): Promise { this._requestInterceptor = handler; await this.doUpdateRequestInterception(); diff --git a/packages/playwright-core/src/server/chromium/crBrowser.ts b/packages/playwright-core/src/server/chromium/crBrowser.ts index 175412c35f..dcb42f9aa1 100644 --- a/packages/playwright-core/src/server/chromium/crBrowser.ts +++ b/packages/playwright-core/src/server/chromium/crBrowser.ts @@ -464,11 +464,21 @@ export class CRBrowserContext extends BrowserContext { await (page._delegate as CRPage).addInitScript(source); } + async doRemoveInitScripts() { + for (const page of this.pages()) + await (page._delegate as CRPage).removeInitScripts(); + } + async doExposeBinding(binding: PageBinding) { for (const page of this.pages()) await (page._delegate as CRPage).exposeBinding(binding); } + async doRemoveExposedBindings() { + for (const page of this.pages()) + await (page._delegate as CRPage).removeExposedBindings(); + } + async doUpdateRequestInterception(): Promise { for (const page of this.pages()) await (page._delegate as CRPage).updateRequestInterception(); diff --git a/packages/playwright-core/src/server/chromium/crPage.ts b/packages/playwright-core/src/server/chromium/crPage.ts index 952db56960..f9c2ec8aa4 100644 --- a/packages/playwright-core/src/server/chromium/crPage.ts +++ b/packages/playwright-core/src/server/chromium/crPage.ts @@ -179,6 +179,10 @@ export class CRPage implements PageDelegate { await Promise.all(this._page.frames().map(frame => frame.evaluateExpression(binding.source, false, {}).catch(e => {}))); } + async removeExposedBindings() { + await this._forAllFrameSessions(frame => frame._removeExposedBindings()); + } + async updateExtraHTTPHeaders(): Promise { await this._forAllFrameSessions(frame => frame._updateExtraHTTPHeaders(false)); } @@ -241,6 +245,10 @@ export class CRPage implements PageDelegate { await this._forAllFrameSessions(frame => frame._evaluateOnNewDocument(source, world)); } + async removeInitScripts() { + await this._forAllFrameSessions(frame => frame._removeEvaluatesOnNewDocument()); + } + async closePage(runBeforeUnload: boolean): Promise { if (runBeforeUnload) await this._mainFrameSession._client.send('Page.close'); @@ -388,6 +396,8 @@ class FrameSession { private _videoRecorder: VideoRecorder | null = null; private _screencastId: string | null = null; private _screencastClients = new Set(); + private _evaluateOnNewDocumentIdentifiers: string[] = []; + private _exposedBindingNames: string[] = []; constructor(crPage: CRPage, client: CRSession, targetId: string, parentSession: FrameSession | null) { this._client = client; @@ -798,10 +808,18 @@ class FrameSession { } async _initBinding(binding: PageBinding) { - await Promise.all([ + const [ , response ] = await Promise.all([ this._client.send('Runtime.addBinding', { name: binding.name }), this._client.send('Page.addScriptToEvaluateOnNewDocument', { source: binding.source }) ]); + this._exposedBindingNames.push(binding.name); + this._evaluateOnNewDocumentIdentifiers.push(response.identifier); + } + + async _removeExposedBindings() { + const names = this._exposedBindingNames; + this._exposedBindingNames = []; + await Promise.all(names.map(name => this._client.send('Runtime.removeBinding', { name }))); } async _onBindingCalled(event: Protocol.Runtime.bindingCalledPayload) { @@ -1054,7 +1072,14 @@ class FrameSession { async _evaluateOnNewDocument(source: string, world: types.World): Promise { const worldName = world === 'utility' ? UTILITY_WORLD_NAME : undefined; - await this._client.send('Page.addScriptToEvaluateOnNewDocument', { source, worldName }); + const { identifier } = await this._client.send('Page.addScriptToEvaluateOnNewDocument', { source, worldName }); + this._evaluateOnNewDocumentIdentifiers.push(identifier); + } + + async _removeEvaluatesOnNewDocument(): Promise { + const identifiers = this._evaluateOnNewDocumentIdentifiers; + this._evaluateOnNewDocumentIdentifiers = []; + await Promise.all(identifiers.map(identifier => this._client.send('Page.removeScriptToEvaluateOnNewDocument', { identifier }))); } async _getContentFrame(handle: dom.ElementHandle): Promise { diff --git a/packages/playwright-core/src/server/firefox/ffBrowser.ts b/packages/playwright-core/src/server/firefox/ffBrowser.ts index 570bb71753..f0c79fc45c 100644 --- a/packages/playwright-core/src/server/firefox/ffBrowser.ts +++ b/packages/playwright-core/src/server/firefox/ffBrowser.ts @@ -324,10 +324,18 @@ export class FFBrowserContext extends BrowserContext { await this._browser._connection.send('Browser.setInitScripts', { browserContextId: this._browserContextId, scripts: this.initScripts.map(script => ({ script })) }); } + async doRemoveInitScripts() { + await this._browser._connection.send('Browser.setInitScripts', { browserContextId: this._browserContextId, scripts: [] }); + } + async doExposeBinding(binding: PageBinding) { await this._browser._connection.send('Browser.addBinding', { browserContextId: this._browserContextId, name: binding.name, script: binding.source }); } + async doRemoveExposedBindings() { + // TODO: implement me. + } + async doUpdateRequestInterception(): Promise { await this._browser._connection.send('Browser.setRequestInterception', { browserContextId: this._browserContextId, enabled: !!this._requestInterceptor }); } diff --git a/packages/playwright-core/src/server/firefox/ffPage.ts b/packages/playwright-core/src/server/firefox/ffPage.ts index 569f49b566..d87d73360b 100644 --- a/packages/playwright-core/src/server/firefox/ffPage.ts +++ b/packages/playwright-core/src/server/firefox/ffPage.ts @@ -333,6 +333,10 @@ export class FFPage implements PageDelegate { await this._session.send('Page.addBinding', { name: binding.name, script: binding.source }); } + async removeExposedBindings() { + // TODO: implement me. + } + didClose() { this._session.dispose(); eventsHelper.removeEventListeners(this._eventListeners); @@ -403,6 +407,11 @@ export class FFPage implements PageDelegate { await this._session.send('Page.setInitScripts', { scripts: this._initScripts }); } + async removeInitScripts() { + this._initScripts = []; + await this._session.send('Page.setInitScripts', { scripts: [] }); + } + async closePage(runBeforeUnload: boolean): Promise { await this._session.send('Page.close', { runBeforeUnload }); } diff --git a/packages/playwright-core/src/server/page.ts b/packages/playwright-core/src/server/page.ts index 107bab226e..7a6bd7f844 100644 --- a/packages/playwright-core/src/server/page.ts +++ b/packages/playwright-core/src/server/page.ts @@ -47,7 +47,9 @@ export interface PageDelegate { goBack(): Promise; goForward(): Promise; exposeBinding(binding: PageBinding): Promise; + removeExposedBindings(): Promise; addInitScript(source: string): Promise; + removeInitScripts(): Promise; closePage(runBeforeUnload: boolean): Promise; potentiallyUninitializedPage(): Page; pageOrError(): Promise; @@ -308,6 +310,11 @@ export class Page extends SdkObject { await this._delegate.exposeBinding(binding); } + async removeExposedBindings() { + this._pageBindings.clear(); + await this._delegate.removeExposedBindings(); + } + setExtraHTTPHeaders(headers: types.HeadersArray) { this._state.extraHTTPHeaders = headers; return this._delegate.updateExtraHTTPHeaders(); @@ -416,6 +423,11 @@ export class Page extends SdkObject { await this._delegate.addInitScript(source); } + async removeInitScripts() { + this.initScripts.splice(0, this.initScripts.length); + await this._delegate.removeInitScripts(); + } + _needsRequestInterception(): boolean { return !!this._clientRequestInterceptor || !!this._serverRequestInterceptor || !!this._browserContext._requestInterceptor; } diff --git a/packages/playwright-core/src/server/webkit/wkBrowser.ts b/packages/playwright-core/src/server/webkit/wkBrowser.ts index c0126be5c0..ec3a083917 100644 --- a/packages/playwright-core/src/server/webkit/wkBrowser.ts +++ b/packages/playwright-core/src/server/webkit/wkBrowser.ts @@ -307,11 +307,21 @@ export class WKBrowserContext extends BrowserContext { await (page._delegate as WKPage)._updateBootstrapScript(); } + async doRemoveInitScripts() { + for (const page of this.pages()) + await (page._delegate as WKPage)._updateBootstrapScript(); + } + async doExposeBinding(binding: PageBinding) { for (const page of this.pages()) await (page._delegate as WKPage).exposeBinding(binding); } + async doRemoveExposedBindings() { + for (const page of this.pages()) + await (page._delegate as WKPage).removeExposedBindings(); + } + async doUpdateRequestInterception(): Promise { for (const page of this.pages()) await (page._delegate as WKPage).updateRequestInterception(); diff --git a/packages/playwright-core/src/server/webkit/wkPage.ts b/packages/playwright-core/src/server/webkit/wkPage.ts index 4fd0bf55a6..2fe09e0d6b 100644 --- a/packages/playwright-core/src/server/webkit/wkPage.ts +++ b/packages/playwright-core/src/server/webkit/wkPage.ts @@ -753,6 +753,10 @@ export class WKPage implements PageDelegate { await this._evaluateBindingScript(binding); } + async removeExposedBindings(): Promise { + await this._updateBootstrapScript(); + } + private async _evaluateBindingScript(binding: PageBinding): Promise { const script = this._bindingToScript(binding); await Promise.all(this._page.frames().map(frame => frame.evaluateExpression(script, false, {}).catch(e => {}))); @@ -762,6 +766,10 @@ export class WKPage implements PageDelegate { await this._updateBootstrapScript(); } + async removeInitScripts() { + await this._updateBootstrapScript(); + } + private _bindingToScript(binding: PageBinding): string { return `self.${binding.name} = (param) => console.debug('${BINDING_CALL_MESSAGE}', {}, param); ${binding.source}`; } diff --git a/packages/playwright-ct-react/test.js b/packages/playwright-ct-react/test.js index 6b0647b1db..101182cfb5 100644 --- a/packages/playwright-ct-react/test.js +++ b/packages/playwright-ct-react/test.js @@ -29,14 +29,12 @@ const test = baseTest.extend({ }, page: async ({ _workerPage }, use) => { - await _workerPage.goto('about:blank'); await use(_workerPage); }, - mount: async ({ page, baseURL }, use) => { + mount: async ({ page, baseURL, viewport }, use) => { await use(async (component, options) => { - await page.goto(baseURL); - const selector = await mount(page, component, options); + const selector = await mount(page, component, options, baseURL, viewport); return page.locator(selector); }); }, diff --git a/packages/playwright-ct-svelte/test.js b/packages/playwright-ct-svelte/test.js index 6b0647b1db..101182cfb5 100644 --- a/packages/playwright-ct-svelte/test.js +++ b/packages/playwright-ct-svelte/test.js @@ -29,14 +29,12 @@ const test = baseTest.extend({ }, page: async ({ _workerPage }, use) => { - await _workerPage.goto('about:blank'); await use(_workerPage); }, - mount: async ({ page, baseURL }, use) => { + mount: async ({ page, baseURL, viewport }, use) => { await use(async (component, options) => { - await page.goto(baseURL); - const selector = await mount(page, component, options); + const selector = await mount(page, component, options, baseURL, viewport); return page.locator(selector); }); }, diff --git a/packages/playwright-ct-vue/test.js b/packages/playwright-ct-vue/test.js index 6b0647b1db..101182cfb5 100644 --- a/packages/playwright-ct-vue/test.js +++ b/packages/playwright-ct-vue/test.js @@ -29,14 +29,12 @@ const test = baseTest.extend({ }, page: async ({ _workerPage }, use) => { - await _workerPage.goto('about:blank'); await use(_workerPage); }, - mount: async ({ page, baseURL }, use) => { + mount: async ({ page, baseURL, viewport }, use) => { await use(async (component, options) => { - await page.goto(baseURL); - const selector = await mount(page, component, options); + const selector = await mount(page, component, options, baseURL, viewport); return page.locator(selector); }); }, diff --git a/packages/playwright-test/src/mount.ts b/packages/playwright-test/src/mount.ts index 62664d893f..6ef3ffa9b3 100644 --- a/packages/playwright-test/src/mount.ts +++ b/packages/playwright-test/src/mount.ts @@ -14,10 +14,16 @@ * limitations under the License. */ -import type { Page } from '@playwright/test'; +import type { Page, ViewportSize } from '@playwright/test'; import { createGuid } from 'playwright-core/lib/utils/utils'; -export async function mount(page: Page, jsxOrType: any, options: any): Promise { +export async function mount(page: Page, jsxOrType: any, options: any, baseURL: string, viewport: ViewportSize): Promise { + await page.goto('about:blank'); + await (page as any)._resetForReuse(); + await (page.context() as any)._resetForReuse(); + await page.setViewportSize(viewport); + await page.goto(baseURL); + let component; if (typeof jsxOrType === 'string') component = { kind: 'object', type: jsxOrType, options };