fix: waitForNavigation in OOPIFs (#8117)

This commit is contained in:
Alex Rudenko 2022-03-09 12:24:17 +01:00 committed by GitHub
parent d4b5a79e55
commit 34775e5831
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 45 additions and 1 deletions

View File

@ -53,6 +53,7 @@ export const FrameManagerEmittedEvents = {
FrameAttached: Symbol('FrameManager.FrameAttached'),
FrameNavigated: Symbol('FrameManager.FrameNavigated'),
FrameDetached: Symbol('FrameManager.FrameDetached'),
FrameSwapped: Symbol('FrameManager.FrameSwapped'),
LifecycleEvent: Symbol('FrameManager.LifecycleEvent'),
FrameNavigatedWithinDocument: Symbol(
'FrameManager.FrameNavigatedWithinDocument'
@ -422,6 +423,8 @@ export class FrameManager extends EventEmitter {
// an actual removement of the frame.
// For frames that become OOP iframes, the reason would be 'swap'.
if (frame) this._removeFramesRecursively(frame);
} else if (reason === 'swap') {
this.emit(FrameManagerEmittedEvents.FrameSwapped, frame);
}
}

View File

@ -82,6 +82,7 @@ export class LifecycleWatcher {
_maximumTimer?: NodeJS.Timeout;
_hasSameDocumentNavigation?: boolean;
_swapped?: boolean;
constructor(
frameManager: FrameManager,
@ -121,6 +122,11 @@ export class LifecycleWatcher {
FrameManagerEmittedEvents.FrameNavigatedWithinDocument,
this._navigatedWithinDocument.bind(this)
),
helper.addEventListener(
this._frameManager,
FrameManagerEmittedEvents.FrameSwapped,
this._frameSwapped.bind(this)
),
helper.addEventListener(
this._frameManager,
FrameManagerEmittedEvents.FrameDetached,
@ -211,6 +217,12 @@ export class LifecycleWatcher {
this._checkLifecycleComplete();
}
_frameSwapped(frame: Frame): void {
if (frame !== this._frame) return;
this._swapped = true;
this._checkLifecycleComplete();
}
_checkLifecycleComplete(): void {
// We expect navigation to commit.
if (!checkLifecycle(this._frame, this._expectedLifecycle)) return;
@ -218,8 +230,13 @@ export class LifecycleWatcher {
if (
this._frame._loaderId === this._initialLoaderId &&
!this._hasSameDocumentNavigation
)
) {
if (this._swapped) {
this._swapped = false;
this._newDocumentNavigationCompleteCallback();
}
return;
}
if (this._hasSameDocumentNavigation)
this._sameDocumentNavigationCompleteCallback();
if (this._frame._loaderId !== this._initialLoaderId)

View File

@ -154,6 +154,30 @@ describeChromeOnly('OOPIF', function () {
await utils.detachFrame(page, 'frame1');
expect(page.frames()).toHaveLength(1);
});
it('should support wait for navigation for transitions from local to OOPIF', async () => {
const { server } = getTestState();
await page.goto(server.EMPTY_PAGE);
const framePromise = page.waitForFrame((frame) => {
return page.frames().indexOf(frame) === 1;
});
await utils.attachFrame(page, 'frame1', server.EMPTY_PAGE);
const frame = await framePromise;
expect(frame.isOOPFrame()).toBe(false);
const nav = frame.waitForNavigation();
await utils.navigateFrame(
page,
'frame1',
server.CROSS_PROCESS_PREFIX + '/empty.html'
);
await nav;
expect(frame.isOOPFrame()).toBe(true);
await utils.detachFrame(page, 'frame1');
expect(page.frames()).toHaveLength(1);
});
it('should keep track of a frames OOP state', async () => {
const { server } = getTestState();