mirror of
https://github.com/microsoft/playwright.git
synced 2025-06-26 21:40:17 +00:00
chore: remove underscore from public members in page (#35820)
This commit is contained in:
parent
eda5a9efeb
commit
baeb065e9e
@ -16,7 +16,7 @@
|
||||
|
||||
import { eventsHelper } from '../utils/eventsHelper';
|
||||
import { Browser } from '../browser';
|
||||
import { BrowserContext, assertBrowserContextIsNotOwned, verifyGeolocation } from '../browserContext';
|
||||
import { BrowserContext, verifyGeolocation } from '../browserContext';
|
||||
import * as network from '../network';
|
||||
import { BidiConnection } from './bidiConnection';
|
||||
import { bidiBytesValueToString } from './bidiNetworkManager';
|
||||
@ -151,12 +151,12 @@ export class BidiBrowser extends Browser {
|
||||
if (event.parent) {
|
||||
const parentFrameId = event.parent;
|
||||
for (const page of this._bidiPages.values()) {
|
||||
const parentFrame = page._page._frameManager.frame(parentFrameId);
|
||||
const parentFrame = page._page.frameManager.frame(parentFrameId);
|
||||
if (!parentFrame)
|
||||
continue;
|
||||
page._session.addFrameBrowsingContext(event.context);
|
||||
page._page._frameManager.frameAttached(event.context, parentFrameId);
|
||||
const frame = page._page._frameManager.frame(event.context);
|
||||
page._page.frameManager.frameAttached(event.context, parentFrameId);
|
||||
const frame = page._page.frameManager.frame(event.context);
|
||||
if (frame)
|
||||
frame._url = event.url;
|
||||
return;
|
||||
@ -180,10 +180,10 @@ export class BidiBrowser extends Browser {
|
||||
this._browserSession.removeFrameBrowsingContext(event.context);
|
||||
const parentFrameId = event.parent;
|
||||
for (const page of this._bidiPages.values()) {
|
||||
const parentFrame = page._page._frameManager.frame(parentFrameId);
|
||||
const parentFrame = page._page.frameManager.frame(parentFrameId);
|
||||
if (!parentFrame)
|
||||
continue;
|
||||
page._page._frameManager.frameDetached(event.context);
|
||||
page._page.frameManager.frameDetached(event.context);
|
||||
return;
|
||||
}
|
||||
return;
|
||||
@ -266,7 +266,6 @@ export class BidiBrowserContext extends BrowserContext {
|
||||
}
|
||||
|
||||
override async doCreateNewPage(): Promise<Page> {
|
||||
assertBrowserContextIsNotOwned(this);
|
||||
const { context } = await this._browser._browserSession.send('browsingContext.create', {
|
||||
type: bidi.BrowsingContext.CreateType.Window,
|
||||
userContext: this._browserContextId,
|
||||
@ -368,7 +367,7 @@ export class BidiBrowserContext extends BrowserContext {
|
||||
async doSetHTTPCredentials(httpCredentials?: types.Credentials): Promise<void> {
|
||||
this._options.httpCredentials = httpCredentials;
|
||||
for (const page of this.pages())
|
||||
await (page._delegate as BidiPage).updateHttpCredentials();
|
||||
await (page.delegate as BidiPage).updateHttpCredentials();
|
||||
}
|
||||
|
||||
async doAddInitScript(initScript: InitScript) {
|
||||
|
||||
@ -59,7 +59,7 @@ export class BidiNetworkManager {
|
||||
if (param.request.url.startsWith('data:'))
|
||||
return;
|
||||
const redirectedFrom = param.redirectCount ? (this._requests.get(param.request.request) || null) : null;
|
||||
const frame = redirectedFrom ? redirectedFrom.request.frame() : (param.context ? this._page._frameManager.frame(param.context) : null);
|
||||
const frame = redirectedFrom ? redirectedFrom.request.frame() : (param.context ? this._page.frameManager.frame(param.context) : null);
|
||||
if (!frame)
|
||||
return;
|
||||
if (redirectedFrom)
|
||||
@ -82,7 +82,7 @@ export class BidiNetworkManager {
|
||||
}
|
||||
const request = new BidiRequest(frame, redirectedFrom, param, route);
|
||||
this._requests.set(request._id, request);
|
||||
this._page._frameManager.requestStarted(request.request, route);
|
||||
this._page.frameManager.requestStarted(request.request, route);
|
||||
}
|
||||
|
||||
private _onResponseStarted(params: bidi.Network.ResponseStartedParameters) {
|
||||
@ -115,7 +115,7 @@ export class BidiNetworkManager {
|
||||
// "raw" headers are the same as "provisional" headers in Bidi.
|
||||
response.setRawResponseHeaders(null);
|
||||
response.setResponseHeadersSize(params.response.headersSize);
|
||||
this._page._frameManager.requestReceivedResponse(response);
|
||||
this._page.frameManager.requestReceivedResponse(response);
|
||||
if (params.navigation)
|
||||
this._onNavigationResponseStarted(params);
|
||||
}
|
||||
@ -139,7 +139,7 @@ export class BidiNetworkManager {
|
||||
response._requestFinished(responseEndTime);
|
||||
}
|
||||
response._setHttpVersion(params.response.protocol);
|
||||
this._page._frameManager.reportRequestFinished(request.request, response);
|
||||
this._page.frameManager.reportRequestFinished(request.request, response);
|
||||
|
||||
}
|
||||
|
||||
@ -156,12 +156,12 @@ export class BidiNetworkManager {
|
||||
}
|
||||
request.request._setFailureText(params.errorText);
|
||||
// TODO: support canceled flag
|
||||
this._page._frameManager.requestFailed(request.request, params.errorText === 'NS_BINDING_ABORTED');
|
||||
this._page.frameManager.requestFailed(request.request, params.errorText === 'NS_BINDING_ABORTED');
|
||||
}
|
||||
|
||||
private _onAuthRequired(params: bidi.Network.AuthRequiredParameters) {
|
||||
const isBasic = params.response.authChallenges?.some(challenge => challenge.scheme.startsWith('Basic'));
|
||||
const credentials = this._page._browserContext._options.httpCredentials;
|
||||
const credentials = this._page.browserContext._options.httpCredentials;
|
||||
if (isBasic && credentials) {
|
||||
this._session.sendMayFail('network.continueWithAuth', {
|
||||
request: params.request.request,
|
||||
@ -230,7 +230,7 @@ class BidiRequest {
|
||||
redirectedFrom._redirectedTo = this;
|
||||
// TODO: missing in the spec?
|
||||
const postDataBuffer = null;
|
||||
this.request = new network.Request(frame._page._browserContext, frame, null, redirectedFrom ? redirectedFrom.request : null, payload.navigation ?? undefined,
|
||||
this.request = new network.Request(frame._page.browserContext, frame, null, redirectedFrom ? redirectedFrom.request : null, payload.navigation ?? undefined,
|
||||
payload.request.url, 'other', payload.request.method, postDataBuffer, fromBidiHeaders(payload.request.headers));
|
||||
// "raw" headers are the same as "provisional" headers in Bidi.
|
||||
this.request.setRawRequestHeaders(null);
|
||||
|
||||
@ -103,7 +103,7 @@ export class BidiPage implements PageDelegate {
|
||||
}
|
||||
|
||||
private _onFrameAttached(frameId: string, parentFrameId: string | null): frames.Frame {
|
||||
return this._page._frameManager.frameAttached(frameId, parentFrameId);
|
||||
return this._page.frameManager.frameAttached(frameId, parentFrameId);
|
||||
}
|
||||
|
||||
private _removeContextsForFrame(frame: frames.Frame, notifyFrame: boolean) {
|
||||
@ -121,7 +121,7 @@ export class BidiPage implements PageDelegate {
|
||||
return;
|
||||
if (realmInfo.type !== 'window')
|
||||
return;
|
||||
const frame = this._page._frameManager.frame(realmInfo.context);
|
||||
const frame = this._page.frameManager.frame(realmInfo.context);
|
||||
if (!frame)
|
||||
return;
|
||||
let worldName: types.World;
|
||||
@ -172,47 +172,47 @@ export class BidiPage implements PageDelegate {
|
||||
|
||||
private _onNavigationStarted(params: bidi.BrowsingContext.NavigationInfo) {
|
||||
const frameId = params.context;
|
||||
this._page._frameManager.frameRequestedNavigation(frameId, params.navigation!);
|
||||
this._page.frameManager.frameRequestedNavigation(frameId, params.navigation!);
|
||||
|
||||
const url = params.url.toLowerCase();
|
||||
if (url.startsWith('file:') || url.startsWith('data:') || url === 'about:blank') {
|
||||
// Navigation to file urls doesn't emit network events, so we fire 'commit' event right when navigation is started.
|
||||
// Doing it in domcontentload would be too late as we'd clear frame tree.
|
||||
const frame = this._page._frameManager.frame(frameId)!;
|
||||
const frame = this._page.frameManager.frame(frameId)!;
|
||||
if (frame)
|
||||
this._page._frameManager.frameCommittedNewDocumentNavigation(frameId, params.url, '', params.navigation!, /* initial */ false);
|
||||
this._page.frameManager.frameCommittedNewDocumentNavigation(frameId, params.url, '', params.navigation!, /* initial */ false);
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: there is no separate event for committed navigation, so we approximate it with responseStarted.
|
||||
private _onNavigationResponseStarted(params: bidi.Network.ResponseStartedParameters) {
|
||||
const frameId = params.context!;
|
||||
const frame = this._page._frameManager.frame(frameId);
|
||||
const frame = this._page.frameManager.frame(frameId);
|
||||
assert(frame);
|
||||
this._page._frameManager.frameCommittedNewDocumentNavigation(frameId, params.response.url, '', params.navigation!, /* initial */ false);
|
||||
this._page.frameManager.frameCommittedNewDocumentNavigation(frameId, params.response.url, '', params.navigation!, /* initial */ false);
|
||||
// if (!initial)
|
||||
// this._firstNonInitialNavigationCommittedFulfill();
|
||||
}
|
||||
|
||||
private _onDomContentLoaded(params: bidi.BrowsingContext.NavigationInfo) {
|
||||
const frameId = params.context;
|
||||
this._page._frameManager.frameLifecycleEvent(frameId, 'domcontentloaded');
|
||||
this._page.frameManager.frameLifecycleEvent(frameId, 'domcontentloaded');
|
||||
}
|
||||
|
||||
private _onLoad(params: bidi.BrowsingContext.NavigationInfo) {
|
||||
this._page._frameManager.frameLifecycleEvent(params.context, 'load');
|
||||
this._page.frameManager.frameLifecycleEvent(params.context, 'load');
|
||||
}
|
||||
|
||||
private _onNavigationAborted(params: bidi.BrowsingContext.NavigationInfo) {
|
||||
this._page._frameManager.frameAbortedNavigation(params.context, 'Navigation aborted', params.navigation || undefined);
|
||||
this._page.frameManager.frameAbortedNavigation(params.context, 'Navigation aborted', params.navigation || undefined);
|
||||
}
|
||||
|
||||
private _onNavigationFailed(params: bidi.BrowsingContext.NavigationInfo) {
|
||||
this._page._frameManager.frameAbortedNavigation(params.context, 'Navigation failed', params.navigation || undefined);
|
||||
this._page.frameManager.frameAbortedNavigation(params.context, 'Navigation failed', params.navigation || undefined);
|
||||
}
|
||||
|
||||
private _onFragmentNavigated(params: bidi.BrowsingContext.NavigationInfo) {
|
||||
this._page._frameManager.frameCommittedSameDocumentNavigation(params.context, params.url);
|
||||
this._page.frameManager.frameCommittedSameDocumentNavigation(params.context, params.url);
|
||||
}
|
||||
|
||||
private _onUserPromptOpened(event: bidi.BrowsingContext.UserPromptOpenedParameters) {
|
||||
@ -235,7 +235,7 @@ export class BidiPage implements PageDelegate {
|
||||
return;
|
||||
const callFrame = params.stackTrace?.callFrames[0];
|
||||
const location = callFrame ?? { url: '', lineNumber: 1, columnNumber: 1 };
|
||||
this._page._addConsoleMessage(entry.method, entry.args.map(arg => createHandle(context, arg)), location, params.text || undefined);
|
||||
this._page.addConsoleMessage(entry.method, entry.args.map(arg => createHandle(context, arg)), location, params.text || undefined);
|
||||
}
|
||||
|
||||
async navigateFrame(frame: frames.Frame, url: string, referrer: string | undefined): Promise<frames.GotoResult> {
|
||||
@ -328,7 +328,7 @@ export class BidiPage implements PageDelegate {
|
||||
return;
|
||||
if (event.data.type !== 'string')
|
||||
return;
|
||||
await this._page._onBindingCalled(event.data.value, context);
|
||||
await this._page.onBindingCalled(event.data.value, context);
|
||||
}
|
||||
|
||||
async addInitScript(initScript: InitScript): Promise<void> {
|
||||
@ -380,7 +380,7 @@ export class BidiPage implements PageDelegate {
|
||||
const frameId = await executionContext.contentFrameIdForFrame(handle);
|
||||
if (!frameId)
|
||||
return null;
|
||||
return this._page._frameManager.frame(frameId);
|
||||
return this._page.frameManager.frame(frameId);
|
||||
}
|
||||
|
||||
async getOwnerFrame(handle: dom.ElementHandle): Promise<string | null> {
|
||||
|
||||
@ -146,7 +146,7 @@ export abstract class Browser extends SdkObject {
|
||||
this._idToVideo.set(videoId, { context, artifact });
|
||||
pageOrError.then(page => {
|
||||
if (page instanceof Page) {
|
||||
page._video = artifact;
|
||||
page.video = artifact;
|
||||
page.emitOnContext(BrowserContext.Events.VideoStarted, artifact);
|
||||
page.emit(Page.Events.Video, artifact);
|
||||
}
|
||||
|
||||
@ -216,11 +216,11 @@ export abstract class BrowserContext extends SdkObject {
|
||||
}
|
||||
|
||||
// Unless dialogs are dismissed, setting extra http headers below does not respond.
|
||||
page?._frameManager.setCloseAllOpeningDialogs(true);
|
||||
await page?._frameManager.closeOpenDialogs();
|
||||
page?.frameManager.setCloseAllOpeningDialogs(true);
|
||||
await page?.frameManager.closeOpenDialogs();
|
||||
// Navigate to about:blank first to ensure no page scripts are running after this point.
|
||||
await page?.mainFrame().goto(metadata, 'about:blank', { timeout: 0 });
|
||||
page?._frameManager.setCloseAllOpeningDialogs(false);
|
||||
page?.frameManager.setCloseAllOpeningDialogs(false);
|
||||
|
||||
await this._resetStorage();
|
||||
await this._removeExposedBindings();
|
||||
@ -544,7 +544,7 @@ export abstract class BrowserContext extends SdkObject {
|
||||
if (originsToSave.size) {
|
||||
const internalMetadata = serverSideCallMetadata();
|
||||
const page = await this.newPage(internalMetadata);
|
||||
await page._setServerRequestInterceptor(handler => {
|
||||
await page.setServerRequestInterceptor(handler => {
|
||||
handler.fulfill({ body: '<html></html>' }).catch(() => {});
|
||||
return true;
|
||||
});
|
||||
@ -574,7 +574,7 @@ export abstract class BrowserContext extends SdkObject {
|
||||
// as a user-visible page.
|
||||
isServerSide: false,
|
||||
});
|
||||
await page._setServerRequestInterceptor(handler => {
|
||||
await page.setServerRequestInterceptor(handler => {
|
||||
handler.fulfill({ body: '<html></html>' }).catch(() => {});
|
||||
return true;
|
||||
});
|
||||
@ -585,7 +585,7 @@ export abstract class BrowserContext extends SdkObject {
|
||||
await frame.resetStorageForCurrentOriginBestEffort(newOrigins.get(origin));
|
||||
}
|
||||
|
||||
await page._setServerRequestInterceptor(undefined);
|
||||
await page.setServerRequestInterceptor(undefined);
|
||||
|
||||
this._origins = new Set([...newOrigins.keys()]);
|
||||
// It is safe to not restore the URL to about:blank since we are doing it in Page::resetForReuse.
|
||||
@ -609,7 +609,7 @@ export abstract class BrowserContext extends SdkObject {
|
||||
if (state.origins && state.origins.length) {
|
||||
const internalMetadata = serverSideCallMetadata();
|
||||
const page = await this.newPage(internalMetadata);
|
||||
await page._setServerRequestInterceptor(handler => {
|
||||
await page.setServerRequestInterceptor(handler => {
|
||||
handler.fulfill({ body: '<html></html>' }).catch(() => {});
|
||||
return true;
|
||||
});
|
||||
@ -670,13 +670,6 @@ export abstract class BrowserContext extends SdkObject {
|
||||
}
|
||||
}
|
||||
|
||||
export function assertBrowserContextIsNotOwned(context: BrowserContext) {
|
||||
for (const page of context.pages()) {
|
||||
if (page._ownedContext)
|
||||
throw new Error('Please use browser.newContext() for multi-page scripts that share the context.');
|
||||
}
|
||||
}
|
||||
|
||||
export function validateBrowserContextOptions(options: types.BrowserContextOptions, browserOptions: BrowserOptions) {
|
||||
if (options.noDefaultViewport && options.deviceScaleFactor !== undefined)
|
||||
throw new Error(`"deviceScaleFactor" option is not supported with null "viewport"`);
|
||||
|
||||
@ -21,7 +21,7 @@ import { assert } from '../../utils/isomorphic/assert';
|
||||
import { createGuid } from '../utils/crypto';
|
||||
import { Artifact } from '../artifact';
|
||||
import { Browser } from '../browser';
|
||||
import { BrowserContext, assertBrowserContextIsNotOwned, verifyGeolocation } from '../browserContext';
|
||||
import { BrowserContext, verifyGeolocation } from '../browserContext';
|
||||
import { Frame } from '../frames';
|
||||
import * as network from '../network';
|
||||
import { Page } from '../page';
|
||||
@ -245,7 +245,7 @@ export class CRBrowser extends Browser {
|
||||
|
||||
private _findOwningPage(frameId: string) {
|
||||
for (const crPage of this._crPages.values()) {
|
||||
const frame = crPage._page._frameManager.frame(frameId);
|
||||
const frame = crPage._page.frameManager.frame(frameId);
|
||||
if (frame)
|
||||
return crPage;
|
||||
}
|
||||
@ -288,7 +288,7 @@ export class CRBrowser extends Browser {
|
||||
|
||||
async startTracing(page?: Page, options: { screenshots?: boolean; categories?: string[]; } = {}) {
|
||||
assert(!this._tracingRecording, 'Cannot start recording trace while already recording trace.');
|
||||
this._tracingClient = page ? (page._delegate as CRPage)._mainFrameSession._client : this._session;
|
||||
this._tracingClient = page ? (page.delegate as CRPage)._mainFrameSession._client : this._session;
|
||||
|
||||
const defaultCategories = [
|
||||
'-*', 'devtools.timeline', 'v8.execute', 'disabled-by-default-devtools.timeline',
|
||||
@ -372,7 +372,6 @@ export class CRBrowserContext extends BrowserContext {
|
||||
}
|
||||
|
||||
override async doCreateNewPage(): Promise<Page> {
|
||||
assertBrowserContextIsNotOwned(this);
|
||||
const { targetId } = await this._browser._session.send('Target.createTarget', { url: 'about:blank', browserContextId: this._browserContextId });
|
||||
return this._browser._crPages.get(targetId)!._page;
|
||||
}
|
||||
@ -435,13 +434,13 @@ export class CRBrowserContext extends BrowserContext {
|
||||
verifyGeolocation(geolocation);
|
||||
this._options.geolocation = geolocation;
|
||||
for (const page of this.pages())
|
||||
await (page._delegate as CRPage).updateGeolocation();
|
||||
await (page.delegate as CRPage).updateGeolocation();
|
||||
}
|
||||
|
||||
async setExtraHTTPHeaders(headers: types.HeadersArray): Promise<void> {
|
||||
this._options.extraHTTPHeaders = headers;
|
||||
for (const page of this.pages())
|
||||
await (page._delegate as CRPage).updateExtraHTTPHeaders();
|
||||
await (page.delegate as CRPage).updateExtraHTTPHeaders();
|
||||
for (const sw of this.serviceWorkers())
|
||||
await (sw as CRServiceWorker).updateExtraHTTPHeaders();
|
||||
}
|
||||
@ -449,14 +448,14 @@ export class CRBrowserContext extends BrowserContext {
|
||||
async setUserAgent(userAgent: string | undefined): Promise<void> {
|
||||
this._options.userAgent = userAgent;
|
||||
for (const page of this.pages())
|
||||
await (page._delegate as CRPage).updateUserAgent();
|
||||
await (page.delegate as CRPage).updateUserAgent();
|
||||
// TODO: service workers don't have Emulation domain?
|
||||
}
|
||||
|
||||
async setOffline(offline: boolean): Promise<void> {
|
||||
this._options.offline = offline;
|
||||
for (const page of this.pages())
|
||||
await (page._delegate as CRPage).updateOffline();
|
||||
await (page.delegate as CRPage).updateOffline();
|
||||
for (const sw of this.serviceWorkers())
|
||||
await (sw as CRServiceWorker).updateOffline();
|
||||
}
|
||||
@ -464,24 +463,24 @@ export class CRBrowserContext extends BrowserContext {
|
||||
async doSetHTTPCredentials(httpCredentials?: types.Credentials): Promise<void> {
|
||||
this._options.httpCredentials = httpCredentials;
|
||||
for (const page of this.pages())
|
||||
await (page._delegate as CRPage).updateHttpCredentials();
|
||||
await (page.delegate as CRPage).updateHttpCredentials();
|
||||
for (const sw of this.serviceWorkers())
|
||||
await (sw as CRServiceWorker).updateHttpCredentials();
|
||||
}
|
||||
|
||||
async doAddInitScript(initScript: InitScript) {
|
||||
for (const page of this.pages())
|
||||
await (page._delegate as CRPage).addInitScript(initScript);
|
||||
await (page.delegate as CRPage).addInitScript(initScript);
|
||||
}
|
||||
|
||||
async doRemoveNonInternalInitScripts() {
|
||||
for (const page of this.pages())
|
||||
await (page._delegate as CRPage).removeNonInternalInitScripts();
|
||||
await (page.delegate as CRPage).removeNonInternalInitScripts();
|
||||
}
|
||||
|
||||
async doUpdateRequestInterception(): Promise<void> {
|
||||
for (const page of this.pages())
|
||||
await (page._delegate as CRPage).updateRequestInterception();
|
||||
await (page.delegate as CRPage).updateRequestInterception();
|
||||
for (const sw of this.serviceWorkers())
|
||||
await (sw as CRServiceWorker).updateRequestInterception();
|
||||
}
|
||||
@ -493,7 +492,7 @@ export class CRBrowserContext extends BrowserContext {
|
||||
// beforeunload.
|
||||
const openedBeforeUnloadDialogs: Dialog[] = [];
|
||||
for (const crPage of this._crPages()) {
|
||||
const dialogs = [...crPage._page._frameManager._openedDialogs].filter(dialog => dialog.type() === 'beforeunload');
|
||||
const dialogs = [...crPage._page.frameManager._openedDialogs].filter(dialog => dialog.type() === 'beforeunload');
|
||||
openedBeforeUnloadDialogs.push(...dialogs);
|
||||
}
|
||||
await Promise.all(openedBeforeUnloadDialogs.map(dialog => dialog.dismiss()));
|
||||
@ -508,7 +507,7 @@ export class CRBrowserContext extends BrowserContext {
|
||||
await this._browser._session.send('Target.disposeBrowserContext', { browserContextId: this._browserContextId });
|
||||
this._browser._contexts.delete(this._browserContextId);
|
||||
for (const [targetId, serviceWorker] of this._browser._serviceWorkers) {
|
||||
if (serviceWorker._browserContext !== this)
|
||||
if (serviceWorker.browserContext !== this)
|
||||
continue;
|
||||
// When closing a browser context, service workers are shutdown
|
||||
// asynchronously and we get detached from them later.
|
||||
@ -559,15 +558,15 @@ export class CRBrowserContext extends BrowserContext {
|
||||
}
|
||||
|
||||
serviceWorkers(): Worker[] {
|
||||
return Array.from(this._browser._serviceWorkers.values()).filter(serviceWorker => serviceWorker._browserContext === this);
|
||||
return Array.from(this._browser._serviceWorkers.values()).filter(serviceWorker => serviceWorker.browserContext === this);
|
||||
}
|
||||
|
||||
async newCDPSession(page: Page | Frame): Promise<CDPSession> {
|
||||
let targetId: string | null = null;
|
||||
if (page instanceof Page) {
|
||||
targetId = (page._delegate as CRPage)._targetId;
|
||||
targetId = (page.delegate as CRPage)._targetId;
|
||||
} else if (page instanceof Frame) {
|
||||
const session = (page._page._delegate as CRPage)._sessions.get(page._id);
|
||||
const session = (page._page.delegate as CRPage)._sessions.get(page._id);
|
||||
if (!session)
|
||||
throw new Error(`This frame does not have a separate CDP session, it is a part of the parent frame's session`);
|
||||
targetId = session._targetId;
|
||||
|
||||
@ -74,13 +74,13 @@ export class CRNetworkManager {
|
||||
];
|
||||
if (this._page) {
|
||||
sessionInfo.eventListeners.push(...[
|
||||
eventsHelper.addEventListener(session, 'Network.webSocketCreated', e => this._page!._frameManager.onWebSocketCreated(e.requestId, e.url)),
|
||||
eventsHelper.addEventListener(session, 'Network.webSocketWillSendHandshakeRequest', e => this._page!._frameManager.onWebSocketRequest(e.requestId)),
|
||||
eventsHelper.addEventListener(session, 'Network.webSocketHandshakeResponseReceived', e => this._page!._frameManager.onWebSocketResponse(e.requestId, e.response.status, e.response.statusText)),
|
||||
eventsHelper.addEventListener(session, 'Network.webSocketFrameSent', e => e.response.payloadData && this._page!._frameManager.onWebSocketFrameSent(e.requestId, e.response.opcode, e.response.payloadData)),
|
||||
eventsHelper.addEventListener(session, 'Network.webSocketFrameReceived', e => e.response.payloadData && this._page!._frameManager.webSocketFrameReceived(e.requestId, e.response.opcode, e.response.payloadData)),
|
||||
eventsHelper.addEventListener(session, 'Network.webSocketClosed', e => this._page!._frameManager.webSocketClosed(e.requestId)),
|
||||
eventsHelper.addEventListener(session, 'Network.webSocketFrameError', e => this._page!._frameManager.webSocketError(e.requestId, e.errorMessage)),
|
||||
eventsHelper.addEventListener(session, 'Network.webSocketCreated', e => this._page!.frameManager.onWebSocketCreated(e.requestId, e.url)),
|
||||
eventsHelper.addEventListener(session, 'Network.webSocketWillSendHandshakeRequest', e => this._page!.frameManager.onWebSocketRequest(e.requestId)),
|
||||
eventsHelper.addEventListener(session, 'Network.webSocketHandshakeResponseReceived', e => this._page!.frameManager.onWebSocketResponse(e.requestId, e.response.status, e.response.statusText)),
|
||||
eventsHelper.addEventListener(session, 'Network.webSocketFrameSent', e => e.response.payloadData && this._page!.frameManager.onWebSocketFrameSent(e.requestId, e.response.opcode, e.response.payloadData)),
|
||||
eventsHelper.addEventListener(session, 'Network.webSocketFrameReceived', e => e.response.payloadData && this._page!.frameManager.webSocketFrameReceived(e.requestId, e.response.opcode, e.response.payloadData)),
|
||||
eventsHelper.addEventListener(session, 'Network.webSocketClosed', e => this._page!.frameManager.webSocketClosed(e.requestId)),
|
||||
eventsHelper.addEventListener(session, 'Network.webSocketFrameError', e => this._page!.frameManager.webSocketError(e.requestId, e.errorMessage)),
|
||||
]);
|
||||
}
|
||||
this._sessions.set(session, sessionInfo);
|
||||
@ -287,19 +287,19 @@ export class CRNetworkManager {
|
||||
redirectedFrom = request;
|
||||
}
|
||||
}
|
||||
let frame = requestWillBeSentEvent.frameId ? this._page?._frameManager.frame(requestWillBeSentEvent.frameId) : requestWillBeSentSessionInfo.workerFrame;
|
||||
let frame = requestWillBeSentEvent.frameId ? this._page?.frameManager.frame(requestWillBeSentEvent.frameId) : requestWillBeSentSessionInfo.workerFrame;
|
||||
// Requests from workers lack frameId, because we receive Network.requestWillBeSent
|
||||
// on the worker target. However, we receive Fetch.requestPaused on the page target,
|
||||
// and lack workerFrame there. Luckily, Fetch.requestPaused provides a frameId.
|
||||
if (!frame && this._page && requestPausedEvent && requestPausedEvent.frameId)
|
||||
frame = this._page._frameManager.frame(requestPausedEvent.frameId);
|
||||
frame = this._page.frameManager.frame(requestPausedEvent.frameId);
|
||||
|
||||
// Check if it's main resource request interception (targetId === main frame id).
|
||||
if (!frame && this._page && requestWillBeSentEvent.frameId === (this._page?._delegate as CRPage)._targetId) {
|
||||
if (!frame && this._page && requestWillBeSentEvent.frameId === (this._page?.delegate as CRPage)._targetId) {
|
||||
// Main resource request for the page is being intercepted so the Frame is not created
|
||||
// yet. Precreate it here for the purposes of request interception. It will be updated
|
||||
// later as soon as the request continues and we receive frame tree from the page.
|
||||
frame = this._page._frameManager.frameAttached(requestWillBeSentEvent.frameId, null);
|
||||
frame = this._page.frameManager.frameAttached(requestWillBeSentEvent.frameId, null);
|
||||
}
|
||||
|
||||
// CORS options preflight request is generated by the network stack. If interception is enabled,
|
||||
@ -349,7 +349,7 @@ export class CRNetworkManager {
|
||||
const documentId = isNavigationRequest ? requestWillBeSentEvent.loaderId : undefined;
|
||||
const request = new InterceptableRequest({
|
||||
session: requestWillBeSentSessionInfo.session,
|
||||
context: (this._page || this._serviceWorker)!._browserContext,
|
||||
context: (this._page || this._serviceWorker)!.browserContext,
|
||||
frame: frame || null,
|
||||
serviceWorker: this._serviceWorker || null,
|
||||
documentId,
|
||||
@ -367,7 +367,7 @@ export class CRNetworkManager {
|
||||
// right away, so that client can call it from the route handler.
|
||||
request.request.setRawRequestHeaders(headersObjectToArray(requestPausedEvent!.request.headers, '\n'));
|
||||
}
|
||||
(this._page?._frameManager || this._serviceWorker)!.requestStarted(request.request, route || undefined);
|
||||
(this._page?.frameManager || this._serviceWorker)!.requestStarted(request.request, route || undefined);
|
||||
}
|
||||
|
||||
_createResponse(request: InterceptableRequest, responsePayload: Protocol.Network.Response, hasExtraInfo: boolean): network.Response {
|
||||
@ -454,8 +454,8 @@ export class CRNetworkManager {
|
||||
response.setEncodedBodySize(null);
|
||||
response._requestFinished((timestamp - request._timestamp) * 1000);
|
||||
this._deleteRequest(request);
|
||||
(this._page?._frameManager || this._serviceWorker)!.requestReceivedResponse(response);
|
||||
(this._page?._frameManager || this._serviceWorker)!.reportRequestFinished(request.request, response);
|
||||
(this._page?.frameManager || this._serviceWorker)!.requestReceivedResponse(response);
|
||||
(this._page?.frameManager || this._serviceWorker)!.reportRequestFinished(request.request, response);
|
||||
}
|
||||
|
||||
_onResponseReceivedExtraInfo(event: Protocol.Network.responseReceivedExtraInfoPayload) {
|
||||
@ -479,7 +479,7 @@ export class CRNetworkManager {
|
||||
if (!request)
|
||||
return;
|
||||
const response = this._createResponse(request, event.response, event.hasExtraInfo);
|
||||
(this._page?._frameManager || this._serviceWorker)!.requestReceivedResponse(response);
|
||||
(this._page?.frameManager || this._serviceWorker)!.requestReceivedResponse(response);
|
||||
}
|
||||
|
||||
_onLoadingFinished(sessionInfo: SessionInfo, event: Protocol.Network.loadingFinishedPayload) {
|
||||
@ -501,7 +501,7 @@ export class CRNetworkManager {
|
||||
response._requestFinished(helper.secondsToRoundishMillis(event.timestamp - request._timestamp));
|
||||
}
|
||||
this._deleteRequest(request);
|
||||
(this._page?._frameManager || this._serviceWorker)!.reportRequestFinished(request.request, response);
|
||||
(this._page?.frameManager || this._serviceWorker)!.reportRequestFinished(request.request, response);
|
||||
}
|
||||
|
||||
_onLoadingFailed(sessionInfo: SessionInfo, event: Protocol.Network.loadingFailedPayload) {
|
||||
@ -537,7 +537,7 @@ export class CRNetworkManager {
|
||||
}
|
||||
this._deleteRequest(request);
|
||||
request.request._setFailureText(event.errorText || event.blockedReason || '');
|
||||
(this._page?._frameManager || this._serviceWorker)!.requestFailed(request.request, !!event.canceled);
|
||||
(this._page?.frameManager || this._serviceWorker)!.requestFailed(request.request, !!event.canceled);
|
||||
}
|
||||
|
||||
private _maybeUpdateRequestSession(sessionInfo: SessionInfo, request: InterceptableRequest) {
|
||||
|
||||
@ -79,7 +79,7 @@ export class CRPage implements PageDelegate {
|
||||
readonly _nextWindowOpenPopupFeatures: string[][] = [];
|
||||
|
||||
static mainFrameSession(page: Page): FrameSession {
|
||||
const crPage = page._delegate as CRPage;
|
||||
const crPage = page.delegate as CRPage;
|
||||
return crPage._mainFrameSession;
|
||||
}
|
||||
|
||||
@ -108,7 +108,7 @@ export class CRPage implements PageDelegate {
|
||||
const features = opener._nextWindowOpenPopupFeatures.shift() || [];
|
||||
const viewportSize = helper.getViewportSizeFromWindowFeatures(features);
|
||||
if (viewportSize)
|
||||
this._page._emulatedSize = { viewport: viewportSize, screen: viewportSize };
|
||||
this._page.setEmulatedSize({ viewport: viewportSize, screen: viewportSize });
|
||||
}
|
||||
|
||||
const createdEvent = this._isBackgroundPage ? CRBrowserContext.CREvents.BackgroundPage : BrowserContext.Events.Page;
|
||||
@ -441,7 +441,7 @@ class FrameSession {
|
||||
}
|
||||
|
||||
async _initialize(hasUIWindow: boolean) {
|
||||
const isSettingStorageState = this._page._browserContext.isSettingStorageState();
|
||||
const isSettingStorageState = this._page.browserContext.isSettingStorageState();
|
||||
if (!isSettingStorageState && hasUIWindow &&
|
||||
!this._crPage._browserContext._browser.isClank() &&
|
||||
!this._crPage._browserContext._options.noDefaultViewport) {
|
||||
@ -480,7 +480,7 @@ class FrameSession {
|
||||
this._addRendererListeners();
|
||||
}
|
||||
|
||||
const localFrames = this._isMainFrame() ? this._page.frames() : [this._page._frameManager.frame(this._targetId)!];
|
||||
const localFrames = this._isMainFrame() ? this._page.frames() : [this._page.frameManager.frame(this._targetId)!];
|
||||
for (const frame of localFrames) {
|
||||
// Note: frames might be removed before we send these.
|
||||
this._client._sendMayFail('Page.createIsolatedWorld', {
|
||||
@ -574,9 +574,9 @@ class FrameSession {
|
||||
if (this._eventBelongsToStaleFrame(event.frameId))
|
||||
return;
|
||||
if (event.name === 'load')
|
||||
this._page._frameManager.frameLifecycleEvent(event.frameId, 'load');
|
||||
this._page.frameManager.frameLifecycleEvent(event.frameId, 'load');
|
||||
else if (event.name === 'DOMContentLoaded')
|
||||
this._page._frameManager.frameLifecycleEvent(event.frameId, 'domcontentloaded');
|
||||
this._page.frameManager.frameLifecycleEvent(event.frameId, 'domcontentloaded');
|
||||
}
|
||||
|
||||
_handleFrameTree(frameTree: Protocol.Page.FrameTree) {
|
||||
@ -590,7 +590,7 @@ class FrameSession {
|
||||
}
|
||||
|
||||
private _eventBelongsToStaleFrame(frameId: string) {
|
||||
const frame = this._page._frameManager.frame(frameId);
|
||||
const frame = this._page.frameManager.frame(frameId);
|
||||
// Subtree may be already gone because some ancestor navigation destroyed the oopif.
|
||||
if (!frame)
|
||||
return true;
|
||||
@ -607,26 +607,26 @@ class FrameSession {
|
||||
if (frameSession && frameId !== this._targetId) {
|
||||
// This is a remote -> local frame transition.
|
||||
frameSession._swappedIn = true;
|
||||
const frame = this._page._frameManager.frame(frameId);
|
||||
const frame = this._page.frameManager.frame(frameId);
|
||||
// Frame or even a whole subtree may be already gone, because some ancestor did navigate.
|
||||
if (frame)
|
||||
this._page._frameManager.removeChildFramesRecursively(frame);
|
||||
this._page.frameManager.removeChildFramesRecursively(frame);
|
||||
return;
|
||||
}
|
||||
if (parentFrameId && !this._page._frameManager.frame(parentFrameId)) {
|
||||
if (parentFrameId && !this._page.frameManager.frame(parentFrameId)) {
|
||||
// Parent frame may be gone already because some ancestor frame navigated and
|
||||
// destroyed the whole subtree of some oopif, while oopif's process is still sending us events.
|
||||
// Be careful to not confuse this with "main frame navigated cross-process" scenario
|
||||
// where parentFrameId is null.
|
||||
return;
|
||||
}
|
||||
this._page._frameManager.frameAttached(frameId, parentFrameId);
|
||||
this._page.frameManager.frameAttached(frameId, parentFrameId);
|
||||
}
|
||||
|
||||
_onFrameNavigated(framePayload: Protocol.Page.Frame, initial: boolean) {
|
||||
if (this._eventBelongsToStaleFrame(framePayload.id))
|
||||
return;
|
||||
this._page._frameManager.frameCommittedNewDocumentNavigation(framePayload.id, framePayload.url + (framePayload.urlFragment || ''), framePayload.name || '', framePayload.loaderId, initial);
|
||||
this._page.frameManager.frameCommittedNewDocumentNavigation(framePayload.id, framePayload.url + (framePayload.urlFragment || ''), framePayload.name || '', framePayload.loaderId, initial);
|
||||
if (!initial)
|
||||
this._firstNonInitialNavigationCommittedFulfill();
|
||||
}
|
||||
@ -635,13 +635,13 @@ class FrameSession {
|
||||
if (this._eventBelongsToStaleFrame(payload.frameId))
|
||||
return;
|
||||
if (payload.disposition === 'currentTab')
|
||||
this._page._frameManager.frameRequestedNavigation(payload.frameId);
|
||||
this._page.frameManager.frameRequestedNavigation(payload.frameId);
|
||||
}
|
||||
|
||||
_onFrameNavigatedWithinDocument(frameId: string, url: string) {
|
||||
if (this._eventBelongsToStaleFrame(frameId))
|
||||
return;
|
||||
this._page._frameManager.frameCommittedSameDocumentNavigation(frameId, url);
|
||||
this._page.frameManager.frameCommittedSameDocumentNavigation(frameId, url);
|
||||
}
|
||||
|
||||
_onFrameDetached(frameId: string, reason: 'remove' | 'swap') {
|
||||
@ -655,17 +655,17 @@ class FrameSession {
|
||||
// This is a local -> remote frame transition, where
|
||||
// Page.frameDetached arrives before Target.attachedToTarget.
|
||||
// We should keep the frame in the tree, and it will be used for the new target.
|
||||
const frame = this._page._frameManager.frame(frameId);
|
||||
const frame = this._page.frameManager.frame(frameId);
|
||||
if (frame)
|
||||
this._page._frameManager.removeChildFramesRecursively(frame);
|
||||
this._page.frameManager.removeChildFramesRecursively(frame);
|
||||
return;
|
||||
}
|
||||
// Just a regular frame detach.
|
||||
this._page._frameManager.frameDetached(frameId);
|
||||
this._page.frameManager.frameDetached(frameId);
|
||||
}
|
||||
|
||||
_onExecutionContextCreated(contextPayload: Protocol.Runtime.ExecutionContextDescription) {
|
||||
const frame = contextPayload.auxData ? this._page._frameManager.frame(contextPayload.auxData.frameId) : null;
|
||||
const frame = contextPayload.auxData ? this._page.frameManager.frame(contextPayload.auxData.frameId) : null;
|
||||
if (!frame || this._eventBelongsToStaleFrame(frame._id))
|
||||
return;
|
||||
const delegate = new CRExecutionContext(this._client, contextPayload);
|
||||
@ -699,10 +699,10 @@ class FrameSession {
|
||||
if (event.targetInfo.type === 'iframe') {
|
||||
// Frame id equals target id.
|
||||
const targetId = event.targetInfo.targetId;
|
||||
const frame = this._page._frameManager.frame(targetId);
|
||||
const frame = this._page.frameManager.frame(targetId);
|
||||
if (!frame)
|
||||
return; // Subtree may be already gone due to renderer/browser race.
|
||||
this._page._frameManager.removeChildFramesRecursively(frame);
|
||||
this._page.frameManager.removeChildFramesRecursively(frame);
|
||||
for (const [contextId, context] of this._contextIdToContext) {
|
||||
if (context.frame === frame)
|
||||
this._onExecutionContextDestroyed(contextId);
|
||||
@ -720,22 +720,22 @@ class FrameSession {
|
||||
|
||||
const url = event.targetInfo.url;
|
||||
const worker = new Worker(this._page, url);
|
||||
this._page._addWorker(event.sessionId, worker);
|
||||
this._page.addWorker(event.sessionId, worker);
|
||||
this._workerSessions.set(event.sessionId, session);
|
||||
session.once('Runtime.executionContextCreated', async event => {
|
||||
worker._createExecutionContext(new CRExecutionContext(session, event.context));
|
||||
worker.createExecutionContext(new CRExecutionContext(session, event.context));
|
||||
});
|
||||
// This might fail if the target is closed before we initialize.
|
||||
session._sendMayFail('Runtime.enable');
|
||||
// TODO: attribute workers to the right frame.
|
||||
this._crPage._networkManager.addSession(session, this._page._frameManager.frame(this._targetId) ?? undefined).catch(() => {});
|
||||
this._crPage._networkManager.addSession(session, this._page.frameManager.frame(this._targetId) ?? undefined).catch(() => {});
|
||||
session._sendMayFail('Runtime.runIfWaitingForDebugger');
|
||||
session._sendMayFail('Target.setAutoAttach', { autoAttach: true, waitForDebuggerOnStart: true, flatten: true });
|
||||
session.on('Target.attachedToTarget', event => this._onAttachedToTarget(event));
|
||||
session.on('Target.detachedFromTarget', event => this._onDetachedFromTarget(event));
|
||||
session.on('Runtime.consoleAPICalled', event => {
|
||||
const args = event.args.map(o => createHandle(worker._existingExecutionContext!, o));
|
||||
this._page._addConsoleMessage(event.type, args, toConsoleMessageLocation(event.stackTrace));
|
||||
const args = event.args.map(o => createHandle(worker.existingExecutionContext!, o));
|
||||
this._page.addConsoleMessage(event.type, args, toConsoleMessageLocation(event.stackTrace));
|
||||
});
|
||||
session.on('Runtime.exceptionThrown', exception => this._page.emitOnContextOnceInitialized(BrowserContext.Events.PageError, exceptionToError(exception.exceptionDetails), this._page));
|
||||
}
|
||||
@ -745,7 +745,7 @@ class FrameSession {
|
||||
const workerSession = this._workerSessions.get(event.sessionId);
|
||||
if (workerSession) {
|
||||
workerSession.dispose();
|
||||
this._page._removeWorker(event.sessionId);
|
||||
this._page.removeWorker(event.sessionId);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -768,7 +768,7 @@ class FrameSession {
|
||||
// Child was not swapped in - that means frameAttached did not happen and
|
||||
// this is remote detach rather than remote -> local swap.
|
||||
if (!childFrameSession._swappedIn)
|
||||
this._page._frameManager.frameDetached(event.targetId!);
|
||||
this._page.frameManager.frameDetached(event.targetId!);
|
||||
childFrameSession.dispose();
|
||||
});
|
||||
}
|
||||
@ -798,7 +798,7 @@ class FrameSession {
|
||||
if (!context)
|
||||
return;
|
||||
const values = event.args.map(arg => createHandle(context, arg));
|
||||
this._page._addConsoleMessage(event.type, values, toConsoleMessageLocation(event.stackTrace));
|
||||
this._page.addConsoleMessage(event.type, values, toConsoleMessageLocation(event.stackTrace));
|
||||
}
|
||||
|
||||
async _onBindingCalled(event: Protocol.Runtime.bindingCalledPayload) {
|
||||
@ -806,12 +806,12 @@ class FrameSession {
|
||||
if (!(pageOrError instanceof Error)) {
|
||||
const context = this._contextIdToContext.get(event.executionContextId);
|
||||
if (context)
|
||||
await this._page._onBindingCalled(event.payload, context);
|
||||
await this._page.onBindingCalled(event.payload, context);
|
||||
}
|
||||
}
|
||||
|
||||
_onDialog(event: Protocol.Page.javascriptDialogOpeningPayload) {
|
||||
if (!this._page._frameManager.frame(this._targetId))
|
||||
if (!this._page.frameManager.frame(this._targetId))
|
||||
return; // Our frame/subtree may be gone already.
|
||||
this._page.emitOnContext(BrowserContext.Events.Dialog, new dialog.Dialog(
|
||||
this._page,
|
||||
@ -820,7 +820,7 @@ class FrameSession {
|
||||
async (accept: boolean, promptText?: string) => {
|
||||
// TODO: this should actually be a CDP event that notifies about a cancelled navigation attempt.
|
||||
if (this._isMainFrame() && event.type === 'beforeunload' && !accept)
|
||||
this._page._frameManager.frameAbortedNavigation(this._page.mainFrame()._id, 'navigation cancelled by beforeunload dialog');
|
||||
this._page.frameManager.frameAbortedNavigation(this._page.mainFrame()._id, 'navigation cancelled by beforeunload dialog');
|
||||
await this._client.send('Page.handleJavaScriptDialog', { accept, promptText });
|
||||
},
|
||||
event.defaultPrompt));
|
||||
@ -845,14 +845,14 @@ class FrameSession {
|
||||
lineNumber: lineNumber || 0,
|
||||
columnNumber: 0,
|
||||
};
|
||||
this._page._addConsoleMessage(level, [], location, text);
|
||||
this._page.addConsoleMessage(level, [], location, text);
|
||||
}
|
||||
}
|
||||
|
||||
async _onFileChooserOpened(event: Protocol.Page.fileChooserOpenedPayload) {
|
||||
if (!event.backendNodeId)
|
||||
return;
|
||||
const frame = this._page._frameManager.frame(event.frameId);
|
||||
const frame = this._page.frameManager.frame(event.frameId);
|
||||
if (!frame)
|
||||
return;
|
||||
let handle;
|
||||
@ -1070,7 +1070,7 @@ class FrameSession {
|
||||
});
|
||||
if (!nodeInfo || typeof nodeInfo.node.frameId !== 'string')
|
||||
return null;
|
||||
return this._page._frameManager.frame(nodeInfo.node.frameId);
|
||||
return this._page.frameManager.frame(nodeInfo.node.frameId);
|
||||
}
|
||||
|
||||
async _getOwnerFrame(handle: dom.ElementHandle): Promise<string | null> {
|
||||
@ -1112,7 +1112,7 @@ class FrameSession {
|
||||
}
|
||||
|
||||
private async _framePosition(): Promise<types.Point | null> {
|
||||
const frame = this._page._frameManager.frame(this._targetId);
|
||||
const frame = this._page.frameManager.frame(this._targetId);
|
||||
if (!frame)
|
||||
return null;
|
||||
if (frame === this._page.mainFrame())
|
||||
|
||||
@ -23,18 +23,18 @@ import type { CRBrowserContext } from './crBrowser';
|
||||
import type { CRSession } from './crConnection';
|
||||
|
||||
export class CRServiceWorker extends Worker {
|
||||
readonly _browserContext: CRBrowserContext;
|
||||
readonly _networkManager?: CRNetworkManager;
|
||||
readonly browserContext: CRBrowserContext;
|
||||
private readonly _networkManager?: CRNetworkManager;
|
||||
private _session: CRSession;
|
||||
|
||||
constructor(browserContext: CRBrowserContext, session: CRSession, url: string) {
|
||||
super(browserContext, url);
|
||||
this._session = session;
|
||||
this._browserContext = browserContext;
|
||||
this.browserContext = browserContext;
|
||||
if (!!process.env.PW_EXPERIMENTAL_SERVICE_WORKER_NETWORK_EVENTS)
|
||||
this._networkManager = new CRNetworkManager(null, this);
|
||||
session.once('Runtime.executionContextCreated', event => {
|
||||
this._createExecutionContext(new CRExecutionContext(session, event.context));
|
||||
this.createExecutionContext(new CRExecutionContext(session, event.context));
|
||||
});
|
||||
|
||||
if (this._networkManager && this._isNetworkInspectionEnabled()) {
|
||||
@ -62,19 +62,19 @@ export class CRServiceWorker extends Worker {
|
||||
async updateOffline(): Promise<void> {
|
||||
if (!this._isNetworkInspectionEnabled())
|
||||
return;
|
||||
await this._networkManager?.setOffline(!!this._browserContext._options.offline).catch(() => {});
|
||||
await this._networkManager?.setOffline(!!this.browserContext._options.offline).catch(() => {});
|
||||
}
|
||||
|
||||
async updateHttpCredentials(): Promise<void> {
|
||||
if (!this._isNetworkInspectionEnabled())
|
||||
return;
|
||||
await this._networkManager?.authenticate(this._browserContext._options.httpCredentials || null).catch(() => {});
|
||||
await this._networkManager?.authenticate(this.browserContext._options.httpCredentials || null).catch(() => {});
|
||||
}
|
||||
|
||||
async updateExtraHTTPHeaders(): Promise<void> {
|
||||
if (!this._isNetworkInspectionEnabled())
|
||||
return;
|
||||
await this._networkManager?.setExtraHTTPHeaders(this._browserContext._options.extraHTTPHeaders || []).catch(() => {});
|
||||
await this._networkManager?.setExtraHTTPHeaders(this.browserContext._options.extraHTTPHeaders || []).catch(() => {});
|
||||
}
|
||||
|
||||
async updateRequestInterception(): Promise<void> {
|
||||
@ -84,32 +84,32 @@ export class CRServiceWorker extends Worker {
|
||||
}
|
||||
|
||||
needsRequestInterception(): boolean {
|
||||
return this._isNetworkInspectionEnabled() && !!this._browserContext._requestInterceptor;
|
||||
return this._isNetworkInspectionEnabled() && !!this.browserContext._requestInterceptor;
|
||||
}
|
||||
|
||||
reportRequestFinished(request: network.Request, response: network.Response | null) {
|
||||
this._browserContext.emit(BrowserContext.Events.RequestFinished, { request, response });
|
||||
this.browserContext.emit(BrowserContext.Events.RequestFinished, { request, response });
|
||||
}
|
||||
|
||||
requestFailed(request: network.Request, _canceled: boolean) {
|
||||
this._browserContext.emit(BrowserContext.Events.RequestFailed, request);
|
||||
this.browserContext.emit(BrowserContext.Events.RequestFailed, request);
|
||||
}
|
||||
|
||||
requestReceivedResponse(response: network.Response) {
|
||||
this._browserContext.emit(BrowserContext.Events.Response, response);
|
||||
this.browserContext.emit(BrowserContext.Events.Response, response);
|
||||
}
|
||||
|
||||
requestStarted(request: network.Request, route?: network.RouteDelegate) {
|
||||
this._browserContext.emit(BrowserContext.Events.Request, request);
|
||||
this.browserContext.emit(BrowserContext.Events.Request, request);
|
||||
if (route) {
|
||||
const r = new network.Route(request, route);
|
||||
if (this._browserContext._requestInterceptor?.(r, request))
|
||||
if (this.browserContext._requestInterceptor?.(r, request))
|
||||
return;
|
||||
r.continue({ isFallback: true }).catch(() => {});
|
||||
}
|
||||
}
|
||||
|
||||
private _isNetworkInspectionEnabled(): boolean {
|
||||
return this._browserContext._options.serviceWorkers !== 'block';
|
||||
return this.browserContext._options.serviceWorkers !== 'block';
|
||||
}
|
||||
}
|
||||
|
||||
@ -77,7 +77,7 @@ export class DebugController extends SdkObject {
|
||||
async resetForReuse() {
|
||||
const contexts = new Set<BrowserContext>();
|
||||
for (const page of this._playwright.allPages())
|
||||
contexts.add(page.context());
|
||||
contexts.add(page.browserContext);
|
||||
for (const context of contexts)
|
||||
await context.resetForReuse(internalMetadata, null);
|
||||
}
|
||||
@ -111,7 +111,7 @@ export class DebugController extends SdkObject {
|
||||
// Update test id attribute.
|
||||
if (params.testIdAttributeName) {
|
||||
for (const page of this._playwright.allPages())
|
||||
page.context().selectors().setTestIdAttributeName(params.testIdAttributeName);
|
||||
page.browserContext.selectors().setTestIdAttributeName(params.testIdAttributeName);
|
||||
}
|
||||
// Toggle the mode.
|
||||
for (const recorder of await this._allRecorders()) {
|
||||
@ -170,7 +170,7 @@ export class DebugController extends SdkObject {
|
||||
private async _allRecorders(): Promise<Recorder[]> {
|
||||
const contexts = new Set<BrowserContext>();
|
||||
for (const page of this._playwright.allPages())
|
||||
contexts.add(page.context());
|
||||
contexts.add(page.browserContext);
|
||||
const result = await Promise.all([...contexts].map(c => Recorder.showInspector(c, { omitCallTracking: true }, () => Promise.resolve(new InspectingRecorderApp(this)))));
|
||||
return result.filter(Boolean) as Recorder[];
|
||||
}
|
||||
|
||||
@ -39,7 +39,7 @@ export class Dialog extends SdkObject {
|
||||
this._message = message;
|
||||
this._onHandle = onHandle;
|
||||
this._defaultValue = defaultValue || '';
|
||||
this._page._frameManager.dialogDidOpen(this);
|
||||
this._page.frameManager.dialogDidOpen(this);
|
||||
this.instrumentation.onDialog(this);
|
||||
}
|
||||
|
||||
@ -62,14 +62,14 @@ export class Dialog extends SdkObject {
|
||||
async accept(promptText?: string) {
|
||||
assert(!this._handled, 'Cannot accept dialog which is already handled!');
|
||||
this._handled = true;
|
||||
this._page._frameManager.dialogWillClose(this);
|
||||
this._page.frameManager.dialogWillClose(this);
|
||||
await this._onHandle(true, promptText);
|
||||
}
|
||||
|
||||
async dismiss() {
|
||||
assert(!this._handled, 'Cannot dismiss dialog which is already handled!');
|
||||
this._handled = true;
|
||||
this._page._frameManager.dialogWillClose(this);
|
||||
this._page.frameManager.dialogWillClose(this);
|
||||
await this._onHandle(false);
|
||||
}
|
||||
|
||||
|
||||
@ -385,7 +385,7 @@ export class DispatcherConnection {
|
||||
}
|
||||
|
||||
function closeReason(sdkObject: SdkObject): string | undefined {
|
||||
return sdkObject.attribution.page?._closeReason ||
|
||||
return sdkObject.attribution.page?.closeReason ||
|
||||
sdkObject.attribution.context?._closeReason ||
|
||||
sdkObject.attribution.browser?._closeReason;
|
||||
}
|
||||
|
||||
@ -93,10 +93,10 @@ export class PageDispatcher extends Dispatcher<Page, channels.PageChannel, Brows
|
||||
this.addObjectListener(Page.Events.WebSocket, webSocket => this._dispatchEvent('webSocket', { webSocket: new WebSocketDispatcher(this, webSocket) }));
|
||||
this.addObjectListener(Page.Events.Worker, worker => this._dispatchEvent('worker', { worker: new WorkerDispatcher(this, worker) }));
|
||||
this.addObjectListener(Page.Events.Video, (artifact: Artifact) => this._dispatchEvent('video', { artifact: ArtifactDispatcher.from(parentScope, artifact) }));
|
||||
if (page._video)
|
||||
this._dispatchEvent('video', { artifact: ArtifactDispatcher.from(this.parentScope(), page._video) });
|
||||
if (page.video)
|
||||
this._dispatchEvent('video', { artifact: ArtifactDispatcher.from(this.parentScope(), page.video) });
|
||||
// Ensure client knows about all frames.
|
||||
const frames = page._frameManager.frames();
|
||||
const frames = page.frameManager.frames();
|
||||
for (let i = 1; i < frames.length; i++)
|
||||
this._onFrameAttached(frames[i]);
|
||||
}
|
||||
@ -183,7 +183,7 @@ export class PageDispatcher extends Dispatcher<Page, channels.PageChannel, Brows
|
||||
}
|
||||
const urlMatchers = params.patterns.map(pattern => pattern.regexSource ? new RegExp(pattern.regexSource, pattern.regexFlags!) : pattern.glob!);
|
||||
await this._page.setClientRequestInterceptor((route, request) => {
|
||||
const matchesSome = urlMatchers.some(urlMatch => urlMatches(this._page._browserContext._options.baseURL, request.url(), urlMatch));
|
||||
const matchesSome = urlMatchers.some(urlMatch => urlMatches(this._page.browserContext._options.baseURL, request.url(), urlMatch));
|
||||
if (!matchesSome)
|
||||
return false;
|
||||
this._dispatchEvent('route', { route: RouteDispatcher.from(RequestDispatcher.from(this.parentScope(), request), route) });
|
||||
@ -347,7 +347,7 @@ export class WorkerDispatcher extends Dispatcher<Worker, channels.WorkerChannel,
|
||||
|
||||
constructor(scope: PageDispatcher | BrowserContextDispatcher, worker: Worker) {
|
||||
super(scope, worker, 'Worker', {
|
||||
url: worker.url()
|
||||
url: worker.url
|
||||
});
|
||||
this.addObjectListener(Worker.Events.Close, () => this._dispatchEvent('close'));
|
||||
}
|
||||
|
||||
@ -59,7 +59,7 @@ export class WebSocketRouteDispatcher extends Dispatcher<{ guid: string }, chann
|
||||
|
||||
static async installIfNeeded(target: Page | BrowserContext) {
|
||||
const kBindingName = '__pwWebSocketBinding';
|
||||
const context = target instanceof Page ? target.context() : target;
|
||||
const context = target instanceof Page ? target.browserContext : target;
|
||||
if (!context.hasBinding(kBindingName)) {
|
||||
await context.exposeBinding(kBindingName, false, (source, payload: ws.BindingPayload) => {
|
||||
if (payload.type === 'onCreate') {
|
||||
|
||||
@ -62,7 +62,7 @@ export class FrameExecutionContext extends js.ExecutionContext {
|
||||
|
||||
override adoptIfNeeded(handle: js.JSHandle): Promise<js.JSHandle> | null {
|
||||
if (handle instanceof ElementHandle && handle._context !== this)
|
||||
return this.frame._page._delegate.adoptElementHandle(handle, this);
|
||||
return this.frame._page.delegate.adoptElementHandle(handle, this);
|
||||
return null;
|
||||
}
|
||||
|
||||
@ -85,15 +85,15 @@ export class FrameExecutionContext extends js.ExecutionContext {
|
||||
injectedScript(): Promise<js.JSHandle<InjectedScript>> {
|
||||
if (!this._injectedScriptPromise) {
|
||||
const customEngines: InjectedScriptOptions['customEngines'] = [];
|
||||
const selectorsRegistry = this.frame._page.context().selectors();
|
||||
const selectorsRegistry = this.frame._page.browserContext.selectors();
|
||||
for (const [name, { source }] of selectorsRegistry._engines)
|
||||
customEngines.push({ name, source });
|
||||
const sdkLanguage = this.frame.attribution.playwright.options.sdkLanguage;
|
||||
const options: InjectedScriptOptions = {
|
||||
sdkLanguage,
|
||||
testIdAttributeName: selectorsRegistry.testIdAttributeName(),
|
||||
stableRafCount: this.frame._page._delegate.rafCountForStablePosition(),
|
||||
browserName: this.frame._page._browserContext._browser.options.name,
|
||||
stableRafCount: this.frame._page.delegate.rafCountForStablePosition(),
|
||||
browserName: this.frame._page.browserContext._browser.options.name,
|
||||
inputFileRoleTextbox: process.env.PLAYWRIGHT_INPUT_FILE_TEXTBOX ? true : false,
|
||||
customEngines,
|
||||
};
|
||||
@ -160,14 +160,14 @@ export class ElementHandle<T extends Node = Node> extends js.JSHandle<T> {
|
||||
}
|
||||
|
||||
async ownerFrame(): Promise<frames.Frame | null> {
|
||||
const frameId = await this._page._delegate.getOwnerFrame(this);
|
||||
const frameId = await this._page.delegate.getOwnerFrame(this);
|
||||
if (!frameId)
|
||||
return null;
|
||||
const frame = this._page._frameManager.frame(frameId);
|
||||
const frame = this._page.frameManager.frame(frameId);
|
||||
if (frame)
|
||||
return frame;
|
||||
for (const page of this._page._browserContext.pages()) {
|
||||
const frame = page._frameManager.frame(frameId);
|
||||
for (const page of this._page.browserContext.pages()) {
|
||||
const frame = page.frameManager.frame(frameId);
|
||||
if (frame)
|
||||
return frame;
|
||||
}
|
||||
@ -182,7 +182,7 @@ export class ElementHandle<T extends Node = Node> extends js.JSHandle<T> {
|
||||
const isFrameElement = throwRetargetableDOMError(await this.isIframeElement());
|
||||
if (!isFrameElement)
|
||||
return null;
|
||||
return this._page._delegate.getContentFrame(this);
|
||||
return this._page.delegate.getContentFrame(this);
|
||||
}
|
||||
|
||||
async generateLocatorString(): Promise<string | undefined> {
|
||||
@ -219,7 +219,7 @@ export class ElementHandle<T extends Node = Node> extends js.JSHandle<T> {
|
||||
}
|
||||
|
||||
async _scrollRectIntoViewIfNeeded(rect?: types.Rect): Promise<'error:notvisible' | 'error:notconnected' | 'done'> {
|
||||
return await this._page._delegate.scrollRectIntoViewIfNeeded(this, rect);
|
||||
return await this._page.delegate.scrollRectIntoViewIfNeeded(this, rect);
|
||||
}
|
||||
|
||||
async _waitAndScrollIntoViewIfNeeded(progress: Progress, waitForVisible: boolean): Promise<void> {
|
||||
@ -239,7 +239,7 @@ export class ElementHandle<T extends Node = Node> extends js.JSHandle<T> {
|
||||
const controller = new ProgressController(metadata, this);
|
||||
return controller.run(
|
||||
progress => this._waitAndScrollIntoViewIfNeeded(progress, false /* waitForVisible */),
|
||||
this._page._timeoutSettings.timeout(options));
|
||||
this._page.timeoutSettings.timeout(options));
|
||||
}
|
||||
|
||||
private async _clickablePoint(): Promise<types.Point | 'error:notvisible' | 'error:notinviewport' | 'error:notconnected'> {
|
||||
@ -263,7 +263,7 @@ export class ElementHandle<T extends Node = Node> extends js.JSHandle<T> {
|
||||
};
|
||||
|
||||
const [quads, metrics] = await Promise.all([
|
||||
this._page._delegate.getContentQuads(this),
|
||||
this._page.delegate.getContentQuads(this),
|
||||
this._page.mainFrame()._utilityContext().then(utility => utility.evaluate(() => ({ width: innerWidth, height: innerHeight }))),
|
||||
] as const);
|
||||
if (quads === 'error:notconnected')
|
||||
@ -275,7 +275,7 @@ export class ElementHandle<T extends Node = Node> extends js.JSHandle<T> {
|
||||
const filtered = quads.map(quad => intersectQuadWithViewport(quad)).filter(quad => computeQuadArea(quad) > 0.99);
|
||||
if (!filtered.length)
|
||||
return 'error:notinviewport';
|
||||
if (this._page._browserContext._browser.options.name === 'firefox') {
|
||||
if (this._page.browserContext._browser.options.name === 'firefox') {
|
||||
// Firefox internally uses integer coordinates, so 8.x is converted to 8 or 9 when clicking.
|
||||
//
|
||||
// This does not work nicely for small elements. For example, 1x1 square with corners
|
||||
@ -470,7 +470,7 @@ export class ElementHandle<T extends Node = Node> extends js.JSHandle<T> {
|
||||
});
|
||||
}
|
||||
|
||||
const actionResult = await this._page._frameManager.waitForSignalsCreatedBy(progress, options.waitAfter === true, async () => {
|
||||
const actionResult = await this._page.frameManager.waitForSignalsCreatedBy(progress, options.waitAfter === true, async () => {
|
||||
if ((options as any).__testHookBeforePointerAction)
|
||||
await (options as any).__testHookBeforePointerAction();
|
||||
progress.throwIfAborted(); // Avoid action that has side-effects.
|
||||
@ -522,7 +522,7 @@ export class ElementHandle<T extends Node = Node> extends js.JSHandle<T> {
|
||||
await this._markAsTargetElement(metadata);
|
||||
const result = await this._hover(progress, options);
|
||||
return assertDone(throwRetargetableDOMError(result));
|
||||
}, this._page._timeoutSettings.timeout(options));
|
||||
}, this._page.timeoutSettings.timeout(options));
|
||||
}
|
||||
|
||||
_hover(progress: Progress, options: types.PointerActionOptions & types.PointerActionWaitOptions): Promise<'error:notconnected' | 'done'> {
|
||||
@ -535,7 +535,7 @@ export class ElementHandle<T extends Node = Node> extends js.JSHandle<T> {
|
||||
await this._markAsTargetElement(metadata);
|
||||
const result = await this._click(progress, { ...options, waitAfter: !options.noWaitAfter });
|
||||
return assertDone(throwRetargetableDOMError(result));
|
||||
}, this._page._timeoutSettings.timeout(options));
|
||||
}, this._page.timeoutSettings.timeout(options));
|
||||
}
|
||||
|
||||
_click(progress: Progress, options: { waitAfter: boolean | 'disabled' } & types.MouseClickOptions & types.PointerActionWaitOptions): Promise<'error:notconnected' | 'done'> {
|
||||
@ -548,7 +548,7 @@ export class ElementHandle<T extends Node = Node> extends js.JSHandle<T> {
|
||||
await this._markAsTargetElement(metadata);
|
||||
const result = await this._dblclick(progress, options);
|
||||
return assertDone(throwRetargetableDOMError(result));
|
||||
}, this._page._timeoutSettings.timeout(options));
|
||||
}, this._page.timeoutSettings.timeout(options));
|
||||
}
|
||||
|
||||
_dblclick(progress: Progress, options: types.MouseMultiClickOptions & types.PointerActionWaitOptions): Promise<'error:notconnected' | 'done'> {
|
||||
@ -561,7 +561,7 @@ export class ElementHandle<T extends Node = Node> extends js.JSHandle<T> {
|
||||
await this._markAsTargetElement(metadata);
|
||||
const result = await this._tap(progress, options);
|
||||
return assertDone(throwRetargetableDOMError(result));
|
||||
}, this._page._timeoutSettings.timeout(options));
|
||||
}, this._page.timeoutSettings.timeout(options));
|
||||
}
|
||||
|
||||
_tap(progress: Progress, options: types.PointerActionWaitOptions): Promise<'error:notconnected' | 'done'> {
|
||||
@ -574,7 +574,7 @@ export class ElementHandle<T extends Node = Node> extends js.JSHandle<T> {
|
||||
await this._markAsTargetElement(metadata);
|
||||
const result = await this._selectOption(progress, elements, values, options);
|
||||
return throwRetargetableDOMError(result);
|
||||
}, this._page._timeoutSettings.timeout(options));
|
||||
}, this._page.timeoutSettings.timeout(options));
|
||||
}
|
||||
|
||||
async _selectOption(progress: Progress, elements: ElementHandle[], values: types.SelectOption[], options: types.CommonActionOptions): Promise<string[] | 'error:notconnected'> {
|
||||
@ -610,7 +610,7 @@ export class ElementHandle<T extends Node = Node> extends js.JSHandle<T> {
|
||||
await this._markAsTargetElement(metadata);
|
||||
const result = await this._fill(progress, value, options);
|
||||
assertDone(throwRetargetableDOMError(result));
|
||||
}, this._page._timeoutSettings.timeout(options));
|
||||
}, this._page.timeoutSettings.timeout(options));
|
||||
}
|
||||
|
||||
async _fill(progress: Progress, value: string, options: types.CommonActionOptions): Promise<'error:notconnected' | 'done'> {
|
||||
@ -656,7 +656,7 @@ export class ElementHandle<T extends Node = Node> extends js.JSHandle<T> {
|
||||
}, { force: options.force });
|
||||
}, options);
|
||||
assertDone(throwRetargetableDOMError(result));
|
||||
}, this._page._timeoutSettings.timeout(options));
|
||||
}, this._page.timeoutSettings.timeout(options));
|
||||
}
|
||||
|
||||
async setInputFiles(metadata: CallMetadata, params: channels.ElementHandleSetInputFilesParams) {
|
||||
@ -666,7 +666,7 @@ export class ElementHandle<T extends Node = Node> extends js.JSHandle<T> {
|
||||
await this._markAsTargetElement(metadata);
|
||||
const result = await this._setInputFiles(progress, inputFileItems);
|
||||
return assertDone(throwRetargetableDOMError(result));
|
||||
}, this._page._timeoutSettings.timeout(params));
|
||||
}, this._page.timeoutSettings.timeout(params));
|
||||
}
|
||||
|
||||
async _setInputFiles(progress: Progress, items: InputFilesItems): Promise<'error:notconnected' | 'done'> {
|
||||
@ -701,7 +701,7 @@ export class ElementHandle<T extends Node = Node> extends js.JSHandle<T> {
|
||||
const waitForInputEvent = localDirectory ? this.evaluate(node => new Promise<any>(fulfill => {
|
||||
node.addEventListener('input', fulfill, { once: true });
|
||||
})).catch(() => {}) : Promise.resolve();
|
||||
await this._page._delegate.setInputFilePaths(retargeted, localPathsOrDirectory);
|
||||
await this._page.delegate.setInputFilePaths(retargeted, localPathsOrDirectory);
|
||||
await waitForInputEvent;
|
||||
} else {
|
||||
await retargeted.evaluateInUtility(([injected, node, files]) =>
|
||||
@ -735,7 +735,7 @@ export class ElementHandle<T extends Node = Node> extends js.JSHandle<T> {
|
||||
await this._markAsTargetElement(metadata);
|
||||
const result = await this._type(progress, text, options);
|
||||
return assertDone(throwRetargetableDOMError(result));
|
||||
}, this._page._timeoutSettings.timeout(options));
|
||||
}, this._page.timeoutSettings.timeout(options));
|
||||
}
|
||||
|
||||
async _type(progress: Progress, text: string, options: { delay?: number } & types.TimeoutOptions & types.StrictOptions): Promise<'error:notconnected' | 'done'> {
|
||||
@ -755,13 +755,13 @@ export class ElementHandle<T extends Node = Node> extends js.JSHandle<T> {
|
||||
await this._markAsTargetElement(metadata);
|
||||
const result = await this._press(progress, key, options);
|
||||
return assertDone(throwRetargetableDOMError(result));
|
||||
}, this._page._timeoutSettings.timeout(options));
|
||||
}, this._page.timeoutSettings.timeout(options));
|
||||
}
|
||||
|
||||
async _press(progress: Progress, key: string, options: { delay?: number, noWaitAfter?: boolean } & types.TimeoutOptions & types.StrictOptions): Promise<'error:notconnected' | 'done'> {
|
||||
progress.log(`elementHandle.press("${key}")`);
|
||||
await this.instrumentation.onBeforeInputAction(this, progress.metadata);
|
||||
return this._page._frameManager.waitForSignalsCreatedBy(progress, !options.noWaitAfter, async () => {
|
||||
return this._page.frameManager.waitForSignalsCreatedBy(progress, !options.noWaitAfter, async () => {
|
||||
const result = await this._focus(progress, true /* resetSelectionIfNotFocused */);
|
||||
if (result !== 'done')
|
||||
return result;
|
||||
@ -776,7 +776,7 @@ export class ElementHandle<T extends Node = Node> extends js.JSHandle<T> {
|
||||
return controller.run(async progress => {
|
||||
const result = await this._setChecked(progress, true, options);
|
||||
return assertDone(throwRetargetableDOMError(result));
|
||||
}, this._page._timeoutSettings.timeout(options));
|
||||
}, this._page.timeoutSettings.timeout(options));
|
||||
}
|
||||
|
||||
async uncheck(metadata: CallMetadata, options: { position?: types.Point } & types.PointerActionWaitOptions) {
|
||||
@ -784,7 +784,7 @@ export class ElementHandle<T extends Node = Node> extends js.JSHandle<T> {
|
||||
return controller.run(async progress => {
|
||||
const result = await this._setChecked(progress, false, options);
|
||||
return assertDone(throwRetargetableDOMError(result));
|
||||
}, this._page._timeoutSettings.timeout(options));
|
||||
}, this._page.timeoutSettings.timeout(options));
|
||||
}
|
||||
|
||||
async _setChecked(progress: Progress, state: boolean, options: { position?: types.Point } & types.PointerActionWaitOptions): Promise<'error:notconnected' | 'done'> {
|
||||
@ -808,7 +808,7 @@ export class ElementHandle<T extends Node = Node> extends js.JSHandle<T> {
|
||||
}
|
||||
|
||||
async boundingBox(): Promise<types.Rect | null> {
|
||||
return this._page._delegate.getBoundingBox(this);
|
||||
return this._page.delegate.getBoundingBox(this);
|
||||
}
|
||||
|
||||
async ariaSnapshot(options: { ref?: boolean, emitGeneric?: boolean, mode?: 'raw' | 'regex' }): Promise<string> {
|
||||
@ -818,8 +818,8 @@ export class ElementHandle<T extends Node = Node> extends js.JSHandle<T> {
|
||||
async screenshot(metadata: CallMetadata, options: ScreenshotOptions & TimeoutOptions = {}): Promise<Buffer> {
|
||||
const controller = new ProgressController(metadata, this);
|
||||
return controller.run(
|
||||
progress => this._page._screenshotter.screenshotElement(progress, this, options),
|
||||
this._page._timeoutSettings.timeout(options));
|
||||
progress => this._page.screenshotter.screenshotElement(progress, this, options),
|
||||
this._page.timeoutSettings.timeout(options));
|
||||
}
|
||||
|
||||
async querySelector(selector: string, options: types.StrictOptions): Promise<ElementHandle | null> {
|
||||
@ -872,7 +872,7 @@ export class ElementHandle<T extends Node = Node> extends js.JSHandle<T> {
|
||||
}, state);
|
||||
}, {});
|
||||
assertDone(throwRetargetableDOMError(result));
|
||||
}, this._page._timeoutSettings.timeout(options));
|
||||
}, this._page.timeoutSettings.timeout(options));
|
||||
}
|
||||
|
||||
async waitForSelector(metadata: CallMetadata, selector: string, options: types.WaitForElementOptions = {}): Promise<ElementHandle<Element> | null> {
|
||||
@ -881,7 +881,7 @@ export class ElementHandle<T extends Node = Node> extends js.JSHandle<T> {
|
||||
|
||||
async _adoptTo(context: FrameExecutionContext): Promise<ElementHandle<T>> {
|
||||
if (this._context !== context) {
|
||||
const adopted = await this._page._delegate.adoptElementHandle(this, context);
|
||||
const adopted = await this._page.delegate.adoptElementHandle(this, context);
|
||||
this.dispose();
|
||||
return adopted;
|
||||
}
|
||||
|
||||
@ -27,14 +27,14 @@ export class Download {
|
||||
private _suggestedFilename: string | undefined;
|
||||
|
||||
constructor(page: Page, downloadsPath: string, uuid: string, url: string, suggestedFilename?: string) {
|
||||
const unaccessibleErrorMessage = page._browserContext._options.acceptDownloads === 'deny' ? 'Pass { acceptDownloads: true } when you are creating your browser context.' : undefined;
|
||||
const unaccessibleErrorMessage = page.browserContext._options.acceptDownloads === 'deny' ? 'Pass { acceptDownloads: true } when you are creating your browser context.' : undefined;
|
||||
this.artifact = new Artifact(page, path.join(downloadsPath, uuid), unaccessibleErrorMessage, () => {
|
||||
return this._page._browserContext.cancelDownload(uuid);
|
||||
return this._page.browserContext.cancelDownload(uuid);
|
||||
});
|
||||
this._page = page;
|
||||
this.url = url;
|
||||
this._suggestedFilename = suggestedFilename;
|
||||
page._browserContext._downloads.add(this);
|
||||
page.browserContext._downloads.add(this);
|
||||
if (suggestedFilename !== undefined)
|
||||
this._fireDownloadEvent();
|
||||
}
|
||||
|
||||
@ -142,7 +142,7 @@ export class ElectronApplication extends SdkObject {
|
||||
|
||||
async browserWindow(page: Page): Promise<js.JSHandle<BrowserWindow>> {
|
||||
// Assume CRPage as Electron is always Chromium.
|
||||
const targetId = (page._delegate as CRPage)._targetId;
|
||||
const targetId = (page.delegate as CRPage)._targetId;
|
||||
const electronHandle = await this._nodeElectronHandlePromise;
|
||||
return await electronHandle.evaluateHandle(({ BrowserWindow, webContents }, targetId) => {
|
||||
const wc = webContents.fromDevToolsTargetId(targetId);
|
||||
|
||||
@ -58,7 +58,7 @@ export async function prepareFilesForUpload(frame: Frame, params: channels.Eleme
|
||||
lastModifiedMs?: number,
|
||||
}[] | undefined = payloads;
|
||||
|
||||
if (!frame._page._browserContext._browser._isCollocatedWithServer) {
|
||||
if (!frame._page.browserContext._browser._isCollocatedWithServer) {
|
||||
// If the browser is on a different machine read files into buffers.
|
||||
if (localPaths) {
|
||||
if (await filesExceedUploadLimit(localPaths))
|
||||
|
||||
@ -17,7 +17,7 @@
|
||||
|
||||
import { assert } from '../../utils';
|
||||
import { Browser } from '../browser';
|
||||
import { BrowserContext, assertBrowserContextIsNotOwned, verifyGeolocation } from '../browserContext';
|
||||
import { BrowserContext, verifyGeolocation } from '../browserContext';
|
||||
import { TargetClosedError } from '../errors';
|
||||
import { kPlaywrightBinding } from '../javascript';
|
||||
import * as network from '../network';
|
||||
@ -137,7 +137,7 @@ export class FFBrowser extends Browser {
|
||||
return;
|
||||
|
||||
// Abort the navigation that turned into download.
|
||||
ffPage._page._frameManager.frameAbortedNavigation(payload.frameId, 'Download is starting');
|
||||
ffPage._page.frameManager.frameAbortedNavigation(payload.frameId, 'Download is starting');
|
||||
|
||||
let originPage = ffPage._page.initializedOrUndefined();
|
||||
// If it's a new window download, report it on the opener page.
|
||||
@ -282,7 +282,6 @@ export class FFBrowserContext extends BrowserContext {
|
||||
}
|
||||
|
||||
override async doCreateNewPage(): Promise<Page> {
|
||||
assertBrowserContextIsNotOwned(this);
|
||||
const { targetId } = await this._browser.session.send('Browser.newPage', {
|
||||
browserContextId: this._browserContextId
|
||||
}).catch(e => {
|
||||
|
||||
@ -59,7 +59,7 @@ export class FFNetworkManager {
|
||||
|
||||
_onRequestWillBeSent(event: Protocol.Network.requestWillBeSentPayload) {
|
||||
const redirectedFrom = event.redirectedFrom ? (this._requests.get(event.redirectedFrom) || null) : null;
|
||||
const frame = redirectedFrom ? redirectedFrom.request.frame() : (event.frameId ? this._page._frameManager.frame(event.frameId) : null);
|
||||
const frame = redirectedFrom ? redirectedFrom.request.frame() : (event.frameId ? this._page.frameManager.frame(event.frameId) : null);
|
||||
if (!frame)
|
||||
return;
|
||||
if (redirectedFrom)
|
||||
@ -69,7 +69,7 @@ export class FFNetworkManager {
|
||||
if (event.isIntercepted)
|
||||
route = new FFRouteImpl(this._session, request);
|
||||
this._requests.set(request._id, request);
|
||||
this._page._frameManager.requestStarted(request.request, route);
|
||||
this._page.frameManager.requestStarted(request.request, route);
|
||||
}
|
||||
|
||||
_onResponseReceived(event: Protocol.Network.responseReceivedPayload) {
|
||||
@ -121,7 +121,7 @@ export class FFNetworkManager {
|
||||
response.setRawResponseHeaders(null);
|
||||
// Headers size are not available in Firefox.
|
||||
response.setResponseHeadersSize(null);
|
||||
this._page._frameManager.requestReceivedResponse(response);
|
||||
this._page.frameManager.requestReceivedResponse(response);
|
||||
}
|
||||
|
||||
_onRequestFinished(event: Protocol.Network.requestFinishedPayload) {
|
||||
@ -143,7 +143,7 @@ export class FFNetworkManager {
|
||||
}
|
||||
if (event.protocolVersion)
|
||||
response._setHttpVersion(event.protocolVersion);
|
||||
this._page._frameManager.reportRequestFinished(request.request, response);
|
||||
this._page.frameManager.reportRequestFinished(request.request, response);
|
||||
}
|
||||
|
||||
_onRequestFailed(event: Protocol.Network.requestFailedPayload) {
|
||||
@ -158,7 +158,7 @@ export class FFNetworkManager {
|
||||
response._requestFinished(-1);
|
||||
}
|
||||
request.request._setFailureText(event.errorCode);
|
||||
this._page._frameManager.requestFailed(request.request, event.errorCode === 'NS_BINDING_ABORTED');
|
||||
this._page.frameManager.requestFailed(request.request, event.errorCode === 'NS_BINDING_ABORTED');
|
||||
}
|
||||
}
|
||||
|
||||
@ -204,7 +204,7 @@ class InterceptableRequest {
|
||||
let postDataBuffer = null;
|
||||
if (payload.postData)
|
||||
postDataBuffer = Buffer.from(payload.postData, 'base64');
|
||||
this.request = new network.Request(frame._page._browserContext, frame, null, redirectedFrom ? redirectedFrom.request : null, payload.navigationId,
|
||||
this.request = new network.Request(frame._page.browserContext, frame, null, redirectedFrom ? redirectedFrom.request : null, payload.navigationId,
|
||||
payload.url, internalCauseToResourceType[payload.internalCause] || causeToResourceType[payload.cause] || 'other', payload.method, postDataBuffer, payload.headers);
|
||||
// "raw" headers are the same as "provisional" headers in Firefox.
|
||||
this.request.setRawRequestHeaders(null);
|
||||
|
||||
@ -120,27 +120,27 @@ export class FFPage implements PageDelegate {
|
||||
}
|
||||
|
||||
_onWebSocketCreated(event: Protocol.Page.webSocketCreatedPayload) {
|
||||
this._page._frameManager.onWebSocketCreated(webSocketId(event.frameId, event.wsid), event.requestURL);
|
||||
this._page._frameManager.onWebSocketRequest(webSocketId(event.frameId, event.wsid));
|
||||
this._page.frameManager.onWebSocketCreated(webSocketId(event.frameId, event.wsid), event.requestURL);
|
||||
this._page.frameManager.onWebSocketRequest(webSocketId(event.frameId, event.wsid));
|
||||
}
|
||||
|
||||
_onWebSocketClosed(event: Protocol.Page.webSocketClosedPayload) {
|
||||
if (event.error)
|
||||
this._page._frameManager.webSocketError(webSocketId(event.frameId, event.wsid), event.error);
|
||||
this._page._frameManager.webSocketClosed(webSocketId(event.frameId, event.wsid));
|
||||
this._page.frameManager.webSocketError(webSocketId(event.frameId, event.wsid), event.error);
|
||||
this._page.frameManager.webSocketClosed(webSocketId(event.frameId, event.wsid));
|
||||
}
|
||||
|
||||
_onWebSocketFrameReceived(event: Protocol.Page.webSocketFrameReceivedPayload) {
|
||||
this._page._frameManager.webSocketFrameReceived(webSocketId(event.frameId, event.wsid), event.opcode, event.data);
|
||||
this._page.frameManager.webSocketFrameReceived(webSocketId(event.frameId, event.wsid), event.opcode, event.data);
|
||||
}
|
||||
|
||||
_onWebSocketFrameSent(event: Protocol.Page.webSocketFrameSentPayload) {
|
||||
this._page._frameManager.onWebSocketFrameSent(webSocketId(event.frameId, event.wsid), event.opcode, event.data);
|
||||
this._page.frameManager.onWebSocketFrameSent(webSocketId(event.frameId, event.wsid), event.opcode, event.data);
|
||||
}
|
||||
|
||||
_onExecutionContextCreated(payload: Protocol.Runtime.executionContextCreatedPayload) {
|
||||
const { executionContextId, auxData } = payload;
|
||||
const frame = this._page._frameManager.frame(auxData.frameId!);
|
||||
const frame = this._page.frameManager.frame(auxData.frameId!);
|
||||
if (!frame)
|
||||
return;
|
||||
const delegate = new FFExecutionContext(this._session, executionContextId);
|
||||
@ -178,17 +178,17 @@ export class FFPage implements PageDelegate {
|
||||
|
||||
_onLinkClicked(phase: 'before' | 'after') {
|
||||
if (phase === 'before')
|
||||
this._page._frameManager.frameWillPotentiallyRequestNavigation();
|
||||
this._page.frameManager.frameWillPotentiallyRequestNavigation();
|
||||
else
|
||||
this._page._frameManager.frameDidPotentiallyRequestNavigation();
|
||||
this._page.frameManager.frameDidPotentiallyRequestNavigation();
|
||||
}
|
||||
|
||||
_onNavigationStarted(params: Protocol.Page.navigationStartedPayload) {
|
||||
this._page._frameManager.frameRequestedNavigation(params.frameId, params.navigationId);
|
||||
this._page.frameManager.frameRequestedNavigation(params.frameId, params.navigationId);
|
||||
}
|
||||
|
||||
_onNavigationAborted(params: Protocol.Page.navigationAbortedPayload) {
|
||||
this._page._frameManager.frameAbortedNavigation(params.frameId, params.errorText, params.navigationId);
|
||||
this._page.frameManager.frameAbortedNavigation(params.frameId, params.errorText, params.navigationId);
|
||||
}
|
||||
|
||||
_onNavigationCommitted(params: Protocol.Page.navigationCommittedPayload) {
|
||||
@ -196,27 +196,27 @@ export class FFPage implements PageDelegate {
|
||||
if (worker.frameId === params.frameId)
|
||||
this._onWorkerDestroyed({ workerId });
|
||||
}
|
||||
this._page._frameManager.frameCommittedNewDocumentNavigation(params.frameId, params.url, params.name || '', params.navigationId || '', false);
|
||||
this._page.frameManager.frameCommittedNewDocumentNavigation(params.frameId, params.url, params.name || '', params.navigationId || '', false);
|
||||
}
|
||||
|
||||
_onSameDocumentNavigation(params: Protocol.Page.sameDocumentNavigationPayload) {
|
||||
this._page._frameManager.frameCommittedSameDocumentNavigation(params.frameId, params.url);
|
||||
this._page.frameManager.frameCommittedSameDocumentNavigation(params.frameId, params.url);
|
||||
}
|
||||
|
||||
_onFrameAttached(params: Protocol.Page.frameAttachedPayload) {
|
||||
this._page._frameManager.frameAttached(params.frameId, params.parentFrameId);
|
||||
this._page.frameManager.frameAttached(params.frameId, params.parentFrameId);
|
||||
}
|
||||
|
||||
_onFrameDetached(params: Protocol.Page.frameDetachedPayload) {
|
||||
this._page._frameManager.frameDetached(params.frameId);
|
||||
this._page.frameManager.frameDetached(params.frameId);
|
||||
}
|
||||
|
||||
_onEventFired(payload: Protocol.Page.eventFiredPayload) {
|
||||
const { frameId, name } = payload;
|
||||
if (name === 'load')
|
||||
this._page._frameManager.frameLifecycleEvent(frameId, 'load');
|
||||
this._page.frameManager.frameLifecycleEvent(frameId, 'load');
|
||||
if (name === 'DOMContentLoaded')
|
||||
this._page._frameManager.frameLifecycleEvent(frameId, 'domcontentloaded');
|
||||
this._page.frameManager.frameLifecycleEvent(frameId, 'domcontentloaded');
|
||||
}
|
||||
|
||||
_onUncaughtError(params: Protocol.Page.uncaughtErrorPayload) {
|
||||
@ -233,7 +233,7 @@ export class FFPage implements PageDelegate {
|
||||
if (!context)
|
||||
return;
|
||||
// Juggler reports 'warn' for some internal messages generated by the browser.
|
||||
this._page._addConsoleMessage(type === 'warn' ? 'warning' : type, args.map(arg => createHandle(context, arg)), location);
|
||||
this._page.addConsoleMessage(type === 'warn' ? 'warning' : type, args.map(arg => createHandle(context, arg)), location);
|
||||
}
|
||||
|
||||
_onDialogOpened(params: Protocol.Page.dialogOpenedPayload) {
|
||||
@ -252,7 +252,7 @@ export class FFPage implements PageDelegate {
|
||||
if (!(pageOrError instanceof Error)) {
|
||||
const context = this._contextIdToContext.get(event.executionContextId);
|
||||
if (context)
|
||||
await this._page._onBindingCalled(event.payload, context);
|
||||
await this._page.onBindingCalled(event.payload, context);
|
||||
}
|
||||
}
|
||||
|
||||
@ -278,14 +278,14 @@ export class FFPage implements PageDelegate {
|
||||
});
|
||||
});
|
||||
this._workers.set(workerId, { session: workerSession, frameId: event.frameId });
|
||||
this._page._addWorker(workerId, worker);
|
||||
this._page.addWorker(workerId, worker);
|
||||
workerSession.once('Runtime.executionContextCreated', event => {
|
||||
worker._createExecutionContext(new FFExecutionContext(workerSession, event.executionContextId));
|
||||
worker.createExecutionContext(new FFExecutionContext(workerSession, event.executionContextId));
|
||||
});
|
||||
workerSession.on('Runtime.console', event => {
|
||||
const { type, args, location } = event;
|
||||
const context = worker._existingExecutionContext!;
|
||||
this._page._addConsoleMessage(type, args.map(arg => createHandle(context, arg)), location);
|
||||
const context = worker.existingExecutionContext!;
|
||||
this._page.addConsoleMessage(type, args.map(arg => createHandle(context, arg)), location);
|
||||
});
|
||||
// Note: we receive worker exceptions directly from the page.
|
||||
}
|
||||
@ -297,7 +297,7 @@ export class FFPage implements PageDelegate {
|
||||
return;
|
||||
worker.session.dispose();
|
||||
this._workers.delete(workerId);
|
||||
this._page._removeWorker(workerId);
|
||||
this._page.removeWorker(workerId);
|
||||
}
|
||||
|
||||
async _onDispatchMessageFromWorker(event: Protocol.Page.dispatchMessageFromWorkerPayload) {
|
||||
@ -431,7 +431,7 @@ export class FFPage implements PageDelegate {
|
||||
});
|
||||
if (!contentFrameId)
|
||||
return null;
|
||||
return this._page._frameManager.frame(contentFrameId);
|
||||
return this._page.frameManager.frame(contentFrameId);
|
||||
}
|
||||
|
||||
async getOwnerFrame(handle: dom.ElementHandle): Promise<string | null> {
|
||||
|
||||
@ -45,8 +45,8 @@ export class FrameSelectors {
|
||||
}
|
||||
|
||||
private _parseSelector(selector: string | ParsedSelector, options?: types.StrictOptions): SelectorInfo {
|
||||
const strict = typeof options?.strict === 'boolean' ? options.strict : !!this.frame._page.context()._options.strictSelectors;
|
||||
return this.frame._page.context().selectors().parseSelector(selector, strict);
|
||||
const strict = typeof options?.strict === 'boolean' ? options.strict : !!this.frame._page.browserContext._options.strictSelectors;
|
||||
return this.frame._page.browserContext.selectors().parseSelector(selector, strict);
|
||||
}
|
||||
|
||||
async query(selector: string, options?: types.StrictOptions, scope?: ElementHandle): Promise<ElementHandle<Element> | null> {
|
||||
@ -137,7 +137,7 @@ export class FrameSelectors {
|
||||
const element = handle.asElement() as ElementHandle<Element> | null;
|
||||
if (!element)
|
||||
return null;
|
||||
const maybeFrame = await frame._page._delegate.getContentFrame(element);
|
||||
const maybeFrame = await frame._page.delegate.getContentFrame(element);
|
||||
element.dispose();
|
||||
if (!maybeFrame)
|
||||
return null;
|
||||
@ -163,7 +163,7 @@ export class FrameSelectors {
|
||||
async function adoptIfNeeded<T extends Node>(handle: ElementHandle<T>, context: FrameExecutionContext): Promise<ElementHandle<T>> {
|
||||
if (handle._context === context)
|
||||
return handle;
|
||||
const adopted = await handle._page._delegate.adoptElementHandle(handle, context);
|
||||
const adopted = await handle._page.delegate.adoptElementHandle(handle, context);
|
||||
handle.dispose();
|
||||
return adopted;
|
||||
}
|
||||
|
||||
@ -171,7 +171,7 @@ export class FrameManager {
|
||||
if (progress)
|
||||
progress.cleanupWhenAborted(() => this._signalBarriers.delete(barrier));
|
||||
const result = await action();
|
||||
await this._page._delegate.inputActionEpilogue();
|
||||
await this._page.delegate.inputActionEpilogue();
|
||||
await barrier.waitFor();
|
||||
this._signalBarriers.delete(barrier);
|
||||
// Resolve in the next task, after all waitForNavigations.
|
||||
@ -306,11 +306,11 @@ export class FrameManager {
|
||||
this._page.emitOnContext(BrowserContext.Events.Request, request);
|
||||
if (route) {
|
||||
const r = new network.Route(request, route);
|
||||
if (this._page._serverRequestInterceptor?.(r, request))
|
||||
if (this._page.serverRequestInterceptor?.(r, request))
|
||||
return;
|
||||
if (this._page._clientRequestInterceptor?.(r, request))
|
||||
if (this._page.clientRequestInterceptor?.(r, request))
|
||||
return;
|
||||
if (this._page._browserContext._requestInterceptor?.(r, request))
|
||||
if (this._page.browserContext._requestInterceptor?.(r, request))
|
||||
return;
|
||||
r.continue({ isFallback: true }).catch(() => {});
|
||||
}
|
||||
@ -563,7 +563,7 @@ export class Frame extends SdkObject {
|
||||
async raceAgainstEvaluationStallingEvents<T>(cb: () => Promise<T>): Promise<T> {
|
||||
if (this._pendingDocument)
|
||||
throw new Error('Frame is currently attempting a navigation');
|
||||
if (this._page._frameManager._openedDialogs.size)
|
||||
if (this._page.frameManager._openedDialogs.size)
|
||||
throw new Error('Open JavaScript dialog prevents evaluation');
|
||||
|
||||
const promise = new ManualPromise<T>();
|
||||
@ -645,9 +645,9 @@ export class Frame extends SdkObject {
|
||||
}
|
||||
|
||||
async goto(metadata: CallMetadata, url: string, options: types.GotoOptions = {}): Promise<network.Response | null> {
|
||||
const constructedNavigationURL = constructURLBasedOnBaseURL(this._page._browserContext._options.baseURL, url);
|
||||
const constructedNavigationURL = constructURLBasedOnBaseURL(this._page.browserContext._options.baseURL, url);
|
||||
const controller = new ProgressController(metadata, this);
|
||||
return controller.run(progress => this._goto(progress, constructedNavigationURL, options), this._page._timeoutSettings.navigationTimeout(options));
|
||||
return controller.run(progress => this._goto(progress, constructedNavigationURL, options), this._page.timeoutSettings.navigationTimeout(options));
|
||||
}
|
||||
|
||||
private async _goto(progress: Progress, url: string, options: types.GotoOptions): Promise<network.Response | null> {
|
||||
@ -670,7 +670,7 @@ export class Frame extends SdkObject {
|
||||
const navigationEvents: NavigationEvent[] = [];
|
||||
const collectNavigations = (arg: NavigationEvent) => navigationEvents.push(arg);
|
||||
this.on(Frame.Events.InternalNavigation, collectNavigations);
|
||||
const navigateResult = await this._page._delegate.navigateFrame(this, url, referer).finally(
|
||||
const navigateResult = await this._page.delegate.navigateFrame(this, url, referer).finally(
|
||||
() => this.off(Frame.Events.InternalNavigation, collectNavigations));
|
||||
|
||||
let event: NavigationEvent;
|
||||
@ -740,7 +740,7 @@ export class Frame extends SdkObject {
|
||||
}
|
||||
|
||||
async frameElement(): Promise<dom.ElementHandle> {
|
||||
return this._page._delegate.getFrameElement(this);
|
||||
return this._page.delegate.getFrameElement(this);
|
||||
}
|
||||
|
||||
_context(world: types.World): Promise<dom.FrameExecutionContext> {
|
||||
@ -792,7 +792,7 @@ export class Frame extends SdkObject {
|
||||
return controller.run(async progress => {
|
||||
progress.log(`waiting for ${this._asLocator(selector)}${state === 'attached' ? '' : ' to be ' + state}`);
|
||||
return await this.waitForSelectorInternal(progress, selector, true, options, scope);
|
||||
}, this._page._timeoutSettings.timeout(options));
|
||||
}, this._page.timeoutSettings.timeout(options));
|
||||
}
|
||||
|
||||
async waitForSelectorInternal(progress: Progress, selector: string, performActionPreChecks: boolean, options: types.WaitForElementOptions, scope?: dom.ElementHandle): Promise<dom.ElementHandle<Element> | null> {
|
||||
@ -916,7 +916,7 @@ export class Frame extends SdkObject {
|
||||
const tag = `--playwright--set--content--${this._id}--${++this._setContentCounter}--`;
|
||||
const context = await this._utilityContext();
|
||||
const lifecyclePromise = new Promise((resolve, reject) => {
|
||||
this._page._frameManager._consoleMessageTags.set(tag, () => {
|
||||
this._page.frameManager._consoleMessageTags.set(tag, () => {
|
||||
// Clear lifecycle right after document.open() - see 'tag' below.
|
||||
this._onClearLifecycle();
|
||||
this._waitForLoadState(progress, waitUntil).then(resolve).catch(reject);
|
||||
@ -931,7 +931,7 @@ export class Frame extends SdkObject {
|
||||
await Promise.all([contentPromise, lifecyclePromise]);
|
||||
return null;
|
||||
});
|
||||
}, this._page._timeoutSettings.navigationTimeout(options));
|
||||
}, this._page.timeoutSettings.navigationTimeout(options));
|
||||
}
|
||||
|
||||
name(): string {
|
||||
@ -976,7 +976,7 @@ export class Frame extends SdkObject {
|
||||
const result = (await context.evaluateHandle(addScriptContent, { content: content!, type })).asElement()!;
|
||||
// Another round trip to the browser to ensure that we receive CSP error messages
|
||||
// (if any) logged asynchronously in a separate task on the content main thread.
|
||||
if (this._page._delegate.cspErrorsAsynchronousForInlineScripts)
|
||||
if (this._page.delegate.cspErrorsAsynchronousForInlineScripts)
|
||||
await context.evaluate(() => true);
|
||||
return result;
|
||||
});
|
||||
@ -1057,7 +1057,7 @@ export class Frame extends SdkObject {
|
||||
let cspMessage: ConsoleMessage | undefined;
|
||||
const actionPromise = func().then(r => result = r).catch(e => error = e);
|
||||
const errorPromise = new Promise<void>(resolve => {
|
||||
listeners.push(eventsHelper.addEventListener(this._page._browserContext, BrowserContext.Events.Console, (message: ConsoleMessage) => {
|
||||
listeners.push(eventsHelper.addEventListener(this._page.browserContext, BrowserContext.Events.Console, (message: ConsoleMessage) => {
|
||||
if (message.page() !== this._page || message.type() !== 'error')
|
||||
return;
|
||||
if (message.text().includes('Content-Security-Policy') || message.text().includes('Content Security Policy')) {
|
||||
@ -1175,7 +1175,7 @@ export class Frame extends SdkObject {
|
||||
async rafrafTimeoutScreenshotElementWithProgress(progress: Progress, selector: string, timeout: number, options: ScreenshotOptions): Promise<Buffer> {
|
||||
return await this._retryWithProgressIfNotConnected(progress, selector, true /* strict */, true /* performActionPreChecks */, async handle => {
|
||||
await handle._frame.rafrafTimeout(timeout);
|
||||
return await this._page._screenshotter.screenshotElement(progress, handle, options);
|
||||
return await this._page.screenshotter.screenshotElement(progress, handle, options);
|
||||
});
|
||||
}
|
||||
|
||||
@ -1183,14 +1183,14 @@ export class Frame extends SdkObject {
|
||||
const controller = new ProgressController(metadata, this);
|
||||
return controller.run(async progress => {
|
||||
return dom.assertDone(await this._retryWithProgressIfNotConnected(progress, selector, options.strict, !options.force /* performActionPreChecks */, handle => handle._click(progress, { ...options, waitAfter: !options.noWaitAfter })));
|
||||
}, this._page._timeoutSettings.timeout(options));
|
||||
}, this._page.timeoutSettings.timeout(options));
|
||||
}
|
||||
|
||||
async dblclick(metadata: CallMetadata, selector: string, options: types.MouseMultiClickOptions & types.PointerActionWaitOptions = {}) {
|
||||
const controller = new ProgressController(metadata, this);
|
||||
return controller.run(async progress => {
|
||||
return dom.assertDone(await this._retryWithProgressIfNotConnected(progress, selector, options.strict, !options.force /* performActionPreChecks */, handle => handle._dblclick(progress, options)));
|
||||
}, this._page._timeoutSettings.timeout(options));
|
||||
}, this._page.timeoutSettings.timeout(options));
|
||||
}
|
||||
|
||||
async dragAndDrop(metadata: CallMetadata, source: string, target: string, options: types.DragActionOptions & types.PointerActionWaitOptions = {}) {
|
||||
@ -1219,37 +1219,37 @@ export class Frame extends SdkObject {
|
||||
timeout: progress.timeUntilDeadline(),
|
||||
});
|
||||
}));
|
||||
}, this._page._timeoutSettings.timeout(options));
|
||||
}, this._page.timeoutSettings.timeout(options));
|
||||
}
|
||||
|
||||
async tap(metadata: CallMetadata, selector: string, options: types.PointerActionWaitOptions) {
|
||||
if (!this._page._browserContext._options.hasTouch)
|
||||
if (!this._page.browserContext._options.hasTouch)
|
||||
throw new Error('The page does not support tap. Use hasTouch context option to enable touch support.');
|
||||
const controller = new ProgressController(metadata, this);
|
||||
return controller.run(async progress => {
|
||||
return dom.assertDone(await this._retryWithProgressIfNotConnected(progress, selector, options.strict, !options.force /* performActionPreChecks */, handle => handle._tap(progress, options)));
|
||||
}, this._page._timeoutSettings.timeout(options));
|
||||
}, this._page.timeoutSettings.timeout(options));
|
||||
}
|
||||
|
||||
async fill(metadata: CallMetadata, selector: string, value: string, options: types.TimeoutOptions & types.StrictOptions & { force?: boolean }) {
|
||||
const controller = new ProgressController(metadata, this);
|
||||
return controller.run(async progress => {
|
||||
return dom.assertDone(await this._retryWithProgressIfNotConnected(progress, selector, options.strict, !options.force /* performActionPreChecks */, handle => handle._fill(progress, value, options)));
|
||||
}, this._page._timeoutSettings.timeout(options));
|
||||
}, this._page.timeoutSettings.timeout(options));
|
||||
}
|
||||
|
||||
async focus(metadata: CallMetadata, selector: string, options: types.TimeoutOptions & types.StrictOptions = {}) {
|
||||
const controller = new ProgressController(metadata, this);
|
||||
await controller.run(async progress => {
|
||||
dom.assertDone(await this._retryWithProgressIfNotConnected(progress, selector, options.strict, true /* performActionPreChecks */, handle => handle._focus(progress)));
|
||||
}, this._page._timeoutSettings.timeout(options));
|
||||
}, this._page.timeoutSettings.timeout(options));
|
||||
}
|
||||
|
||||
async blur(metadata: CallMetadata, selector: string, options: types.TimeoutOptions & types.StrictOptions = {}) {
|
||||
const controller = new ProgressController(metadata, this);
|
||||
await controller.run(async progress => {
|
||||
dom.assertDone(await this._retryWithProgressIfNotConnected(progress, selector, options.strict, true /* performActionPreChecks */, handle => handle._blur(progress)));
|
||||
}, this._page._timeoutSettings.timeout(options));
|
||||
}, this._page.timeoutSettings.timeout(options));
|
||||
}
|
||||
|
||||
async textContent(metadata: CallMetadata, selector: string, options: types.QueryOnSelectorOptions = {}, scope?: dom.ElementHandle): Promise<string | null> {
|
||||
@ -1314,7 +1314,7 @@ export class Frame extends SdkObject {
|
||||
return controller.run(async progress => {
|
||||
progress.log(` checking visibility of ${this._asLocator(selector)}`);
|
||||
return await this.isVisibleInternal(selector, options, scope);
|
||||
}, this._page._timeoutSettings.timeout({}));
|
||||
}, this._page.timeoutSettings.timeout({}));
|
||||
}
|
||||
|
||||
async isVisibleInternal(selector: string, options: types.StrictOptions = {}, scope?: dom.ElementHandle): Promise<boolean> {
|
||||
@ -1358,14 +1358,14 @@ export class Frame extends SdkObject {
|
||||
const controller = new ProgressController(metadata, this);
|
||||
return controller.run(async progress => {
|
||||
return dom.assertDone(await this._retryWithProgressIfNotConnected(progress, selector, options.strict, !options.force /* performActionPreChecks */, handle => handle._hover(progress, options)));
|
||||
}, this._page._timeoutSettings.timeout(options));
|
||||
}, this._page.timeoutSettings.timeout(options));
|
||||
}
|
||||
|
||||
async selectOption(metadata: CallMetadata, selector: string, elements: dom.ElementHandle[], values: types.SelectOption[], options: types.CommonActionOptions = {}): Promise<string[]> {
|
||||
const controller = new ProgressController(metadata, this);
|
||||
return controller.run(async progress => {
|
||||
return await this._retryWithProgressIfNotConnected(progress, selector, options.strict, !options.force /* performActionPreChecks */, handle => handle._selectOption(progress, elements, values, options));
|
||||
}, this._page._timeoutSettings.timeout(options));
|
||||
}, this._page.timeoutSettings.timeout(options));
|
||||
}
|
||||
|
||||
async setInputFiles(metadata: CallMetadata, selector: string, params: channels.FrameSetInputFilesParams): Promise<channels.FrameSetInputFilesResult> {
|
||||
@ -1373,35 +1373,35 @@ export class Frame extends SdkObject {
|
||||
const controller = new ProgressController(metadata, this);
|
||||
return controller.run(async progress => {
|
||||
return dom.assertDone(await this._retryWithProgressIfNotConnected(progress, selector, params.strict, true /* performActionPreChecks */, handle => handle._setInputFiles(progress, inputFileItems)));
|
||||
}, this._page._timeoutSettings.timeout(params));
|
||||
}, this._page.timeoutSettings.timeout(params));
|
||||
}
|
||||
|
||||
async type(metadata: CallMetadata, selector: string, text: string, options: { delay?: number } & types.TimeoutOptions & types.StrictOptions = {}) {
|
||||
const controller = new ProgressController(metadata, this);
|
||||
return controller.run(async progress => {
|
||||
return dom.assertDone(await this._retryWithProgressIfNotConnected(progress, selector, options.strict, true /* performActionPreChecks */, handle => handle._type(progress, text, options)));
|
||||
}, this._page._timeoutSettings.timeout(options));
|
||||
}, this._page.timeoutSettings.timeout(options));
|
||||
}
|
||||
|
||||
async press(metadata: CallMetadata, selector: string, key: string, options: { delay?: number, noWaitAfter?: boolean } & types.TimeoutOptions & types.StrictOptions = {}) {
|
||||
const controller = new ProgressController(metadata, this);
|
||||
return controller.run(async progress => {
|
||||
return dom.assertDone(await this._retryWithProgressIfNotConnected(progress, selector, options.strict, true /* performActionPreChecks */, handle => handle._press(progress, key, options)));
|
||||
}, this._page._timeoutSettings.timeout(options));
|
||||
}, this._page.timeoutSettings.timeout(options));
|
||||
}
|
||||
|
||||
async check(metadata: CallMetadata, selector: string, options: types.PointerActionWaitOptions = {}) {
|
||||
const controller = new ProgressController(metadata, this);
|
||||
return controller.run(async progress => {
|
||||
return dom.assertDone(await this._retryWithProgressIfNotConnected(progress, selector, options.strict, !options.force /* performActionPreChecks */, handle => handle._setChecked(progress, true, options)));
|
||||
}, this._page._timeoutSettings.timeout(options));
|
||||
}, this._page.timeoutSettings.timeout(options));
|
||||
}
|
||||
|
||||
async uncheck(metadata: CallMetadata, selector: string, options: types.PointerActionWaitOptions = {}) {
|
||||
const controller = new ProgressController(metadata, this);
|
||||
return controller.run(async progress => {
|
||||
return dom.assertDone(await this._retryWithProgressIfNotConnected(progress, selector, options.strict, !options.force /* performActionPreChecks */, handle => handle._setChecked(progress, false, options)));
|
||||
}, this._page._timeoutSettings.timeout(options));
|
||||
}, this._page.timeoutSettings.timeout(options));
|
||||
}
|
||||
|
||||
async waitForTimeout(metadata: CallMetadata, timeout: number) {
|
||||
@ -1415,7 +1415,7 @@ export class Frame extends SdkObject {
|
||||
const controller = new ProgressController(metadata, this);
|
||||
return controller.run(async progress => {
|
||||
return await this._retryWithProgressIfNotConnected(progress, selector, true /* strict */, true /* performActionPreChecks */, handle => handle.ariaSnapshot(options));
|
||||
}, this._page._timeoutSettings.timeout(options));
|
||||
}, this._page.timeoutSettings.timeout(options));
|
||||
}
|
||||
|
||||
async expect(metadata: CallMetadata, selector: string, options: FrameExpectParams): Promise<{ matches: boolean, received?: any, log?: string[], timedOut?: boolean }> {
|
||||
@ -1429,7 +1429,7 @@ export class Frame extends SdkObject {
|
||||
private async _expectImpl(metadata: CallMetadata, selector: string, options: FrameExpectParams): Promise<{ matches: boolean, received?: any, log?: string[], timedOut?: boolean }> {
|
||||
const lastIntermediateResult: { received?: any, isSet: boolean } = { isSet: false };
|
||||
try {
|
||||
let timeout = this._page._timeoutSettings.timeout(options);
|
||||
let timeout = this._page.timeoutSettings.timeout(options);
|
||||
const start = timeout > 0 ? monotonicTime() : 0;
|
||||
|
||||
// Step 1: perform locator handlers checkpoint with a specified timeout.
|
||||
@ -1581,7 +1581,7 @@ export class Frame extends SdkObject {
|
||||
progress.cleanupWhenAborted(() => handle.evaluate(h => h.abort()).catch(() => {}));
|
||||
return handle.evaluateHandle(h => h.result);
|
||||
});
|
||||
}, this._page._timeoutSettings.timeout(options));
|
||||
}, this._page.timeoutSettings.timeout(options));
|
||||
}
|
||||
|
||||
async waitForFunctionValueInUtility<R>(progress: Progress, pageFunction: js.Func1<any, R>) {
|
||||
@ -1656,7 +1656,7 @@ export class Frame extends SdkObject {
|
||||
return value!;
|
||||
});
|
||||
return scope ? scope._context._raceAgainstContextDestroyed(promise) : promise;
|
||||
}, this._page._timeoutSettings.timeout(options));
|
||||
}, this._page.timeoutSettings.timeout(options));
|
||||
}
|
||||
|
||||
private _setContext(world: types.World, context: dom.FrameExecutionContext | null) {
|
||||
|
||||
@ -322,7 +322,7 @@ export class Touchscreen {
|
||||
async tap(x: number, y: number, metadata?: CallMetadata) {
|
||||
if (metadata)
|
||||
metadata.point = { x, y };
|
||||
if (!this._page._browserContext._options.hasTouch)
|
||||
if (!this._page.browserContext._options.hasTouch)
|
||||
throw new Error('hasTouch must be enabled on the browser context before using the touchscreen.');
|
||||
await this._raw.tap(x, y, this._page.keyboard._modifiers());
|
||||
}
|
||||
|
||||
@ -75,7 +75,7 @@ export async function launchApp(browserType: BrowserType, options: {
|
||||
|
||||
async function installAppIcon(page: Page) {
|
||||
const icon = await fs.promises.readFile(require.resolve('./chromium/appIcon.png'));
|
||||
const crPage = page._delegate as CRPage;
|
||||
const crPage = page.delegate as CRPage;
|
||||
await crPage._mainFrameSession._client.send('Browser.setDockTile', {
|
||||
image: icon.toString('base64')
|
||||
});
|
||||
|
||||
@ -144,29 +144,28 @@ export class Page extends SdkObject {
|
||||
private _eventsToEmitAfterInitialized: { event: string | symbol, args: any[] }[] = [];
|
||||
private _crashed = false;
|
||||
readonly openScope = new LongStandingScope();
|
||||
readonly _browserContext: BrowserContext;
|
||||
readonly browserContext: BrowserContext;
|
||||
readonly keyboard: input.Keyboard;
|
||||
readonly mouse: input.Mouse;
|
||||
readonly touchscreen: input.Touchscreen;
|
||||
readonly _timeoutSettings: TimeoutSettings;
|
||||
readonly _delegate: PageDelegate;
|
||||
_emulatedSize: EmulatedSize | undefined;
|
||||
readonly timeoutSettings: TimeoutSettings;
|
||||
readonly delegate: PageDelegate;
|
||||
private _emulatedSize: EmulatedSize | undefined;
|
||||
private _extraHTTPHeaders: types.HeadersArray | undefined;
|
||||
private _emulatedMedia: Partial<EmulatedMedia> = {};
|
||||
private _interceptFileChooser = false;
|
||||
private readonly _pageBindings = new Map<string, PageBinding>();
|
||||
initScripts: InitScript[] = [];
|
||||
readonly _screenshotter: Screenshotter;
|
||||
readonly _frameManager: frames.FrameManager;
|
||||
readonly screenshotter: Screenshotter;
|
||||
readonly frameManager: frames.FrameManager;
|
||||
readonly accessibility: accessibility.Accessibility;
|
||||
private _workers = new Map<string, Worker>();
|
||||
readonly pdf: ((options: channels.PagePdfParams) => Promise<Buffer>) | undefined;
|
||||
readonly coverage: any;
|
||||
_clientRequestInterceptor: network.RouteHandler | undefined;
|
||||
_serverRequestInterceptor: network.RouteHandler | undefined;
|
||||
_ownedContext: BrowserContext | undefined;
|
||||
_video: Artifact | null = null;
|
||||
_opener: Page | undefined;
|
||||
clientRequestInterceptor: network.RouteHandler | undefined;
|
||||
serverRequestInterceptor: network.RouteHandler | undefined;
|
||||
video: Artifact | null = null;
|
||||
private _opener: Page | undefined;
|
||||
private _isServerSideOnly = false;
|
||||
private _locatorHandlers = new Map<number, { selector: string, noWaitAfter?: boolean, resolved?: ManualPromise<void> }>();
|
||||
private _lastLocatorHandlerUid = 0;
|
||||
@ -175,20 +174,20 @@ export class Page extends SdkObject {
|
||||
// Aiming at 25 fps by default - each frame is 40ms, but we give some slack with 35ms.
|
||||
// When throttling for tracing, 200ms between frames, except for 10 frames around the action.
|
||||
private _frameThrottler = new FrameThrottler(10, 35, 200);
|
||||
_closeReason: string | undefined;
|
||||
closeReason: string | undefined;
|
||||
|
||||
constructor(delegate: PageDelegate, browserContext: BrowserContext) {
|
||||
super(browserContext, 'page');
|
||||
this.attribution.page = this;
|
||||
this._delegate = delegate;
|
||||
this._browserContext = browserContext;
|
||||
this.delegate = delegate;
|
||||
this.browserContext = browserContext;
|
||||
this.accessibility = new accessibility.Accessibility(delegate.getAccessibilityTree.bind(delegate));
|
||||
this.keyboard = new input.Keyboard(delegate.rawKeyboard);
|
||||
this.mouse = new input.Mouse(delegate.rawMouse, this);
|
||||
this.touchscreen = new input.Touchscreen(delegate.rawTouchscreen, this);
|
||||
this._timeoutSettings = new TimeoutSettings(browserContext._timeoutSettings);
|
||||
this._screenshotter = new Screenshotter(this);
|
||||
this._frameManager = new frames.FrameManager(this);
|
||||
this.timeoutSettings = new TimeoutSettings(browserContext._timeoutSettings);
|
||||
this.screenshotter = new Screenshotter(this);
|
||||
this.frameManager = new frames.FrameManager(this);
|
||||
if (delegate.pdf)
|
||||
this.pdf = delegate.pdf.bind(delegate);
|
||||
this.coverage = delegate.coverage ? delegate.coverage() : null;
|
||||
@ -207,15 +206,15 @@ export class Page extends SdkObject {
|
||||
if (error) {
|
||||
// Initialization error could have happened because of
|
||||
// context/browser closure. Just ignore the page.
|
||||
if (this._browserContext.isClosingOrClosed())
|
||||
if (this.browserContext.isClosingOrClosed())
|
||||
return;
|
||||
this._frameManager.createDummyMainFrameIfNeeded();
|
||||
this.frameManager.createDummyMainFrameIfNeeded();
|
||||
}
|
||||
this._initialized = error || this;
|
||||
this.emitOnContext(contextEvent, this);
|
||||
|
||||
for (const { event, args } of this._eventsToEmitAfterInitialized)
|
||||
this._browserContext.emit(event, ...args);
|
||||
this.browserContext.emit(event, ...args);
|
||||
this._eventsToEmitAfterInitialized = [];
|
||||
|
||||
// It may happen that page initialization finishes after Close event has already been sent,
|
||||
@ -242,7 +241,7 @@ export class Page extends SdkObject {
|
||||
emitOnContext(event: string | symbol, ...args: any[]) {
|
||||
if (this._isServerSideOnly)
|
||||
return;
|
||||
this._browserContext.emit(event, ...args);
|
||||
this.browserContext.emit(event, ...args);
|
||||
}
|
||||
|
||||
emitOnContextOnceInitialized(event: string | symbol, ...args: any[]) {
|
||||
@ -253,7 +252,7 @@ export class Page extends SdkObject {
|
||||
// and dispatch it to the client later, either on the live Page,
|
||||
// or on the "errored" Page.
|
||||
if (this._initialized)
|
||||
this._browserContext.emit(event, ...args);
|
||||
this.browserContext.emit(event, ...args);
|
||||
else
|
||||
this._eventsToEmitAfterInitialized.push({ event, args });
|
||||
}
|
||||
@ -266,7 +265,7 @@ export class Page extends SdkObject {
|
||||
await this._removeExposedBindings();
|
||||
await this._removeInitScripts();
|
||||
await this.setClientRequestInterceptor(undefined);
|
||||
await this._setServerRequestInterceptor(undefined);
|
||||
await this.setServerRequestInterceptor(undefined);
|
||||
await this.setFileChooserIntercepted(false);
|
||||
// Re-navigate once init scripts are gone.
|
||||
await this.mainFrame().goto(metadata, 'about:blank');
|
||||
@ -276,16 +275,16 @@ export class Page extends SdkObject {
|
||||
this._interceptFileChooser = false;
|
||||
|
||||
await Promise.all([
|
||||
this._delegate.updateEmulatedViewportSize(),
|
||||
this._delegate.updateEmulateMedia(),
|
||||
this._delegate.updateFileChooserInterception(),
|
||||
this.delegate.updateEmulatedViewportSize(),
|
||||
this.delegate.updateEmulateMedia(),
|
||||
this.delegate.updateFileChooserInterception(),
|
||||
]);
|
||||
|
||||
await this._delegate.resetForReuse();
|
||||
await this.delegate.resetForReuse();
|
||||
}
|
||||
|
||||
_didClose() {
|
||||
this._frameManager.dispose();
|
||||
this.frameManager.dispose();
|
||||
this._frameThrottler.dispose();
|
||||
assert(this._closedState !== 'closed', 'Page closed twice');
|
||||
this._closedState = 'closed';
|
||||
@ -296,7 +295,7 @@ export class Page extends SdkObject {
|
||||
}
|
||||
|
||||
_didCrash() {
|
||||
this._frameManager.dispose();
|
||||
this.frameManager.dispose();
|
||||
this._frameThrottler.dispose();
|
||||
this.emit(Page.Events.Crash);
|
||||
this._crashed = true;
|
||||
@ -320,42 +319,38 @@ export class Page extends SdkObject {
|
||||
this.emit(Page.Events.FileChooser, fileChooser);
|
||||
}
|
||||
|
||||
context(): BrowserContext {
|
||||
return this._browserContext;
|
||||
}
|
||||
|
||||
opener(): Page | undefined {
|
||||
return this._opener;
|
||||
}
|
||||
|
||||
mainFrame(): frames.Frame {
|
||||
return this._frameManager.mainFrame();
|
||||
return this.frameManager.mainFrame();
|
||||
}
|
||||
|
||||
frames(): frames.Frame[] {
|
||||
return this._frameManager.frames();
|
||||
return this.frameManager.frames();
|
||||
}
|
||||
|
||||
setDefaultNavigationTimeout(timeout: number | undefined) {
|
||||
this._timeoutSettings.setDefaultNavigationTimeout(timeout);
|
||||
this.timeoutSettings.setDefaultNavigationTimeout(timeout);
|
||||
}
|
||||
|
||||
setDefaultTimeout(timeout: number | undefined) {
|
||||
this._timeoutSettings.setDefaultTimeout(timeout);
|
||||
this.timeoutSettings.setDefaultTimeout(timeout);
|
||||
}
|
||||
|
||||
async exposeBinding(name: string, needsHandle: boolean, playwrightBinding: frames.FunctionWithSource) {
|
||||
if (this._pageBindings.has(name))
|
||||
throw new Error(`Function "${name}" has been already registered`);
|
||||
if (this._browserContext._pageBindings.has(name))
|
||||
if (this.browserContext._pageBindings.has(name))
|
||||
throw new Error(`Function "${name}" has been already registered in the browser context`);
|
||||
const binding = new PageBinding(name, playwrightBinding, needsHandle);
|
||||
this._pageBindings.set(name, binding);
|
||||
await this._delegate.addInitScript(binding.initScript);
|
||||
await this.delegate.addInitScript(binding.initScript);
|
||||
await Promise.all(this.frames().map(frame => frame.evaluateExpression(binding.initScript.source).catch(e => {})));
|
||||
}
|
||||
|
||||
async _removeExposedBindings() {
|
||||
private async _removeExposedBindings() {
|
||||
for (const [key, binding] of this._pageBindings) {
|
||||
if (!binding.internal)
|
||||
this._pageBindings.delete(key);
|
||||
@ -364,22 +359,22 @@ export class Page extends SdkObject {
|
||||
|
||||
setExtraHTTPHeaders(headers: types.HeadersArray) {
|
||||
this._extraHTTPHeaders = headers;
|
||||
return this._delegate.updateExtraHTTPHeaders();
|
||||
return this.delegate.updateExtraHTTPHeaders();
|
||||
}
|
||||
|
||||
extraHTTPHeaders(): types.HeadersArray | undefined {
|
||||
return this._extraHTTPHeaders;
|
||||
}
|
||||
|
||||
async _onBindingCalled(payload: string, context: dom.FrameExecutionContext) {
|
||||
async onBindingCalled(payload: string, context: dom.FrameExecutionContext) {
|
||||
if (this._closedState === 'closed')
|
||||
return;
|
||||
await PageBinding.dispatch(this, payload, context);
|
||||
}
|
||||
|
||||
_addConsoleMessage(type: string, args: js.JSHandle[], location: types.ConsoleMessageLocation, text?: string) {
|
||||
addConsoleMessage(type: string, args: js.JSHandle[], location: types.ConsoleMessageLocation, text?: string) {
|
||||
const message = new ConsoleMessage(this, type, text, args, location);
|
||||
const intercepted = this._frameManager.interceptConsoleMessage(message);
|
||||
const intercepted = this.frameManager.interceptConsoleMessage(message);
|
||||
if (intercepted) {
|
||||
args.forEach(arg => arg.dispose());
|
||||
return;
|
||||
@ -395,10 +390,10 @@ export class Page extends SdkObject {
|
||||
const [response] = await Promise.all([
|
||||
// Reload must be a new document, and should not be confused with a stray pushState.
|
||||
this.mainFrame()._waitForNavigation(progress, true /* requiresNewDocument */, options),
|
||||
this._delegate.reload(),
|
||||
this.delegate.reload(),
|
||||
]);
|
||||
return response;
|
||||
}), this._timeoutSettings.navigationTimeout(options));
|
||||
}), this.timeoutSettings.navigationTimeout(options));
|
||||
}
|
||||
|
||||
async goBack(metadata: CallMetadata, options: types.NavigateOptions): Promise<network.Response | null> {
|
||||
@ -411,14 +406,14 @@ export class Page extends SdkObject {
|
||||
error = e;
|
||||
return null;
|
||||
});
|
||||
const result = await this._delegate.goBack();
|
||||
const result = await this.delegate.goBack();
|
||||
if (!result)
|
||||
return null;
|
||||
const response = await waitPromise;
|
||||
if (error)
|
||||
throw error;
|
||||
return response;
|
||||
}), this._timeoutSettings.navigationTimeout(options));
|
||||
}), this.timeoutSettings.navigationTimeout(options));
|
||||
}
|
||||
|
||||
async goForward(metadata: CallMetadata, options: types.NavigateOptions): Promise<network.Response | null> {
|
||||
@ -431,18 +426,18 @@ export class Page extends SdkObject {
|
||||
error = e;
|
||||
return null;
|
||||
});
|
||||
const result = await this._delegate.goForward();
|
||||
const result = await this.delegate.goForward();
|
||||
if (!result)
|
||||
return null;
|
||||
const response = await waitPromise;
|
||||
if (error)
|
||||
throw error;
|
||||
return response;
|
||||
}), this._timeoutSettings.navigationTimeout(options));
|
||||
}), this.timeoutSettings.navigationTimeout(options));
|
||||
}
|
||||
|
||||
requestGC(): Promise<void> {
|
||||
return this._delegate.requestGC();
|
||||
return this.delegate.requestGC();
|
||||
}
|
||||
|
||||
registerLocatorHandler(selector: string, noWaitAfter: boolean | undefined) {
|
||||
@ -477,7 +472,7 @@ export class Page extends SdkObject {
|
||||
private async _performWaitForNavigationCheck(progress: Progress) {
|
||||
if (process.env.PLAYWRIGHT_SKIP_NAVIGATION_CHECK)
|
||||
return;
|
||||
const mainFrame = this._frameManager.mainFrame();
|
||||
const mainFrame = this.frameManager.mainFrame();
|
||||
if (!mainFrame || !mainFrame.pendingDocument())
|
||||
return;
|
||||
const url = mainFrame.pendingDocument()?.request?.url();
|
||||
@ -535,11 +530,11 @@ export class Page extends SdkObject {
|
||||
if (options.contrast !== undefined)
|
||||
this._emulatedMedia.contrast = options.contrast;
|
||||
|
||||
await this._delegate.updateEmulateMedia();
|
||||
await this.delegate.updateEmulateMedia();
|
||||
}
|
||||
|
||||
emulatedMedia(): EmulatedMedia {
|
||||
const contextOptions = this._browserContext._options;
|
||||
const contextOptions = this.browserContext._options;
|
||||
return {
|
||||
media: this._emulatedMedia.media || 'no-override',
|
||||
colorScheme: this._emulatedMedia.colorScheme !== undefined ? this._emulatedMedia.colorScheme : contextOptions.colorScheme ?? 'light',
|
||||
@ -551,47 +546,51 @@ export class Page extends SdkObject {
|
||||
|
||||
async setViewportSize(viewportSize: types.Size) {
|
||||
this._emulatedSize = { viewport: { ...viewportSize }, screen: { ...viewportSize } };
|
||||
await this._delegate.updateEmulatedViewportSize();
|
||||
await this.delegate.updateEmulatedViewportSize();
|
||||
}
|
||||
|
||||
viewportSize(): types.Size | null {
|
||||
return this.emulatedSize()?.viewport || null;
|
||||
}
|
||||
|
||||
setEmulatedSize(emulatedSize: EmulatedSize) {
|
||||
this._emulatedSize = emulatedSize;
|
||||
}
|
||||
|
||||
emulatedSize(): EmulatedSize | null {
|
||||
if (this._emulatedSize)
|
||||
return this._emulatedSize;
|
||||
const contextOptions = this._browserContext._options;
|
||||
const contextOptions = this.browserContext._options;
|
||||
return contextOptions.viewport ? { viewport: contextOptions.viewport, screen: contextOptions.screen || contextOptions.viewport } : null;
|
||||
}
|
||||
|
||||
async bringToFront(): Promise<void> {
|
||||
await this._delegate.bringToFront();
|
||||
await this.delegate.bringToFront();
|
||||
}
|
||||
|
||||
async addInitScript(source: string, name?: string) {
|
||||
const initScript = new InitScript(source, false /* internal */, name);
|
||||
this.initScripts.push(initScript);
|
||||
await this._delegate.addInitScript(initScript);
|
||||
await this.delegate.addInitScript(initScript);
|
||||
}
|
||||
|
||||
async _removeInitScripts() {
|
||||
private async _removeInitScripts() {
|
||||
this.initScripts = this.initScripts.filter(script => script.internal);
|
||||
await this._delegate.removeNonInternalInitScripts();
|
||||
await this.delegate.removeNonInternalInitScripts();
|
||||
}
|
||||
|
||||
needsRequestInterception(): boolean {
|
||||
return !!this._clientRequestInterceptor || !!this._serverRequestInterceptor || !!this._browserContext._requestInterceptor;
|
||||
return !!this.clientRequestInterceptor || !!this.serverRequestInterceptor || !!this.browserContext._requestInterceptor;
|
||||
}
|
||||
|
||||
async setClientRequestInterceptor(handler: network.RouteHandler | undefined): Promise<void> {
|
||||
this._clientRequestInterceptor = handler;
|
||||
await this._delegate.updateRequestInterception();
|
||||
this.clientRequestInterceptor = handler;
|
||||
await this.delegate.updateRequestInterception();
|
||||
}
|
||||
|
||||
async _setServerRequestInterceptor(handler: network.RouteHandler | undefined): Promise<void> {
|
||||
this._serverRequestInterceptor = handler;
|
||||
await this._delegate.updateRequestInterception();
|
||||
async setServerRequestInterceptor(handler: network.RouteHandler | undefined): Promise<void> {
|
||||
this.serverRequestInterceptor = handler;
|
||||
await this.delegate.updateRequestInterception();
|
||||
}
|
||||
|
||||
async expectScreenshot(metadata: CallMetadata, options: ExpectScreenshotOptions = {}): Promise<{ actual?: Buffer, previous?: Buffer, diff?: Buffer, errorMessage?: string, log?: string[] }> {
|
||||
@ -601,7 +600,7 @@ export class Page extends SdkObject {
|
||||
} : async (progress: Progress, timeout: number) => {
|
||||
await this.performActionPreChecks(progress);
|
||||
await this.mainFrame().rafrafTimeout(timeout);
|
||||
return await this._screenshotter.screenshotPage(progress, options || {});
|
||||
return await this.screenshotter.screenshotPage(progress, options || {});
|
||||
};
|
||||
|
||||
const comparator = getComparator('image/png');
|
||||
@ -629,7 +628,7 @@ export class Page extends SdkObject {
|
||||
intermediateResult = { errorMessage: comparatorResult.errorMessage, diff: comparatorResult.diff, actual, previous };
|
||||
return false;
|
||||
};
|
||||
const callTimeout = this._timeoutSettings.timeout(options);
|
||||
const callTimeout = this.timeoutSettings.timeout(options);
|
||||
return controller.run(async progress => {
|
||||
let actual: Buffer | undefined;
|
||||
let previous: Buffer | undefined;
|
||||
@ -699,26 +698,24 @@ export class Page extends SdkObject {
|
||||
async screenshot(metadata: CallMetadata, options: ScreenshotOptions & TimeoutOptions = {}): Promise<Buffer> {
|
||||
const controller = new ProgressController(metadata, this);
|
||||
return controller.run(
|
||||
progress => this._screenshotter.screenshotPage(progress, options),
|
||||
this._timeoutSettings.timeout(options));
|
||||
progress => this.screenshotter.screenshotPage(progress, options),
|
||||
this.timeoutSettings.timeout(options));
|
||||
}
|
||||
|
||||
async close(metadata: CallMetadata, options: { runBeforeUnload?: boolean, reason?: string } = {}) {
|
||||
if (this._closedState === 'closed')
|
||||
return;
|
||||
if (options.reason)
|
||||
this._closeReason = options.reason;
|
||||
this.closeReason = options.reason;
|
||||
const runBeforeUnload = !!options.runBeforeUnload;
|
||||
if (this._closedState !== 'closing') {
|
||||
this._closedState = 'closing';
|
||||
// This might throw if the browser context containing the page closes
|
||||
// while we are trying to close the page.
|
||||
await this._delegate.closePage(runBeforeUnload).catch(e => debugLogger.log('error', e));
|
||||
await this.delegate.closePage(runBeforeUnload).catch(e => debugLogger.log('error', e));
|
||||
}
|
||||
if (!runBeforeUnload)
|
||||
await this._closedPromise;
|
||||
if (this._ownedContext)
|
||||
await this._ownedContext.close(options);
|
||||
}
|
||||
|
||||
isClosed(): boolean {
|
||||
@ -733,12 +730,12 @@ export class Page extends SdkObject {
|
||||
return this._closedState !== 'open' || this._crashed;
|
||||
}
|
||||
|
||||
_addWorker(workerId: string, worker: Worker) {
|
||||
addWorker(workerId: string, worker: Worker) {
|
||||
this._workers.set(workerId, worker);
|
||||
this.emit(Page.Events.Worker, worker);
|
||||
}
|
||||
|
||||
_removeWorker(workerId: string) {
|
||||
removeWorker(workerId: string) {
|
||||
const worker = this._workers.get(workerId);
|
||||
if (!worker)
|
||||
return;
|
||||
@ -746,7 +743,7 @@ export class Page extends SdkObject {
|
||||
this._workers.delete(workerId);
|
||||
}
|
||||
|
||||
_clearWorkers() {
|
||||
clearWorkers() {
|
||||
for (const [workerId, worker] of this._workers) {
|
||||
worker.didClose();
|
||||
this._workers.delete(workerId);
|
||||
@ -755,7 +752,7 @@ export class Page extends SdkObject {
|
||||
|
||||
async setFileChooserIntercepted(enabled: boolean): Promise<void> {
|
||||
this._interceptFileChooser = enabled;
|
||||
await this._delegate.updateFileChooserInterception();
|
||||
await this.delegate.updateFileChooserInterception();
|
||||
}
|
||||
|
||||
fileChooserIntercepted() {
|
||||
@ -766,20 +763,20 @@ export class Page extends SdkObject {
|
||||
this.emit(Page.Events.InternalFrameNavigatedToNewDocument, frame);
|
||||
const origin = frame.origin();
|
||||
if (origin)
|
||||
this._browserContext.addVisitedOrigin(origin);
|
||||
this.browserContext.addVisitedOrigin(origin);
|
||||
}
|
||||
|
||||
allInitScripts() {
|
||||
const bindings = [...this._browserContext._pageBindings.values(), ...this._pageBindings.values()];
|
||||
return [kUtilityInitScript, ...bindings.map(binding => binding.initScript), ...this._browserContext.initScripts, ...this.initScripts];
|
||||
const bindings = [...this.browserContext._pageBindings.values(), ...this._pageBindings.values()];
|
||||
return [kUtilityInitScript, ...bindings.map(binding => binding.initScript), ...this.browserContext.initScripts, ...this.initScripts];
|
||||
}
|
||||
|
||||
getBinding(name: string) {
|
||||
return this._pageBindings.get(name) || this._browserContext._pageBindings.get(name);
|
||||
return this._pageBindings.get(name) || this.browserContext._pageBindings.get(name);
|
||||
}
|
||||
|
||||
setScreencastOptions(options: { width: number, height: number, quality: number } | null) {
|
||||
this._delegate.setScreencastOptions(options).catch(e => debugLogger.log('error', e));
|
||||
this.delegate.setScreencastOptions(options).catch(e => debugLogger.log('error', e));
|
||||
this._frameThrottler.setThrottlingEnabled(!!options);
|
||||
}
|
||||
|
||||
@ -817,32 +814,28 @@ export class Worker extends SdkObject {
|
||||
Close: 'close',
|
||||
};
|
||||
|
||||
private _url: string;
|
||||
readonly url: string;
|
||||
private _executionContextPromise: Promise<js.ExecutionContext>;
|
||||
private _executionContextCallback: (value: js.ExecutionContext) => void;
|
||||
_existingExecutionContext: js.ExecutionContext | null = null;
|
||||
existingExecutionContext: js.ExecutionContext | null = null;
|
||||
readonly openScope = new LongStandingScope();
|
||||
|
||||
constructor(parent: SdkObject, url: string) {
|
||||
super(parent, 'worker');
|
||||
this._url = url;
|
||||
this.url = url;
|
||||
this._executionContextCallback = () => {};
|
||||
this._executionContextPromise = new Promise(x => this._executionContextCallback = x);
|
||||
}
|
||||
|
||||
_createExecutionContext(delegate: js.ExecutionContextDelegate) {
|
||||
this._existingExecutionContext = new js.ExecutionContext(this, delegate, 'worker');
|
||||
this._executionContextCallback(this._existingExecutionContext);
|
||||
return this._existingExecutionContext;
|
||||
}
|
||||
|
||||
url(): string {
|
||||
return this._url;
|
||||
createExecutionContext(delegate: js.ExecutionContextDelegate) {
|
||||
this.existingExecutionContext = new js.ExecutionContext(this, delegate, 'worker');
|
||||
this._executionContextCallback(this.existingExecutionContext);
|
||||
return this.existingExecutionContext;
|
||||
}
|
||||
|
||||
didClose() {
|
||||
if (this._existingExecutionContext)
|
||||
this._existingExecutionContext.contextDestroyed('Worker was closed');
|
||||
if (this.existingExecutionContext)
|
||||
this.existingExecutionContext.contextDestroyed('Worker was closed');
|
||||
this.emit(Worker.Events.Close, this);
|
||||
this.openScope.close(new Error('Worker closed'));
|
||||
}
|
||||
@ -882,12 +875,12 @@ export class PageBinding {
|
||||
let result: any;
|
||||
if (binding.needsHandle) {
|
||||
const handle = await context.evaluateExpressionHandle(`arg => ${js.accessUtilityScript()}.takeBindingHandle(arg)`, { isFunction: true }, { name, seq }).catch(e => null);
|
||||
result = await binding.playwrightFunction({ frame: context.frame, page, context: page._browserContext }, handle);
|
||||
result = await binding.playwrightFunction({ frame: context.frame, page, context: page.browserContext }, handle);
|
||||
} else {
|
||||
if (!Array.isArray(serializedArgs))
|
||||
throw new Error(`serializedArgs is not an array. This can happen when Array.prototype.toJSON is defined incorrectly`);
|
||||
const args = serializedArgs!.map(a => parseEvaluationResultValue(a));
|
||||
result = await binding.playwrightFunction({ frame: context.frame, page, context: page._browserContext }, ...args);
|
||||
result = await binding.playwrightFunction({ frame: context.frame, page, context: page.browserContext }, ...args);
|
||||
}
|
||||
context.evaluateExpressionHandle(`arg => ${js.accessUtilityScript()}.deliverBindingResult(arg)`, { isFunction: true }, { name, seq, result }).catch(e => debugLogger.log('error', e));
|
||||
} catch (error) {
|
||||
|
||||
@ -57,13 +57,13 @@ export class RecorderApp extends EventEmitter implements IRecorderApp {
|
||||
}
|
||||
|
||||
async close() {
|
||||
await this._page.context().close({ reason: 'Recorder window closed' });
|
||||
await this._page.browserContext.close({ reason: 'Recorder window closed' });
|
||||
}
|
||||
|
||||
private async _init() {
|
||||
await syncLocalStorageWithSettings(this._page, 'recorder');
|
||||
|
||||
await this._page._setServerRequestInterceptor(route => {
|
||||
await this._page.setServerRequestInterceptor(route => {
|
||||
if (!route.request().url().startsWith('https://playwright/'))
|
||||
return false;
|
||||
|
||||
@ -86,7 +86,7 @@ export class RecorderApp extends EventEmitter implements IRecorderApp {
|
||||
|
||||
this._page.once('close', () => {
|
||||
this.emit('close');
|
||||
this._page.context().close({ reason: 'Recorder window closed' }).catch(() => {});
|
||||
this._page.browserContext.close({ reason: 'Recorder window closed' }).catch(() => {});
|
||||
});
|
||||
|
||||
const mainFrame = this._page.mainFrame();
|
||||
|
||||
@ -262,7 +262,7 @@ export class Screenshotter {
|
||||
async _preparePageForScreenshot(progress: Progress, frame: Frame, screenshotStyle: string | undefined, hideCaret: boolean, disableAnimations: boolean) {
|
||||
if (disableAnimations)
|
||||
progress.log(' disabled all CSS animations');
|
||||
const syncAnimations = this._page._delegate.shouldToggleStyleSheetToSyncAnimations();
|
||||
const syncAnimations = this._page.delegate.shouldToggleStyleSheetToSyncAnimations();
|
||||
await this._page.safeNonStallingEvaluateInAllFrames('(' + inPagePrepareForScreenshots.toString() + `)(${JSON.stringify(screenshotStyle)}, ${hideCaret}, ${disableAnimations}, ${syncAnimations})`, 'utility');
|
||||
if (!process.env.PW_TEST_SCREENSHOT_NO_FONTS_READY) {
|
||||
progress.log('waiting for fonts to load...');
|
||||
@ -308,8 +308,8 @@ export class Screenshotter {
|
||||
progress.throwIfAborted(); // Screenshotting is expensive - avoid extra work.
|
||||
const shouldSetDefaultBackground = options.omitBackground && format === 'png';
|
||||
if (shouldSetDefaultBackground) {
|
||||
await this._page._delegate.setBackgroundColor({ r: 0, g: 0, b: 0, a: 0 });
|
||||
progress.cleanupWhenAborted(() => this._page._delegate.setBackgroundColor());
|
||||
await this._page.delegate.setBackgroundColor({ r: 0, g: 0, b: 0, a: 0 });
|
||||
progress.cleanupWhenAborted(() => this._page.delegate.setBackgroundColor());
|
||||
}
|
||||
progress.throwIfAborted(); // Avoid extra work.
|
||||
|
||||
@ -317,14 +317,14 @@ export class Screenshotter {
|
||||
progress.throwIfAborted(); // Avoid extra work.
|
||||
|
||||
const quality = format === 'jpeg' ? options.quality ?? 80 : undefined;
|
||||
const buffer = await this._page._delegate.takeScreenshot(progress, format, documentRect, viewportRect, quality, fitsViewport, options.scale || 'device');
|
||||
const buffer = await this._page.delegate.takeScreenshot(progress, format, documentRect, viewportRect, quality, fitsViewport, options.scale || 'device');
|
||||
progress.throwIfAborted(); // Avoid restoring after failure - should be done by cleanup.
|
||||
|
||||
await cleanupHighlight();
|
||||
progress.throwIfAborted(); // Avoid restoring after failure - should be done by cleanup.
|
||||
|
||||
if (shouldSetDefaultBackground)
|
||||
await this._page._delegate.setBackgroundColor();
|
||||
await this._page.delegate.setBackgroundColor();
|
||||
progress.throwIfAborted(); // Avoid side effects.
|
||||
if ((options as any).__testHookAfterScreenshot)
|
||||
await (options as any).__testHookAfterScreenshot();
|
||||
|
||||
@ -17,7 +17,7 @@
|
||||
|
||||
import { assert } from '../../utils';
|
||||
import { Browser } from '../browser';
|
||||
import { BrowserContext, assertBrowserContextIsNotOwned, verifyGeolocation } from '../browserContext';
|
||||
import { BrowserContext, verifyGeolocation } from '../browserContext';
|
||||
import * as network from '../network';
|
||||
import { WKConnection, WKSession, kPageProxyMessageReceived } from './wkConnection';
|
||||
import { WKPage } from './wkPage';
|
||||
@ -121,7 +121,7 @@ export class WKBrowser extends Browser {
|
||||
// TODO: this is racy, because download might be unrelated any navigation, and we will
|
||||
// abort navigation that is still running. We should be able to fix this by
|
||||
// instrumenting policy decision start/proceed/cancel.
|
||||
page._page._frameManager.frameAbortedNavigation(payload.frameId, 'Download is starting');
|
||||
page._page.frameManager.frameAbortedNavigation(payload.frameId, 'Download is starting');
|
||||
let originPage = page._page.initializedOrUndefined();
|
||||
// If it's a new window download, report it on the opener page.
|
||||
if (!originPage) {
|
||||
@ -245,7 +245,6 @@ export class WKBrowserContext extends BrowserContext {
|
||||
}
|
||||
|
||||
override async doCreateNewPage(): Promise<Page> {
|
||||
assertBrowserContextIsNotOwned(this);
|
||||
const { pageProxyId } = await this._browser._browserSession.send('Playwright.createPage', { browserContextId: this._browserContextId });
|
||||
return this._browser._wkPages.get(pageProxyId)!._page;
|
||||
}
|
||||
@ -274,11 +273,11 @@ export class WKBrowserContext extends BrowserContext {
|
||||
}
|
||||
|
||||
async doGrantPermissions(origin: string, permissions: string[]) {
|
||||
await Promise.all(this.pages().map(page => (page._delegate as WKPage)._grantPermissions(origin, permissions)));
|
||||
await Promise.all(this.pages().map(page => (page.delegate as WKPage)._grantPermissions(origin, permissions)));
|
||||
}
|
||||
|
||||
async doClearPermissions() {
|
||||
await Promise.all(this.pages().map(page => (page._delegate as WKPage)._clearPermissions()));
|
||||
await Promise.all(this.pages().map(page => (page.delegate as WKPage)._clearPermissions()));
|
||||
}
|
||||
|
||||
async setGeolocation(geolocation?: types.Geolocation): Promise<void> {
|
||||
@ -291,40 +290,40 @@ export class WKBrowserContext extends BrowserContext {
|
||||
async setExtraHTTPHeaders(headers: types.HeadersArray): Promise<void> {
|
||||
this._options.extraHTTPHeaders = headers;
|
||||
for (const page of this.pages())
|
||||
await (page._delegate as WKPage).updateExtraHTTPHeaders();
|
||||
await (page.delegate as WKPage).updateExtraHTTPHeaders();
|
||||
}
|
||||
|
||||
async setUserAgent(userAgent: string | undefined): Promise<void> {
|
||||
this._options.userAgent = userAgent;
|
||||
for (const page of this.pages())
|
||||
await (page._delegate as WKPage).updateUserAgent();
|
||||
await (page.delegate as WKPage).updateUserAgent();
|
||||
}
|
||||
|
||||
async setOffline(offline: boolean): Promise<void> {
|
||||
this._options.offline = offline;
|
||||
for (const page of this.pages())
|
||||
await (page._delegate as WKPage).updateOffline();
|
||||
await (page.delegate as WKPage).updateOffline();
|
||||
}
|
||||
|
||||
async doSetHTTPCredentials(httpCredentials?: types.Credentials): Promise<void> {
|
||||
this._options.httpCredentials = httpCredentials;
|
||||
for (const page of this.pages())
|
||||
await (page._delegate as WKPage).updateHttpCredentials();
|
||||
await (page.delegate as WKPage).updateHttpCredentials();
|
||||
}
|
||||
|
||||
async doAddInitScript(initScript: InitScript) {
|
||||
for (const page of this.pages())
|
||||
await (page._delegate as WKPage)._updateBootstrapScript();
|
||||
await (page.delegate as WKPage)._updateBootstrapScript();
|
||||
}
|
||||
|
||||
async doRemoveNonInternalInitScripts() {
|
||||
for (const page of this.pages())
|
||||
await (page._delegate as WKPage)._updateBootstrapScript();
|
||||
await (page.delegate as WKPage)._updateBootstrapScript();
|
||||
}
|
||||
|
||||
async doUpdateRequestInterception(): Promise<void> {
|
||||
for (const page of this.pages())
|
||||
await (page._delegate as WKPage).updateRequestInterception();
|
||||
await (page.delegate as WKPage).updateRequestInterception();
|
||||
}
|
||||
|
||||
onClosePersistent() {}
|
||||
|
||||
@ -152,7 +152,7 @@ export class RawMouseImpl implements input.RawMouse {
|
||||
}
|
||||
|
||||
async wheel(x: number, y: number, buttons: Set<types.MouseButton>, modifiers: Set<types.KeyboardModifier>, deltaX: number, deltaY: number): Promise<void> {
|
||||
if (this._page?._browserContext._options.isMobile)
|
||||
if (this._page?.browserContext._options.isMobile)
|
||||
throw new Error('Mouse wheel is not supported in mobile WebKit');
|
||||
await this._session!.send('Page.updateScrollingState');
|
||||
// Wheel events hit the compositor first, so wait one frame for it to be synced.
|
||||
|
||||
@ -57,7 +57,7 @@ export class WKInterceptableRequest {
|
||||
this._wallTime = event.walltime * 1000;
|
||||
if (event.request.postData)
|
||||
postDataBuffer = Buffer.from(event.request.postData, 'base64');
|
||||
this.request = new network.Request(frame._page._browserContext, frame, null, redirectedFrom?.request || null, documentId, event.request.url,
|
||||
this.request = new network.Request(frame._page.browserContext, frame, null, redirectedFrom?.request || null, documentId, event.request.url,
|
||||
resourceType, event.request.method, postDataBuffer, headersObjectToArray(event.request.headers));
|
||||
}
|
||||
|
||||
|
||||
@ -109,12 +109,12 @@ export class WKPage implements PageDelegate {
|
||||
const viewportSize = helper.getViewportSizeFromWindowFeatures(opener._nextWindowOpenPopupFeatures);
|
||||
opener._nextWindowOpenPopupFeatures = undefined;
|
||||
if (viewportSize)
|
||||
this._page._emulatedSize = { viewport: viewportSize, screen: viewportSize };
|
||||
this._page.setEmulatedSize({ viewport: viewportSize, screen: viewportSize });
|
||||
}
|
||||
}
|
||||
|
||||
private async _initializePageProxySession() {
|
||||
if (this._page._browserContext.isSettingStorageState())
|
||||
if (this._page.browserContext.isSettingStorageState())
|
||||
return;
|
||||
const promises: Promise<any>[] = [
|
||||
this._pageProxySession.send('Dialog.enable'),
|
||||
@ -187,7 +187,7 @@ export class WKPage implements PageDelegate {
|
||||
promises.push(session.send('Network.setResourceCachingDisabled', { disabled: true }));
|
||||
promises.push(session.send('Network.addInterception', { url: '.*', stage: 'request', isRegex: true }));
|
||||
}
|
||||
if (this._page._browserContext.isSettingStorageState()) {
|
||||
if (this._page.browserContext.isSettingStorageState()) {
|
||||
await Promise.all(promises);
|
||||
return;
|
||||
}
|
||||
@ -290,7 +290,7 @@ export class WKPage implements PageDelegate {
|
||||
let errorText = event.error;
|
||||
if (errorText.includes('cancelled'))
|
||||
errorText += '; maybe frame was detached?';
|
||||
this._page._frameManager.frameAbortedNavigation(this._page.mainFrame()._id, errorText, event.loaderId);
|
||||
this._page.frameManager.frameAbortedNavigation(this._page.mainFrame()._id, errorText, event.loaderId);
|
||||
}
|
||||
|
||||
handleWindowOpen(event: Protocol.Playwright.windowOpenPayload) {
|
||||
@ -368,8 +368,8 @@ export class WKPage implements PageDelegate {
|
||||
eventsHelper.addEventListener(this._session, 'Page.willCheckNavigationPolicy', event => this._onWillCheckNavigationPolicy(event.frameId)),
|
||||
eventsHelper.addEventListener(this._session, 'Page.didCheckNavigationPolicy', event => this._onDidCheckNavigationPolicy(event.frameId, event.cancel)),
|
||||
eventsHelper.addEventListener(this._session, 'Page.frameScheduledNavigation', event => this._onFrameScheduledNavigation(event.frameId, event.delay, event.targetIsCurrentFrame)),
|
||||
eventsHelper.addEventListener(this._session, 'Page.loadEventFired', event => this._page._frameManager.frameLifecycleEvent(event.frameId, 'load')),
|
||||
eventsHelper.addEventListener(this._session, 'Page.domContentEventFired', event => this._page._frameManager.frameLifecycleEvent(event.frameId, 'domcontentloaded')),
|
||||
eventsHelper.addEventListener(this._session, 'Page.loadEventFired', event => this._page.frameManager.frameLifecycleEvent(event.frameId, 'load')),
|
||||
eventsHelper.addEventListener(this._session, 'Page.domContentEventFired', event => this._page.frameManager.frameLifecycleEvent(event.frameId, 'domcontentloaded')),
|
||||
eventsHelper.addEventListener(this._session, 'Runtime.executionContextCreated', event => this._onExecutionContextCreated(event.context)),
|
||||
eventsHelper.addEventListener(this._session, 'Runtime.bindingCalled', event => this._onBindingCalled(event.contextId, event.argument)),
|
||||
eventsHelper.addEventListener(this._session, 'Console.messageAdded', event => this._onConsoleMessage(event)),
|
||||
@ -381,13 +381,13 @@ export class WKPage implements PageDelegate {
|
||||
eventsHelper.addEventListener(this._session, 'Network.responseReceived', e => this._onResponseReceived(this._session, e)),
|
||||
eventsHelper.addEventListener(this._session, 'Network.loadingFinished', e => this._onLoadingFinished(e)),
|
||||
eventsHelper.addEventListener(this._session, 'Network.loadingFailed', e => this._onLoadingFailed(this._session, e)),
|
||||
eventsHelper.addEventListener(this._session, 'Network.webSocketCreated', e => this._page._frameManager.onWebSocketCreated(e.requestId, e.url)),
|
||||
eventsHelper.addEventListener(this._session, 'Network.webSocketWillSendHandshakeRequest', e => this._page._frameManager.onWebSocketRequest(e.requestId)),
|
||||
eventsHelper.addEventListener(this._session, 'Network.webSocketHandshakeResponseReceived', e => this._page._frameManager.onWebSocketResponse(e.requestId, e.response.status, e.response.statusText)),
|
||||
eventsHelper.addEventListener(this._session, 'Network.webSocketFrameSent', e => e.response.payloadData && this._page._frameManager.onWebSocketFrameSent(e.requestId, e.response.opcode, e.response.payloadData)),
|
||||
eventsHelper.addEventListener(this._session, 'Network.webSocketFrameReceived', e => e.response.payloadData && this._page._frameManager.webSocketFrameReceived(e.requestId, e.response.opcode, e.response.payloadData)),
|
||||
eventsHelper.addEventListener(this._session, 'Network.webSocketClosed', e => this._page._frameManager.webSocketClosed(e.requestId)),
|
||||
eventsHelper.addEventListener(this._session, 'Network.webSocketFrameError', e => this._page._frameManager.webSocketError(e.requestId, e.errorMessage)),
|
||||
eventsHelper.addEventListener(this._session, 'Network.webSocketCreated', e => this._page.frameManager.onWebSocketCreated(e.requestId, e.url)),
|
||||
eventsHelper.addEventListener(this._session, 'Network.webSocketWillSendHandshakeRequest', e => this._page.frameManager.onWebSocketRequest(e.requestId)),
|
||||
eventsHelper.addEventListener(this._session, 'Network.webSocketHandshakeResponseReceived', e => this._page.frameManager.onWebSocketResponse(e.requestId, e.response.status, e.response.statusText)),
|
||||
eventsHelper.addEventListener(this._session, 'Network.webSocketFrameSent', e => e.response.payloadData && this._page.frameManager.onWebSocketFrameSent(e.requestId, e.response.opcode, e.response.payloadData)),
|
||||
eventsHelper.addEventListener(this._session, 'Network.webSocketFrameReceived', e => e.response.payloadData && this._page.frameManager.webSocketFrameReceived(e.requestId, e.response.opcode, e.response.payloadData)),
|
||||
eventsHelper.addEventListener(this._session, 'Network.webSocketClosed', e => this._page.frameManager.webSocketClosed(e.requestId)),
|
||||
eventsHelper.addEventListener(this._session, 'Network.webSocketFrameError', e => this._page.frameManager.webSocketError(e.requestId, e.errorMessage)),
|
||||
];
|
||||
}
|
||||
private async _updateState<T extends keyof Protocol.CommandParameters>(
|
||||
@ -420,7 +420,7 @@ export class WKPage implements PageDelegate {
|
||||
// one.
|
||||
if (this._provisionalPage)
|
||||
return;
|
||||
this._page._frameManager.frameRequestedNavigation(frameId);
|
||||
this._page.frameManager.frameRequestedNavigation(frameId);
|
||||
}
|
||||
|
||||
private _onDidCheckNavigationPolicy(frameId: string, cancel?: boolean) {
|
||||
@ -430,19 +430,19 @@ export class WKPage implements PageDelegate {
|
||||
// the provisional page. Bail out as we are tracking it.
|
||||
if (this._provisionalPage)
|
||||
return;
|
||||
this._page._frameManager.frameAbortedNavigation(frameId, 'Navigation canceled by policy check');
|
||||
this._page.frameManager.frameAbortedNavigation(frameId, 'Navigation canceled by policy check');
|
||||
}
|
||||
|
||||
private _onFrameScheduledNavigation(frameId: string, delay: number, targetIsCurrentFrame: boolean) {
|
||||
if (targetIsCurrentFrame)
|
||||
this._page._frameManager.frameRequestedNavigation(frameId);
|
||||
this._page.frameManager.frameRequestedNavigation(frameId);
|
||||
}
|
||||
|
||||
private _handleFrameTree(frameTree: Protocol.Page.FrameResourceTree) {
|
||||
this._onFrameAttached(frameTree.frame.id, frameTree.frame.parentId || null);
|
||||
this._onFrameNavigated(frameTree.frame, true);
|
||||
this._page._frameManager.frameLifecycleEvent(frameTree.frame.id, 'domcontentloaded');
|
||||
this._page._frameManager.frameLifecycleEvent(frameTree.frame.id, 'load');
|
||||
this._page.frameManager.frameLifecycleEvent(frameTree.frame.id, 'domcontentloaded');
|
||||
this._page.frameManager.frameLifecycleEvent(frameTree.frame.id, 'load');
|
||||
|
||||
if (!frameTree.childFrames)
|
||||
return;
|
||||
@ -451,26 +451,26 @@ export class WKPage implements PageDelegate {
|
||||
}
|
||||
|
||||
_onFrameAttached(frameId: string, parentFrameId: string | null): frames.Frame {
|
||||
return this._page._frameManager.frameAttached(frameId, parentFrameId);
|
||||
return this._page.frameManager.frameAttached(frameId, parentFrameId);
|
||||
}
|
||||
|
||||
private _onFrameNavigated(framePayload: Protocol.Page.Frame, initial: boolean) {
|
||||
const frame = this._page._frameManager.frame(framePayload.id);
|
||||
const frame = this._page.frameManager.frame(framePayload.id);
|
||||
assert(frame);
|
||||
this._removeContextsForFrame(frame, true);
|
||||
if (!framePayload.parentId)
|
||||
this._workers.clear();
|
||||
this._page._frameManager.frameCommittedNewDocumentNavigation(framePayload.id, framePayload.url, framePayload.name || '', framePayload.loaderId, initial);
|
||||
this._page.frameManager.frameCommittedNewDocumentNavigation(framePayload.id, framePayload.url, framePayload.name || '', framePayload.loaderId, initial);
|
||||
if (!initial)
|
||||
this._firstNonInitialNavigationCommittedFulfill();
|
||||
}
|
||||
|
||||
private _onFrameNavigatedWithinDocument(frameId: string, url: string) {
|
||||
this._page._frameManager.frameCommittedSameDocumentNavigation(frameId, url);
|
||||
this._page.frameManager.frameCommittedSameDocumentNavigation(frameId, url);
|
||||
}
|
||||
|
||||
private _onFrameDetached(frameId: string) {
|
||||
this._page._frameManager.frameDetached(frameId);
|
||||
this._page.frameManager.frameDetached(frameId);
|
||||
}
|
||||
|
||||
private _removeContextsForFrame(frame: frames.Frame, notifyFrame: boolean) {
|
||||
@ -486,7 +486,7 @@ export class WKPage implements PageDelegate {
|
||||
private _onExecutionContextCreated(contextPayload: Protocol.Runtime.ExecutionContextDescription) {
|
||||
if (this._contextIdToContext.has(contextPayload.id))
|
||||
return;
|
||||
const frame = this._page._frameManager.frame(contextPayload.frameId);
|
||||
const frame = this._page.frameManager.frame(contextPayload.frameId);
|
||||
if (!frame)
|
||||
return;
|
||||
const delegate = new WKExecutionContext(this._session, contextPayload.id);
|
||||
@ -506,7 +506,7 @@ export class WKPage implements PageDelegate {
|
||||
if (!(pageOrError instanceof Error)) {
|
||||
const context = this._contextIdToContext.get(contextId);
|
||||
if (context)
|
||||
await this._page._onBindingCalled(argument, context);
|
||||
await this._page.onBindingCalled(argument, context);
|
||||
}
|
||||
}
|
||||
|
||||
@ -587,7 +587,7 @@ export class WKPage implements PageDelegate {
|
||||
location
|
||||
} = this._lastConsoleMessage;
|
||||
for (let i = count; i < event.count; ++i)
|
||||
this._page._addConsoleMessage(derivedType, handles, location, handles.length ? undefined : text);
|
||||
this._page.addConsoleMessage(derivedType, handles, location, handles.length ? undefined : text);
|
||||
this._lastConsoleMessage.count = event.count;
|
||||
}
|
||||
}
|
||||
@ -600,7 +600,7 @@ export class WKPage implements PageDelegate {
|
||||
async (accept: boolean, promptText?: string) => {
|
||||
// TODO: this should actually be a RDP event that notifies about a cancelled navigation attempt.
|
||||
if (event.type === 'beforeunload' && !accept)
|
||||
this._page._frameManager.frameAbortedNavigation(this._page.mainFrame()._id, 'navigation cancelled by beforeunload dialog');
|
||||
this._page.frameManager.frameAbortedNavigation(this._page.mainFrame()._id, 'navigation cancelled by beforeunload dialog');
|
||||
await this._pageProxySession.send('Dialog.handleJavaScriptDialog', { accept, promptText });
|
||||
},
|
||||
event.defaultPrompt));
|
||||
@ -609,7 +609,7 @@ export class WKPage implements PageDelegate {
|
||||
private async _onFileChooserOpened(event: {frameId: Protocol.Network.FrameId, element: Protocol.Runtime.RemoteObject}) {
|
||||
let handle;
|
||||
try {
|
||||
const context = await this._page._frameManager.frame(event.frameId)!._mainContext();
|
||||
const context = await this._page.frameManager.frame(event.frameId)!._mainContext();
|
||||
handle = createHandle(context, event.element).asElement()!;
|
||||
} catch (e) {
|
||||
// During async processing, frame/context may go away. We should not throw.
|
||||
@ -774,7 +774,7 @@ export class WKPage implements PageDelegate {
|
||||
|
||||
private _calculateBootstrapScript(): string {
|
||||
const scripts: string[] = [];
|
||||
if (!this._page.context()._options.isMobile) {
|
||||
if (!this._page.browserContext._options.isMobile) {
|
||||
scripts.push('delete window.orientation');
|
||||
scripts.push('delete window.ondevicemotion');
|
||||
scripts.push('delete window.ondeviceorientation');
|
||||
@ -802,7 +802,7 @@ export class WKPage implements PageDelegate {
|
||||
}
|
||||
|
||||
private _toolbarHeight(): number {
|
||||
if (this._page._browserContext._browser?.options.headful)
|
||||
if (this._page.browserContext._browser?.options.headful)
|
||||
return hostPlatform === 'mac10.15' ? 55 : 59;
|
||||
return 0;
|
||||
}
|
||||
@ -831,8 +831,8 @@ export class WKPage implements PageDelegate {
|
||||
// (see https://github.com/microsoft/playwright/issues/16727).
|
||||
if (process.platform === 'darwin')
|
||||
return;
|
||||
if (!omitDeviceScaleFactor && this._page._browserContext._options.deviceScaleFactor)
|
||||
side = Math.ceil(side * this._page._browserContext._options.deviceScaleFactor);
|
||||
if (!omitDeviceScaleFactor && this._page.browserContext._options.deviceScaleFactor)
|
||||
side = Math.ceil(side * this._page.browserContext._options.deviceScaleFactor);
|
||||
if (side > 32767)
|
||||
throw new Error('Cannot take screenshot larger than 32767 pixels on any dimension');
|
||||
}
|
||||
@ -856,7 +856,7 @@ export class WKPage implements PageDelegate {
|
||||
});
|
||||
if (!nodeInfo.contentFrameId)
|
||||
return null;
|
||||
return this._page._frameManager.frame(nodeInfo.contentFrameId);
|
||||
return this._page.frameManager.frame(nodeInfo.contentFrameId);
|
||||
}
|
||||
|
||||
async getOwnerFrame(handle: dom.ElementHandle): Promise<string | null> {
|
||||
@ -1035,7 +1035,7 @@ export class WKPage implements PageDelegate {
|
||||
redirectedFrom = request;
|
||||
}
|
||||
}
|
||||
const frame = redirectedFrom ? redirectedFrom.request.frame() : this._page._frameManager.frame(event.frameId);
|
||||
const frame = redirectedFrom ? redirectedFrom.request.frame() : this._page.frameManager.frame(event.frameId);
|
||||
// sometimes we get stray network events for detached frames
|
||||
// TODO(einbinder) why?
|
||||
if (!frame)
|
||||
@ -1053,7 +1053,7 @@ export class WKPage implements PageDelegate {
|
||||
request.request.setRawRequestHeaders(null);
|
||||
}
|
||||
this._requestIdToRequest.set(event.requestId, request);
|
||||
this._page._frameManager.requestStarted(request.request, route);
|
||||
this._page.frameManager.requestStarted(request.request, route);
|
||||
}
|
||||
|
||||
private _handleRequestRedirect(request: WKInterceptableRequest, requestId: string, responsePayload: Protocol.Network.Response, timestamp: number) {
|
||||
@ -1064,8 +1064,8 @@ export class WKPage implements PageDelegate {
|
||||
response.setEncodedBodySize(null);
|
||||
response._requestFinished(responsePayload.timing ? helper.secondsToRoundishMillis(timestamp - request._timestamp) : -1);
|
||||
this._requestIdToRequest.delete(requestId);
|
||||
this._page._frameManager.requestReceivedResponse(response);
|
||||
this._page._frameManager.reportRequestFinished(request.request, response);
|
||||
this._page.frameManager.requestReceivedResponse(response);
|
||||
this._page.frameManager.reportRequestFinished(request.request, response);
|
||||
}
|
||||
|
||||
_onRequestIntercepted(session: WKSession, event: Protocol.Network.requestInterceptedPayload) {
|
||||
@ -1095,7 +1095,7 @@ export class WKPage implements PageDelegate {
|
||||
|
||||
this._requestIdToResponseReceivedPayloadEvent.set(event.requestId, event);
|
||||
const response = request.createResponse(event.response);
|
||||
this._page._frameManager.requestReceivedResponse(response);
|
||||
this._page.frameManager.requestReceivedResponse(response);
|
||||
|
||||
if (response.status() === 204 && request.request.isNavigationRequest()) {
|
||||
this._onLoadingFailed(session, {
|
||||
@ -1138,7 +1138,7 @@ export class WKPage implements PageDelegate {
|
||||
|
||||
this._requestIdToResponseReceivedPayloadEvent.delete(event.requestId);
|
||||
this._requestIdToRequest.delete(event.requestId);
|
||||
this._page._frameManager.reportRequestFinished(request.request, response);
|
||||
this._page.frameManager.reportRequestFinished(request.request, response);
|
||||
}
|
||||
|
||||
_onLoadingFailed(session: WKSession, event: Protocol.Network.loadingFailedPayload) {
|
||||
@ -1169,7 +1169,7 @@ export class WKPage implements PageDelegate {
|
||||
}
|
||||
this._requestIdToRequest.delete(event.requestId);
|
||||
request.request._setFailureText(event.errorText);
|
||||
this._page._frameManager.requestFailed(request.request, event.errorText.includes('cancelled'));
|
||||
this._page.frameManager.requestFailed(request.request, event.errorText.includes('cancelled'));
|
||||
}
|
||||
|
||||
async _grantPermissions(origin: string, permissions: string[]) {
|
||||
|
||||
@ -49,7 +49,7 @@ export class WKProvisionalPage {
|
||||
return (payload: any) => {
|
||||
// Pretend that the events happened in the same process.
|
||||
if (payload.frameId)
|
||||
payload.frameId = this._wkPage._page._frameManager.mainFrame()._id;
|
||||
payload.frameId = this._wkPage._page.frameManager.mainFrame()._id;
|
||||
handler(payload);
|
||||
};
|
||||
};
|
||||
|
||||
@ -48,8 +48,8 @@ export class WKWorkers {
|
||||
});
|
||||
});
|
||||
this._workerSessions.set(event.workerId, workerSession);
|
||||
worker._createExecutionContext(new WKExecutionContext(workerSession, undefined));
|
||||
this._page._addWorker(event.workerId, worker);
|
||||
worker.createExecutionContext(new WKExecutionContext(workerSession, undefined));
|
||||
this._page.addWorker(event.workerId, worker);
|
||||
workerSession.on('Console.messageAdded', event => this._onConsoleMessage(worker, event));
|
||||
Promise.all([
|
||||
workerSession.send('Runtime.enable'),
|
||||
@ -57,7 +57,7 @@ export class WKWorkers {
|
||||
session.send('Worker.initialized', { workerId: event.workerId })
|
||||
]).catch(e => {
|
||||
// Worker can go as we are initializing it.
|
||||
this._page._removeWorker(event.workerId);
|
||||
this._page.removeWorker(event.workerId);
|
||||
});
|
||||
}),
|
||||
eventsHelper.addEventListener(session, 'Worker.dispatchMessageFromWorker', (event: Protocol.Worker.dispatchMessageFromWorkerPayload) => {
|
||||
@ -72,13 +72,13 @@ export class WKWorkers {
|
||||
return;
|
||||
workerSession.dispose();
|
||||
this._workerSessions.delete(event.workerId);
|
||||
this._page._removeWorker(event.workerId);
|
||||
this._page.removeWorker(event.workerId);
|
||||
})
|
||||
];
|
||||
}
|
||||
|
||||
clear() {
|
||||
this._page._clearWorkers();
|
||||
this._page.clearWorkers();
|
||||
this._workerSessions.clear();
|
||||
}
|
||||
|
||||
@ -95,13 +95,13 @@ export class WKWorkers {
|
||||
derivedType = 'timeEnd';
|
||||
|
||||
const handles = (parameters || []).map(p => {
|
||||
return createHandle(worker._existingExecutionContext!, p);
|
||||
return createHandle(worker.existingExecutionContext!, p);
|
||||
});
|
||||
const location: types.ConsoleMessageLocation = {
|
||||
url: url || '',
|
||||
lineNumber: (lineNumber || 1) - 1,
|
||||
columnNumber: (columnNumber || 1) - 1
|
||||
};
|
||||
this._page._addConsoleMessage(derivedType, handles, location, handles.length ? undefined : text);
|
||||
this._page.addConsoleMessage(derivedType, handles, location, handles.length ? undefined : text);
|
||||
}
|
||||
}
|
||||
|
||||
@ -142,7 +142,7 @@ export const traceViewerFixtures: Fixtures<TraceViewerFixtures, {}, BaseTestFixt
|
||||
const contextImpls: any[] = [];
|
||||
await use(async (traces: string[], { host, port } = {}) => {
|
||||
const pageImpl = await runTraceViewerApp(traces, browserName, { headless, host, port });
|
||||
const contextImpl = pageImpl.context();
|
||||
const contextImpl = pageImpl.browserContext;
|
||||
const browser = await playwright.chromium.connectOverCDP(contextImpl._browser.options.wsEndpoint);
|
||||
browsers.push(browser);
|
||||
contextImpls.push(contextImpl);
|
||||
|
||||
@ -23,9 +23,9 @@ const test = testBase.extend<{ crash: () => void }, { dummy: string }>({
|
||||
if (browserName === 'chromium')
|
||||
page.goto('chrome://crash').catch(e => {});
|
||||
else if (browserName === 'webkit')
|
||||
toImpl(page)._delegate._session.send('Page.crash', {}).catch(e => {});
|
||||
toImpl(page).delegate._session.send('Page.crash', {}).catch(e => {});
|
||||
else if (browserName === 'firefox')
|
||||
toImpl(page)._delegate._session.send('Page.crash', {}).catch(e => {});
|
||||
toImpl(page).delegate._session.send('Page.crash', {}).catch(e => {});
|
||||
});
|
||||
},
|
||||
// Force a separate worker to avoid messing up with other tests.
|
||||
|
||||
@ -37,9 +37,9 @@ it('should have correct execution contexts @smoke', async ({ page, server }) =>
|
||||
|
||||
function expectContexts(pageImpl, count, browserName) {
|
||||
if (browserName === 'chromium')
|
||||
expect(pageImpl._delegate._mainFrameSession._contextIdToContext.size).toBe(count);
|
||||
expect(pageImpl.delegate._mainFrameSession._contextIdToContext.size).toBe(count);
|
||||
else
|
||||
expect(pageImpl._delegate._contextIdToContext.size).toBe(count);
|
||||
expect(pageImpl.delegate._contextIdToContext.size).toBe(count);
|
||||
}
|
||||
|
||||
it('should dispose context on navigation', async ({ page, server, toImpl, browserName, isElectron }) => {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user