diff --git a/src/frames.ts b/src/frames.ts index 0c5056ec4d..27924dad30 100644 --- a/src/frames.ts +++ b/src/frames.ts @@ -117,10 +117,10 @@ export class FrameManager { frame._url = url; frame._name = name; frame._lastDocumentId = documentId; - frame._documentWatchers.forEach(watcher => watcher(documentId)); + for (const watcher of frame._documentWatchers) + watcher(documentId); this.clearFrameLifecycle(frame); this.clearWebSockets(frame); - // TODO should the document watchers only fire if !initial? if (!initial) this._page.emit(Events.Page.FrameNavigated, frame); } @@ -342,7 +342,6 @@ export class Frame { _id: string; readonly _firedLifecycleEvents: Set; _lastDocumentId = ''; - _expectedDocumentId = ''; _requestWatchers = new Set<(request: network.Request) => void>(); _documentWatchers = new Set<(documentId: string, error?: Error) => void>(); _sameDocumentNavigationWatchers = new Set<() => void>(); @@ -415,7 +414,7 @@ export class Frame { disposer.dispose(); - return request ? request!._finalRequest._waitForResponse() : null; + return request ? request._finalRequest._waitForResponse() : null; function throwIfError(error: Error|void): asserts error is void { if (!error) @@ -437,8 +436,8 @@ export class Frame { disposer.add(createTimeoutPromise(timeout)), disposer.add(createFrameDestroyedPromise(this)), ]); - let documentId : string|null = null; - let error : void|Error = await Promise.race([ + let documentId: string|null = null; + let error: void|Error = await Promise.race([ failurePromise, disposer.add(waitForNewDocument(this, options.url)).then(result => { if (result.error) @@ -989,7 +988,7 @@ class RerunnableTask { type Disposable = {value: T, dispose: () => void}; class Disposer { private _disposes: (() => void)[] = []; - add({value, dispose} : Disposable) { + add({value, dispose}: Disposable) { this._disposes.push(dispose); return value; } @@ -1000,8 +999,8 @@ class Disposer { } } -function createFrameDestroyedPromise(frame: Frame) : Disposable> { - let detachedCallback : (error: Error) => void; +function createFrameDestroyedPromise(frame: Frame): Disposable> { + let detachedCallback: (error: Error) => void; const detachedPromise = new Promise(x => detachedCallback = x); const listener = (detachedFrame: Frame) => { if (detachedFrame !== frame) @@ -1037,7 +1036,7 @@ function createTimeoutPromise(timeout: number): Disposable }; } -function waitForSpecificDocument(frame: Frame, expectedDocumentId: string) : Disposable> { +function waitForSpecificDocument(frame: Frame, expectedDocumentId: string): Disposable> { let resolve: (error: Error|void) => void; const promise = new Promise(x => resolve = x); const watch = (documentId: string, error?: Error) => { @@ -1050,7 +1049,7 @@ function waitForSpecificDocument(frame: Frame, expectedDocumentId: string) : Dis return {value: promise, dispose}; } -function waitForNewDocument(frame: Frame, url?: types.URLMatch) : Disposable> { +function waitForNewDocument(frame: Frame, url?: types.URLMatch): Disposable> { let resolve: (error: {error?: Error, documentId: string}) => void; const promise = new Promise<{error?: Error, documentId: string}>(x => resolve = x); const watch = (documentId: string, error?: Error) => { @@ -1063,7 +1062,7 @@ function waitForNewDocument(frame: Frame, url?: types.URLMatch) : Disposable> { +function waitForSameDocumentNavigation(frame: Frame, url?: types.URLMatch): Disposable> { let resolve: () => void; const promise = new Promise(x => resolve = x); const watch = () => { @@ -1075,7 +1074,7 @@ function waitForSameDocumentNavigation(frame: Frame, url?: types.URLMatch) : Dis return {value: promise, dispose}; } -function waitForLifecycle(frame: Frame, waitUntil: LifecycleEvent|LifecycleEvent[] = 'load') : Disposable> { +function waitForLifecycle(frame: Frame, waitUntil: LifecycleEvent|LifecycleEvent[] = 'load'): Disposable> { let resolve: () => void; const expectedLifecycle = typeof waitUntil === 'string' ? [waitUntil] : waitUntil; for (const event of expectedLifecycle) { @@ -1108,7 +1107,7 @@ function waitForLifecycle(frame: Frame, waitUntil: LifecycleEvent|LifecycleEvent } } -function trackDocumentRequests(frame: Frame) : Disposable> { +function trackDocumentRequests(frame: Frame): Disposable> { const requestMap = new Map(); const dispose = () => { frame._requestWatchers.delete(onRequest); diff --git a/test/navigation.spec.js b/test/navigation.spec.js index faa0f649ef..356582c78d 100644 --- a/test/navigation.spec.js +++ b/test/navigation.spec.js @@ -722,6 +722,17 @@ module.exports.describe = function({testRunner, expect, playwright, FFOX, CHROMI await waitPromise; expect(resolved).toBe(true); }); + it('should work for cross-process navigations', async({page, server}) => { + await page.goto(server.EMPTY_PAGE); + const waitPromise = page.waitForNavigation({waitUntil: []}); + const url = server.CROSS_PROCESS_PREFIX + '/empty.html'; + const gotoPromise = page.goto(url); + const response = await waitPromise; + expect(response.url()).toBe(url); + expect(page.url()).toBe(url); + expect(await page.evaluate('document.location.href')).toBe(url); + await gotoPromise; + }); }); describe('Page.waitForLoadState', () => {