more cleanup
This commit is contained in:
parent
b0dc3efc2d
commit
fc8112f904
|
|
@ -80,9 +80,9 @@ export class BidiPage implements PageDelegate {
|
||||||
|
|
||||||
// Initialize main frame.
|
// Initialize main frame.
|
||||||
// TODO: Wait for first execution context to be created and maybe about:blank navigated.
|
// TODO: Wait for first execution context to be created and maybe about:blank navigated.
|
||||||
this._initialize()
|
this._initialize().then(
|
||||||
.finally(() => this._page.initOpener(this._opener?._page))
|
() => this._page.reportAsNew(this._opener?._page),
|
||||||
.then(() => this._page.reportAsNew(), error => this._page.reportAsNew(error));
|
error => this._page.reportAsNew(this._opener?._page, error));
|
||||||
}
|
}
|
||||||
|
|
||||||
private async _initialize() {
|
private async _initialize() {
|
||||||
|
|
@ -101,10 +101,6 @@ export class BidiPage implements PageDelegate {
|
||||||
return Promise.all(this._page.allInitScripts().map(initScript => this.addInitScript(initScript)));
|
return Promise.all(this._page.allInitScripts().map(initScript => this.addInitScript(initScript)));
|
||||||
}
|
}
|
||||||
|
|
||||||
potentiallyUninitializedPage(): Page {
|
|
||||||
return this._page;
|
|
||||||
}
|
|
||||||
|
|
||||||
didClose() {
|
didClose() {
|
||||||
this._session.dispose();
|
this._session.dispose();
|
||||||
eventsHelper.removeEventListeners(this._sessionListeners);
|
eventsHelper.removeEventListeners(this._sessionListeners);
|
||||||
|
|
|
||||||
|
|
@ -257,7 +257,7 @@ export abstract class BrowserContext extends SdkObject {
|
||||||
}
|
}
|
||||||
|
|
||||||
pages(): Page[] {
|
pages(): Page[] {
|
||||||
return this.possiblyUninitializedPages().filter(page => page.initialized());
|
return this.possiblyUninitializedPages().filter(page => page.initializedOrUndefined());
|
||||||
}
|
}
|
||||||
|
|
||||||
// BrowserContext methods.
|
// BrowserContext methods.
|
||||||
|
|
|
||||||
|
|
@ -259,10 +259,10 @@ export class CRBrowser extends Browser {
|
||||||
}
|
}
|
||||||
page.willBeginDownload();
|
page.willBeginDownload();
|
||||||
|
|
||||||
let originPage = page._page.initialized();
|
let originPage = page._page.initializedOrUndefined();
|
||||||
// If it's a new window download, report it on the opener page.
|
// If it's a new window download, report it on the opener page.
|
||||||
if (!originPage && page._opener)
|
if (!originPage && page._opener)
|
||||||
originPage = page._opener._page.initialized();
|
originPage = page._opener._page.initializedOrUndefined();
|
||||||
if (!originPage)
|
if (!originPage)
|
||||||
return;
|
return;
|
||||||
this._downloadCreated(originPage, payload.guid, payload.url, payload.suggestedFilename);
|
this._downloadCreated(originPage, payload.guid, payload.url, payload.suggestedFilename);
|
||||||
|
|
@ -544,7 +544,7 @@ export class CRBrowserContext extends BrowserContext {
|
||||||
// When persistent context is closed, we do not necessary get Target.detachedFromTarget
|
// When persistent context is closed, we do not necessary get Target.detachedFromTarget
|
||||||
// for all the background pages.
|
// for all the background pages.
|
||||||
for (const [targetId, backgroundPage] of this._browser._backgroundPages.entries()) {
|
for (const [targetId, backgroundPage] of this._browser._backgroundPages.entries()) {
|
||||||
if (backgroundPage._browserContext === this && backgroundPage._page.initialized()) {
|
if (backgroundPage._browserContext === this && backgroundPage._page.initializedOrUndefined()) {
|
||||||
backgroundPage.didClose();
|
backgroundPage.didClose();
|
||||||
this._browser._backgroundPages.delete(targetId);
|
this._browser._backgroundPages.delete(targetId);
|
||||||
}
|
}
|
||||||
|
|
@ -569,7 +569,7 @@ export class CRBrowserContext extends BrowserContext {
|
||||||
backgroundPages(): Page[] {
|
backgroundPages(): Page[] {
|
||||||
const result: Page[] = [];
|
const result: Page[] = [];
|
||||||
for (const backgroundPage of this._browser._backgroundPages.values()) {
|
for (const backgroundPage of this._browser._backgroundPages.values()) {
|
||||||
if (backgroundPage._browserContext === this && backgroundPage._page.initialized())
|
if (backgroundPage._browserContext === this && backgroundPage._page.initializedOrUndefined())
|
||||||
result.push(backgroundPage._page);
|
result.push(backgroundPage._page);
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
|
|
|
||||||
|
|
@ -108,9 +108,9 @@ export class CRPage implements PageDelegate {
|
||||||
}
|
}
|
||||||
|
|
||||||
const createdEvent = this._isBackgroundPage ? CRBrowserContext.CREvents.BackgroundPage : BrowserContext.Events.Page;
|
const createdEvent = this._isBackgroundPage ? CRBrowserContext.CREvents.BackgroundPage : BrowserContext.Events.Page;
|
||||||
this._mainFrameSession._initialize(bits.hasUIWindow)
|
this._mainFrameSession._initialize(bits.hasUIWindow).then(
|
||||||
.finally(() => this._page.initOpener(this._opener?._page))
|
() => this._page.reportAsNew(this._opener?._page, undefined, createdEvent),
|
||||||
.then(() => this._page.reportAsNew(undefined, createdEvent), error => this._page.reportAsNew(error, createdEvent));
|
error => this._page.reportAsNew(this._opener?._page, error, createdEvent));
|
||||||
}
|
}
|
||||||
|
|
||||||
private async _forAllFrameSessions(cb: (frame: FrameSession) => Promise<any>) {
|
private async _forAllFrameSessions(cb: (frame: FrameSession) => Promise<any>) {
|
||||||
|
|
@ -873,7 +873,7 @@ class FrameSession {
|
||||||
}
|
}
|
||||||
|
|
||||||
_willBeginDownload() {
|
_willBeginDownload() {
|
||||||
if (!this._crPage._page.initialized()) {
|
if (!this._crPage._page.initializedOrUndefined()) {
|
||||||
// Resume the page creation with an error. The page will automatically close right
|
// Resume the page creation with an error. The page will automatically close right
|
||||||
// after the download begins.
|
// after the download begins.
|
||||||
this._firstNonInitialNavigationCommittedReject(new Error('Starting new page download'));
|
this._firstNonInitialNavigationCommittedReject(new Error('Starting new page download'));
|
||||||
|
|
|
||||||
|
|
@ -133,7 +133,7 @@ export class BrowserContextDispatcher extends Dispatcher<BrowserContext, channel
|
||||||
const requestDispatcher = RequestDispatcher.from(this, request);
|
const requestDispatcher = RequestDispatcher.from(this, request);
|
||||||
this._dispatchEvent('request', {
|
this._dispatchEvent('request', {
|
||||||
request: requestDispatcher,
|
request: requestDispatcher,
|
||||||
page: PageDispatcher.fromNullable(this, request.frame()?._page.initialized())
|
page: PageDispatcher.fromNullable(this, request.frame()?._page.initializedOrUndefined())
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
this.addObjectListener(BrowserContext.Events.Response, (response: Response) => {
|
this.addObjectListener(BrowserContext.Events.Response, (response: Response) => {
|
||||||
|
|
@ -142,7 +142,7 @@ export class BrowserContextDispatcher extends Dispatcher<BrowserContext, channel
|
||||||
return;
|
return;
|
||||||
this._dispatchEvent('response', {
|
this._dispatchEvent('response', {
|
||||||
response: ResponseDispatcher.from(this, response),
|
response: ResponseDispatcher.from(this, response),
|
||||||
page: PageDispatcher.fromNullable(this, response.frame()?._page.initialized())
|
page: PageDispatcher.fromNullable(this, response.frame()?._page.initializedOrUndefined())
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
this.addObjectListener(BrowserContext.Events.RequestFailed, (request: Request) => {
|
this.addObjectListener(BrowserContext.Events.RequestFailed, (request: Request) => {
|
||||||
|
|
@ -153,7 +153,7 @@ export class BrowserContextDispatcher extends Dispatcher<BrowserContext, channel
|
||||||
request: RequestDispatcher.from(this, request),
|
request: RequestDispatcher.from(this, request),
|
||||||
failureText: request._failureText || undefined,
|
failureText: request._failureText || undefined,
|
||||||
responseEndTiming: request._responseEndTiming,
|
responseEndTiming: request._responseEndTiming,
|
||||||
page: PageDispatcher.fromNullable(this, request.frame()?._page.initialized())
|
page: PageDispatcher.fromNullable(this, request.frame()?._page.initializedOrUndefined())
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
this.addObjectListener(BrowserContext.Events.RequestFinished, ({ request, response }: { request: Request, response: Response | null }) => {
|
this.addObjectListener(BrowserContext.Events.RequestFinished, ({ request, response }: { request: Request, response: Response | null }) => {
|
||||||
|
|
@ -164,13 +164,13 @@ export class BrowserContextDispatcher extends Dispatcher<BrowserContext, channel
|
||||||
request: RequestDispatcher.from(this, request),
|
request: RequestDispatcher.from(this, request),
|
||||||
response: ResponseDispatcher.fromNullable(this, response),
|
response: ResponseDispatcher.fromNullable(this, response),
|
||||||
responseEndTiming: request._responseEndTiming,
|
responseEndTiming: request._responseEndTiming,
|
||||||
page: PageDispatcher.fromNullable(this, request.frame()?._page.initialized()),
|
page: PageDispatcher.fromNullable(this, request.frame()?._page.initializedOrUndefined()),
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private _shouldDispatchNetworkEvent(request: Request, event: channels.BrowserContextUpdateSubscriptionParams['event'] & channels.PageUpdateSubscriptionParams['event']): boolean {
|
private _shouldDispatchNetworkEvent(request: Request, event: channels.BrowserContextUpdateSubscriptionParams['event'] & channels.PageUpdateSubscriptionParams['event']): boolean {
|
||||||
return this._shouldDispatchEvent(request.frame()?._page?.initialized(), event);
|
return this._shouldDispatchEvent(request.frame()?._page?.initializedOrUndefined(), event);
|
||||||
}
|
}
|
||||||
|
|
||||||
private _shouldDispatchEvent(page: Page | undefined, event: channels.BrowserContextUpdateSubscriptionParams['event'] & channels.PageUpdateSubscriptionParams['event']): boolean {
|
private _shouldDispatchEvent(page: Page | undefined, event: channels.BrowserContextUpdateSubscriptionParams['event'] & channels.PageUpdateSubscriptionParams['event']): boolean {
|
||||||
|
|
|
||||||
|
|
@ -24,7 +24,7 @@ export class DialogDispatcher extends Dispatcher<Dialog, channels.DialogChannel,
|
||||||
_type_Dialog = true;
|
_type_Dialog = true;
|
||||||
|
|
||||||
constructor(scope: BrowserContextDispatcher, dialog: Dialog) {
|
constructor(scope: BrowserContextDispatcher, dialog: Dialog) {
|
||||||
const page = PageDispatcher.fromNullable(scope, dialog.page().initialized());
|
const page = PageDispatcher.fromNullable(scope, dialog.page().initializedOrUndefined());
|
||||||
// Prefer scoping to the page, unless we don't have one.
|
// Prefer scoping to the page, unless we don't have one.
|
||||||
super(page || scope, dialog, 'Dialog', {
|
super(page || scope, dialog, 'Dialog', {
|
||||||
page,
|
page,
|
||||||
|
|
|
||||||
|
|
@ -136,14 +136,14 @@ export class FFBrowser extends Browser {
|
||||||
// Abort the navigation that turned into download.
|
// 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.initialized();
|
let originPage = ffPage._page.initializedOrUndefined();
|
||||||
// If it's a new window download, report it on the opener page.
|
// If it's a new window download, report it on the opener page.
|
||||||
if (!originPage) {
|
if (!originPage) {
|
||||||
// Resume the page creation with an error. The page will automatically close right
|
// Resume the page creation with an error. The page will automatically close right
|
||||||
// after the download begins.
|
// after the download begins.
|
||||||
ffPage._markAsError(new Error('Starting new page download'));
|
ffPage._markAsError(new Error('Starting new page download'));
|
||||||
if (ffPage._opener)
|
if (ffPage._opener)
|
||||||
originPage = ffPage._opener._page.initialized();
|
originPage = ffPage._opener._page.initializedOrUndefined();
|
||||||
}
|
}
|
||||||
if (!originPage)
|
if (!originPage)
|
||||||
return;
|
return;
|
||||||
|
|
|
||||||
|
|
@ -48,7 +48,7 @@ export class FFPage implements PageDelegate {
|
||||||
readonly _page: Page;
|
readonly _page: Page;
|
||||||
readonly _networkManager: FFNetworkManager;
|
readonly _networkManager: FFNetworkManager;
|
||||||
readonly _browserContext: FFBrowserContext;
|
readonly _browserContext: FFBrowserContext;
|
||||||
private _initializationFailed = false;
|
private _reportedAsNew = false;
|
||||||
readonly _opener: FFPage | null;
|
readonly _opener: FFPage | null;
|
||||||
private readonly _contextIdToContext: Map<string, dom.FrameExecutionContext>;
|
private readonly _contextIdToContext: Map<string, dom.FrameExecutionContext>;
|
||||||
private _eventListeners: RegisteredListener[];
|
private _eventListeners: RegisteredListener[];
|
||||||
|
|
@ -99,31 +99,23 @@ export class FFPage implements PageDelegate {
|
||||||
eventsHelper.addEventListener(this._session, 'Page.screencastFrame', this._onScreencastFrame.bind(this)),
|
eventsHelper.addEventListener(this._session, 'Page.screencastFrame', this._onScreencastFrame.bind(this)),
|
||||||
|
|
||||||
];
|
];
|
||||||
this._session.once('Page.ready', async () => {
|
this._session.once('Page.ready', () => {
|
||||||
await this._page.initOpener(this._opener?._page);
|
if (this._reportedAsNew)
|
||||||
if (this._initializationFailed)
|
|
||||||
return;
|
return;
|
||||||
this._page.reportAsNew();
|
this._reportedAsNew = true;
|
||||||
|
this._page.reportAsNew(this._opener?._page);
|
||||||
});
|
});
|
||||||
// Ideally, we somehow ensure that utility world is created before Page.ready arrives, but currently it is racy.
|
// Ideally, we somehow ensure that utility world is created before Page.ready arrives, but currently it is racy.
|
||||||
// Therefore, we can end up with an initialized page without utility world, although very unlikely.
|
// Therefore, we can end up with an initialized page without utility world, although very unlikely.
|
||||||
this.addInitScript(new InitScript('', true), UTILITY_WORLD_NAME).catch(e => this._markAsError(e));
|
this.addInitScript(new InitScript('', true), UTILITY_WORLD_NAME).catch(e => this._markAsError(e));
|
||||||
}
|
}
|
||||||
|
|
||||||
potentiallyUninitializedPage(): Page {
|
|
||||||
return this._page;
|
|
||||||
}
|
|
||||||
|
|
||||||
async _markAsError(error: Error) {
|
async _markAsError(error: Error) {
|
||||||
// Same error may be reported twice: channel disconnected and session.send fails.
|
// Same error may be reported twice: channel disconnected and session.send fails.
|
||||||
if (this._initializationFailed)
|
if (this._reportedAsNew)
|
||||||
return;
|
return;
|
||||||
this._initializationFailed = true;
|
this._reportedAsNew = true;
|
||||||
|
this._page.reportAsNew(this._opener?._page, error);
|
||||||
if (!this._page.initialized()) {
|
|
||||||
await this._page.initOpener(this._opener?._page);
|
|
||||||
this._page.reportAsNew(error);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
_onWebSocketCreated(event: Protocol.Page.webSocketCreatedPayload) {
|
_onWebSocketCreated(event: Protocol.Page.webSocketCreatedPayload) {
|
||||||
|
|
|
||||||
|
|
@ -192,15 +192,16 @@ export class Page extends SdkObject {
|
||||||
this.coverage = delegate.coverage ? delegate.coverage() : null;
|
this.coverage = delegate.coverage ? delegate.coverage() : null;
|
||||||
}
|
}
|
||||||
|
|
||||||
async initOpener(opener: Page | undefined) {
|
async reportAsNew(opener: Page | undefined, error: Error | undefined = undefined, contextEvent: string = BrowserContext.Events.Page) {
|
||||||
if (!opener)
|
if (opener) {
|
||||||
return;
|
const openerPageOrError = await opener.waitForInitializedOrError();
|
||||||
const openerPageOrError = await opener.waitForInitializedOrError();
|
if (openerPageOrError instanceof Page && !openerPageOrError.isClosed())
|
||||||
if (openerPageOrError instanceof Page && !openerPageOrError.isClosed())
|
this._opener = openerPageOrError;
|
||||||
this._opener = openerPageOrError;
|
}
|
||||||
|
this._markInitialized(error, contextEvent);
|
||||||
}
|
}
|
||||||
|
|
||||||
reportAsNew(error: Error | undefined = undefined, contextEvent: string = BrowserContext.Events.Page) {
|
private _markInitialized(error: Error | undefined = undefined, contextEvent: string = BrowserContext.Events.Page) {
|
||||||
if (error) {
|
if (error) {
|
||||||
// Initialization error could have happened because of
|
// Initialization error could have happened because of
|
||||||
// context/browser closure. Just ignore the page.
|
// context/browser closure. Just ignore the page.
|
||||||
|
|
@ -228,7 +229,7 @@ export class Page extends SdkObject {
|
||||||
this._initializedPromise.resolve(this._initialized);
|
this._initializedPromise.resolve(this._initialized);
|
||||||
}
|
}
|
||||||
|
|
||||||
initialized(): Page | undefined {
|
initializedOrUndefined(): Page | undefined {
|
||||||
return this._initialized ? this : undefined;
|
return this._initialized ? this : undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -121,14 +121,14 @@ export class WKBrowser extends Browser {
|
||||||
// abort navigation that is still running. We should be able to fix this by
|
// abort navigation that is still running. We should be able to fix this by
|
||||||
// instrumenting policy decision start/proceed/cancel.
|
// 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.initialized();
|
let originPage = page._page.initializedOrUndefined();
|
||||||
// If it's a new window download, report it on the opener page.
|
// If it's a new window download, report it on the opener page.
|
||||||
if (!originPage) {
|
if (!originPage) {
|
||||||
// Resume the page creation with an error. The page will automatically close right
|
// Resume the page creation with an error. The page will automatically close right
|
||||||
// after the download begins.
|
// after the download begins.
|
||||||
page._firstNonInitialNavigationCommittedReject(new Error('Starting new page download'));
|
page._firstNonInitialNavigationCommittedReject(new Error('Starting new page download'));
|
||||||
if (page._opener)
|
if (page._opener)
|
||||||
originPage = page._opener._page.initialized();
|
originPage = page._opener._page.initializedOrUndefined();
|
||||||
}
|
}
|
||||||
if (!originPage)
|
if (!originPage)
|
||||||
return;
|
return;
|
||||||
|
|
|
||||||
|
|
@ -108,10 +108,6 @@ export class WKPage implements PageDelegate {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
potentiallyUninitializedPage(): Page {
|
|
||||||
return this._page;
|
|
||||||
}
|
|
||||||
|
|
||||||
private async _initializePageProxySession() {
|
private async _initializePageProxySession() {
|
||||||
if (this._page._browserContext.isSettingStorageState())
|
if (this._page._browserContext.isSettingStorageState())
|
||||||
return;
|
return;
|
||||||
|
|
@ -280,7 +276,7 @@ export class WKPage implements PageDelegate {
|
||||||
}
|
}
|
||||||
|
|
||||||
handleProvisionalLoadFailed(event: Protocol.Playwright.provisionalLoadFailedPayload) {
|
handleProvisionalLoadFailed(event: Protocol.Playwright.provisionalLoadFailedPayload) {
|
||||||
if (!this._page.initialized()) {
|
if (!this._page.initializedOrUndefined()) {
|
||||||
this._firstNonInitialNavigationCommittedReject(new Error('Initial load failed'));
|
this._firstNonInitialNavigationCommittedReject(new Error('Initial load failed'));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
@ -309,7 +305,7 @@ export class WKPage implements PageDelegate {
|
||||||
assert(targetInfo.type === 'page', 'Only page targets are expected in WebKit, received: ' + targetInfo.type);
|
assert(targetInfo.type === 'page', 'Only page targets are expected in WebKit, received: ' + targetInfo.type);
|
||||||
|
|
||||||
if (!targetInfo.isProvisional) {
|
if (!targetInfo.isProvisional) {
|
||||||
assert(!this._page.initialized());
|
assert(!this._page.initializedOrUndefined());
|
||||||
let pageOrError: Page | Error;
|
let pageOrError: Page | Error;
|
||||||
try {
|
try {
|
||||||
this._setSession(session);
|
this._setSession(session);
|
||||||
|
|
@ -336,8 +332,7 @@ export class WKPage implements PageDelegate {
|
||||||
// Avoid rejection on disconnect.
|
// Avoid rejection on disconnect.
|
||||||
this._firstNonInitialNavigationCommittedPromise.catch(() => {});
|
this._firstNonInitialNavigationCommittedPromise.catch(() => {});
|
||||||
}
|
}
|
||||||
await this._page.initOpener(this._opener?._page);
|
this._page.reportAsNew(this._opener?._page, pageOrError instanceof Page ? undefined : pageOrError);
|
||||||
this._page.reportAsNew(pageOrError instanceof Page ? undefined : pageOrError);
|
|
||||||
} else {
|
} else {
|
||||||
assert(targetInfo.isProvisional);
|
assert(targetInfo.isProvisional);
|
||||||
assert(!this._provisionalPage);
|
assert(!this._provisionalPage);
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue