diff --git a/package.json b/package.json index 5a8a68f86f..6cc382dab6 100644 --- a/package.json +++ b/package.json @@ -9,7 +9,7 @@ "main": "index.js", "playwright": { "chromium_revision": "719491", - "firefox_revision": "1004", + "firefox_revision": "1005", "webkit_revision": "1032" }, "scripts": { diff --git a/src/firefox/Browser.ts b/src/firefox/Browser.ts index bf6bc3a5dc..92df635f6f 100644 --- a/src/firefox/Browser.ts +++ b/src/firefox/Browser.ts @@ -29,7 +29,7 @@ import * as network from '../network'; import { BrowserContext, BrowserInterface } from '../browserContext'; export class Browser extends EventEmitter implements BrowserInterface { - private _connection: Connection; + _connection: Connection; _defaultViewport: types.Viewport; private _process: import('child_process').ChildProcess; private _closeCallback: () => Promise; diff --git a/src/firefox/ExecutionContext.ts b/src/firefox/ExecutionContext.ts index cdb61b750e..4764bead76 100644 --- a/src/firefox/ExecutionContext.ts +++ b/src/firefox/ExecutionContext.ts @@ -124,6 +124,8 @@ export class ExecutionContextDelegate implements js.ExecutionContextDelegate { } async releaseHandle(handle: js.JSHandle): Promise { + if (!handle._remoteObject.objectId) + return; await this._session.send('Runtime.disposeObject', { executionContextId: this._executionContextId, objectId: handle._remoteObject.objectId, diff --git a/src/firefox/FrameManager.ts b/src/firefox/FrameManager.ts index 5a22a07235..89c467803f 100644 --- a/src/firefox/FrameManager.ts +++ b/src/firefox/FrameManager.ts @@ -301,13 +301,26 @@ export class FrameManager extends EventEmitter implements PageDelegate { return watcher.navigationResponse(); } - async setFrameContent(frame: frames.Frame, html: string) { + async setFrameContent(frame: frames.Frame, html: string, options: frames.NavigateOptions = {}) { + const { + waitUntil = (['load'] as frames.LifecycleEvent[]), + timeout = this._page._timeoutSettings.navigationTimeout(), + } = options; const context = await frame._utilityContext(); + frame._firedLifecycleEvents.clear(); await context.evaluate(html => { document.open(); document.write(html); document.close(); }, html); + const watcher = new frames.LifecycleWatcher(frame, waitUntil, timeout); + const error = await Promise.race([ + watcher.timeoutOrTerminationPromise, + watcher.lifecyclePromise, + ]); + watcher.dispose(); + if (error) + throw error; } setExtraHTTPHeaders(extraHTTPHeaders: network.Headers): Promise { diff --git a/test/page.spec.js b/test/page.spec.js index cdf021a4f7..4702e86bec 100644 --- a/test/page.spec.js +++ b/test/page.spec.js @@ -528,6 +528,24 @@ module.exports.addTests = function({testRunner, expect, headless, playwright, FF const result = await page.content(); expect(result).toBe(expectedOutput); }); + it('should not confuse with previous navigation', async({page, server}) => { + const imgPath = '/img.png'; + let imgResponse = null; + server.setRoute(imgPath, (req, res) => imgResponse = res); + let loaded = false; + // Trigger navigation which might resolve next setContent call. + page.evaluate(url => window.location.href = url, server.EMPTY_PAGE); + const contentPromise = page.setContent(``).then(() => loaded = true); + await server.waitForRequest(imgPath); + + expect(loaded).toBe(false); + for (let i = 0; i < 5; i++) + await page.evaluate('1'); // Roundtrips to give setContent a chance to resolve. + expect(loaded).toBe(false); + + imgResponse.end(); + await contentPromise; + }); it('should work with doctype', async({page, server}) => { const doctype = ''; await page.setContent(`${doctype}
hello
`); @@ -541,7 +559,7 @@ module.exports.addTests = function({testRunner, expect, headless, playwright, FF const result = await page.content(); expect(result).toBe(`${doctype}${expectedOutput}`); }); - it.skip(FFOX)('should respect timeout', async({page, server}) => { + it('should respect timeout', async({page, server}) => { const imgPath = '/img.png'; // stall for image server.setRoute(imgPath, (req, res) => {}); @@ -549,7 +567,7 @@ module.exports.addTests = function({testRunner, expect, headless, playwright, FF await page.setContent(``, {timeout: 1}).catch(e => error = e); expect(error).toBeInstanceOf(playwright.errors.TimeoutError); }); - it.skip(FFOX)('should respect default navigation timeout', async({page, server}) => { + it('should respect default navigation timeout', async({page, server}) => { page.setDefaultNavigationTimeout(1); const imgPath = '/img.png'; // stall for image @@ -558,7 +576,7 @@ module.exports.addTests = function({testRunner, expect, headless, playwright, FF await page.setContent(``).catch(e => error = e); expect(error).toBeInstanceOf(playwright.errors.TimeoutError); }); - it.skip(FFOX)('should await resources to load', async({page, server}) => { + it('should await resources to load', async({page, server}) => { const imgPath = '/img.png'; let imgResponse = null; server.setRoute(imgPath, (req, res) => imgResponse = res);