fix(firefox): setContent to properly listen for lifecycle events (#219)
This commit is contained in:
parent
ee1f4784c6
commit
90f0b8c2b0
|
|
@ -9,7 +9,7 @@
|
||||||
"main": "index.js",
|
"main": "index.js",
|
||||||
"playwright": {
|
"playwright": {
|
||||||
"chromium_revision": "719491",
|
"chromium_revision": "719491",
|
||||||
"firefox_revision": "1004",
|
"firefox_revision": "1005",
|
||||||
"webkit_revision": "1032"
|
"webkit_revision": "1032"
|
||||||
},
|
},
|
||||||
"scripts": {
|
"scripts": {
|
||||||
|
|
|
||||||
|
|
@ -29,7 +29,7 @@ import * as network from '../network';
|
||||||
import { BrowserContext, BrowserInterface } from '../browserContext';
|
import { BrowserContext, BrowserInterface } from '../browserContext';
|
||||||
|
|
||||||
export class Browser extends EventEmitter implements BrowserInterface {
|
export class Browser extends EventEmitter implements BrowserInterface {
|
||||||
private _connection: Connection;
|
_connection: Connection;
|
||||||
_defaultViewport: types.Viewport;
|
_defaultViewport: types.Viewport;
|
||||||
private _process: import('child_process').ChildProcess;
|
private _process: import('child_process').ChildProcess;
|
||||||
private _closeCallback: () => Promise<void>;
|
private _closeCallback: () => Promise<void>;
|
||||||
|
|
|
||||||
|
|
@ -124,6 +124,8 @@ export class ExecutionContextDelegate implements js.ExecutionContextDelegate {
|
||||||
}
|
}
|
||||||
|
|
||||||
async releaseHandle(handle: js.JSHandle): Promise<void> {
|
async releaseHandle(handle: js.JSHandle): Promise<void> {
|
||||||
|
if (!handle._remoteObject.objectId)
|
||||||
|
return;
|
||||||
await this._session.send('Runtime.disposeObject', {
|
await this._session.send('Runtime.disposeObject', {
|
||||||
executionContextId: this._executionContextId,
|
executionContextId: this._executionContextId,
|
||||||
objectId: handle._remoteObject.objectId,
|
objectId: handle._remoteObject.objectId,
|
||||||
|
|
|
||||||
|
|
@ -301,13 +301,26 @@ export class FrameManager extends EventEmitter implements PageDelegate {
|
||||||
return watcher.navigationResponse();
|
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();
|
const context = await frame._utilityContext();
|
||||||
|
frame._firedLifecycleEvents.clear();
|
||||||
await context.evaluate(html => {
|
await context.evaluate(html => {
|
||||||
document.open();
|
document.open();
|
||||||
document.write(html);
|
document.write(html);
|
||||||
document.close();
|
document.close();
|
||||||
}, html);
|
}, 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<void> {
|
setExtraHTTPHeaders(extraHTTPHeaders: network.Headers): Promise<void> {
|
||||||
|
|
|
||||||
|
|
@ -528,6 +528,24 @@ module.exports.addTests = function({testRunner, expect, headless, playwright, FF
|
||||||
const result = await page.content();
|
const result = await page.content();
|
||||||
expect(result).toBe(expectedOutput);
|
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(`<img src="${server.PREFIX + imgPath}"></img>`).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}) => {
|
it('should work with doctype', async({page, server}) => {
|
||||||
const doctype = '<!DOCTYPE html>';
|
const doctype = '<!DOCTYPE html>';
|
||||||
await page.setContent(`${doctype}<div>hello</div>`);
|
await page.setContent(`${doctype}<div>hello</div>`);
|
||||||
|
|
@ -541,7 +559,7 @@ module.exports.addTests = function({testRunner, expect, headless, playwright, FF
|
||||||
const result = await page.content();
|
const result = await page.content();
|
||||||
expect(result).toBe(`${doctype}${expectedOutput}`);
|
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';
|
const imgPath = '/img.png';
|
||||||
// stall for image
|
// stall for image
|
||||||
server.setRoute(imgPath, (req, res) => {});
|
server.setRoute(imgPath, (req, res) => {});
|
||||||
|
|
@ -549,7 +567,7 @@ module.exports.addTests = function({testRunner, expect, headless, playwright, FF
|
||||||
await page.setContent(`<img src="${server.PREFIX + imgPath}"></img>`, {timeout: 1}).catch(e => error = e);
|
await page.setContent(`<img src="${server.PREFIX + imgPath}"></img>`, {timeout: 1}).catch(e => error = e);
|
||||||
expect(error).toBeInstanceOf(playwright.errors.TimeoutError);
|
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);
|
page.setDefaultNavigationTimeout(1);
|
||||||
const imgPath = '/img.png';
|
const imgPath = '/img.png';
|
||||||
// stall for image
|
// stall for image
|
||||||
|
|
@ -558,7 +576,7 @@ module.exports.addTests = function({testRunner, expect, headless, playwright, FF
|
||||||
await page.setContent(`<img src="${server.PREFIX + imgPath}"></img>`).catch(e => error = e);
|
await page.setContent(`<img src="${server.PREFIX + imgPath}"></img>`).catch(e => error = e);
|
||||||
expect(error).toBeInstanceOf(playwright.errors.TimeoutError);
|
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';
|
const imgPath = '/img.png';
|
||||||
let imgResponse = null;
|
let imgResponse = null;
|
||||||
server.setRoute(imgPath, (req, res) => imgResponse = res);
|
server.setRoute(imgPath, (req, res) => imgResponse = res);
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue