feat(firefox): basic support for Network (#3988)
This patch introduces basic Request and Response events for page. It also teaches navigation methods, e.g. `page.goto` to return navigation response.
This commit is contained in:
parent
fb9d4049d8
commit
afb9355b15
@ -10,6 +10,10 @@ const Events = {
|
||||
Load: 'load',
|
||||
PageError: 'pageerror',
|
||||
Popup: 'popup',
|
||||
Request: 'request',
|
||||
Response: 'response',
|
||||
RequestFinished: 'requestfinished',
|
||||
RequestFailed: 'requestfailed',
|
||||
},
|
||||
Browser: {
|
||||
TargetCreated: 'targetcreated',
|
||||
@ -30,8 +34,15 @@ const Events = {
|
||||
Load: Symbol('Events.FrameManager.Load'),
|
||||
DOMContentLoaded: Symbol('Events.FrameManager.DOMContentLoaded'),
|
||||
FrameAttached: Symbol('Events.FrameManager.FrameAttached'),
|
||||
FrameNavigated: Symbol('Events.FrameManager.FrameNavigated'),
|
||||
FrameDetached: Symbol('Events.FrameManager.FrameDetached'),
|
||||
}
|
||||
},
|
||||
|
||||
NetworkManager: {
|
||||
Request: Symbol('Events.NetworkManager.Request'),
|
||||
Response: Symbol('Events.NetworkManager.Response'),
|
||||
RequestFinished: Symbol('Events.NetworkManager.RequestFinished'),
|
||||
},
|
||||
};
|
||||
|
||||
module.exports = {Events};
|
||||
|
@ -24,6 +24,8 @@ class FrameManager extends EventEmitter {
|
||||
helper.addEventListener(this._session, 'Page.eventFired', this._onEventFired.bind(this)),
|
||||
helper.addEventListener(this._session, 'Page.frameAttached', this._onFrameAttached.bind(this)),
|
||||
helper.addEventListener(this._session, 'Page.frameDetached', this._onFrameDetached.bind(this)),
|
||||
helper.addEventListener(this._session, 'Page.navigationCommitted', this._onNavigationCommitted.bind(this)),
|
||||
helper.addEventListener(this._session, 'Page.sameDocumentNavigation', this._onSameDocumentNavigation.bind(this)),
|
||||
];
|
||||
}
|
||||
|
||||
@ -48,6 +50,20 @@ class FrameManager extends EventEmitter {
|
||||
}
|
||||
}
|
||||
|
||||
_onNavigationCommitted(params) {
|
||||
const frame = this._frames.get(params.frameId);
|
||||
frame._navigated(params.url, params.name, params.navigationId);
|
||||
frame._DOMContentLoadedFired = false;
|
||||
frame._loadFired = false;
|
||||
this.emit(Events.FrameManager.FrameNavigated, frame);
|
||||
}
|
||||
|
||||
_onSameDocumentNavigation(params) {
|
||||
const frame = this._frames.get(params.frameId);
|
||||
frame._url = params.url;
|
||||
this.emit(Events.FrameManager.FrameNavigated, frame);
|
||||
}
|
||||
|
||||
_onFrameAttached(params) {
|
||||
const frame = new Frame(this._session, this, this._page, params.frameId, this._timeoutSettings);
|
||||
const parentFrame = this._frames.get(params.parentFrameId) || null;
|
||||
|
174
experimental/puppeteer-firefox/lib/NetworkManager.js
Normal file
174
experimental/puppeteer-firefox/lib/NetworkManager.js
Normal file
@ -0,0 +1,174 @@
|
||||
const {helper} = require('./helper');
|
||||
const util = require('util');
|
||||
const EventEmitter = require('events');
|
||||
const {Events} = require('./Events');
|
||||
|
||||
class NetworkManager extends EventEmitter {
|
||||
constructor(session, frameManager) {
|
||||
super();
|
||||
this._session = session;
|
||||
|
||||
this._requests = new Map();
|
||||
this._frameManager = frameManager;
|
||||
|
||||
this._eventListeners = [
|
||||
helper.addEventListener(session, 'Page.requestWillBeSent', this._onRequestWillBeSent.bind(this)),
|
||||
helper.addEventListener(session, 'Page.responseReceived', this._onResponseReceived.bind(this)),
|
||||
helper.addEventListener(session, 'Page.requestFinished', this._onRequestFinished.bind(this)),
|
||||
];
|
||||
}
|
||||
|
||||
_onRequestWillBeSent(event) {
|
||||
const frame = this._frameManager && event.frameId ? this._frameManager.frame(event.frameId) : null;
|
||||
if (!frame)
|
||||
return;
|
||||
let redirectChain = [];
|
||||
const redirected = event.redirectedFrom ? this._requests.get(event.redirectedFrom) : null;
|
||||
if (redirected) {
|
||||
redirectChain = redirected._redirectChain;
|
||||
redirectChain.push(redirected);
|
||||
this._requests.delete(redirected._id);
|
||||
}
|
||||
const request = new Request(frame, redirectChain, event);
|
||||
this._requests.set(request._id, request);
|
||||
this.emit(Events.NetworkManager.Request, request);
|
||||
}
|
||||
|
||||
_onResponseReceived(event) {
|
||||
const request = this._requests.get(event.requestId);
|
||||
if (!request)
|
||||
return;
|
||||
const response = new Response(request, event);
|
||||
request._response = response;
|
||||
this.emit(Events.NetworkManager.Response, response);
|
||||
}
|
||||
|
||||
_onRequestFinished(event) {
|
||||
const request = this._requests.get(event.requestId);
|
||||
if (!request)
|
||||
return;
|
||||
// Keep redirected requests in the map for future reference in redirectChain.
|
||||
const isRedirected = request.response().status() >= 300 && request.response().status() <= 399;
|
||||
if (!isRedirected)
|
||||
this._requests.delete(request._id);
|
||||
this.emit(Events.NetworkManager.RequestFinished, request);
|
||||
}
|
||||
|
||||
dispose() {
|
||||
helper.removeEventListeners(this._eventListeners);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* document, stylesheet, image, media, font, script, texttrack, xhr, fetch, eventsource, websocket, manifest, other.
|
||||
*/
|
||||
const causeToResourceType = {
|
||||
TYPE_INVALID: 'other',
|
||||
TYPE_OTHER: 'other',
|
||||
TYPE_SCRIPT: 'script',
|
||||
TYPE_IMAGE: 'image',
|
||||
TYPE_STYLESHEET: 'stylesheet',
|
||||
TYPE_OBJECT: 'other',
|
||||
TYPE_DOCUMENT: 'document',
|
||||
TYPE_SUBDOCUMENT: 'document',
|
||||
TYPE_REFRESH: 'document',
|
||||
TYPE_XBL: 'other',
|
||||
TYPE_PING: 'other',
|
||||
TYPE_XMLHTTPREQUEST: 'xhr',
|
||||
TYPE_OBJECT_SUBREQUEST: 'other',
|
||||
TYPE_DTD: 'other',
|
||||
TYPE_FONT: 'font',
|
||||
TYPE_MEDIA: 'media',
|
||||
TYPE_WEBSOCKET: 'websocket',
|
||||
TYPE_CSP_REPORT: 'other',
|
||||
TYPE_XSLT: 'other',
|
||||
TYPE_BEACON: 'other',
|
||||
TYPE_FETCH: 'fetch',
|
||||
TYPE_IMAGESET: 'images',
|
||||
TYPE_WEB_MANIFEST: 'manifest',
|
||||
};
|
||||
|
||||
class Request {
|
||||
constructor(frame, redirectChain, payload) {
|
||||
this._frame = frame;
|
||||
this._id = payload.requestId;
|
||||
this._redirectChain = redirectChain;
|
||||
this._url = payload.url;
|
||||
this._response = null;
|
||||
this._isNavigationRequest = payload.isNavigationRequest;
|
||||
this._method = payload.method;
|
||||
this._resourceType = causeToResourceType[payload.cause] || 'other';
|
||||
}
|
||||
|
||||
redirectChain() {
|
||||
return this._redirectChain.slice();
|
||||
}
|
||||
|
||||
resourceType() {
|
||||
return this._resourceType;
|
||||
}
|
||||
|
||||
url() {
|
||||
return this._url;
|
||||
}
|
||||
|
||||
method() {
|
||||
return this._method;
|
||||
}
|
||||
|
||||
isNavigationRequest() {
|
||||
return this._isNavigationRequest;
|
||||
}
|
||||
|
||||
frame() {
|
||||
return this._frame;
|
||||
}
|
||||
|
||||
response() {
|
||||
return this._response;
|
||||
}
|
||||
}
|
||||
|
||||
class Response {
|
||||
constructor(request, payload) {
|
||||
this._request = request;
|
||||
this._remoteIPAddress = payload.remoteIPAddress;
|
||||
this._remotePort = payload.remotePort;
|
||||
this._status = payload.status;
|
||||
this._statusText = payload.statusText;
|
||||
}
|
||||
|
||||
status() {
|
||||
return this._status;
|
||||
}
|
||||
|
||||
statusText() {
|
||||
return this._statusText;
|
||||
}
|
||||
|
||||
ok() {
|
||||
return this._status >= 200 && this._status <= 299;
|
||||
}
|
||||
|
||||
remoteAddress() {
|
||||
return {
|
||||
ip: this._remoteIPAddress,
|
||||
port: this._remotePort,
|
||||
};
|
||||
}
|
||||
|
||||
frame() {
|
||||
return this._request.frame();
|
||||
}
|
||||
|
||||
url() {
|
||||
return this._request.url();
|
||||
}
|
||||
|
||||
request() {
|
||||
return this._request;
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = {NetworkManager, Request, Response};
|
@ -9,6 +9,7 @@ const EventEmitter = require('events');
|
||||
const {createHandle} = require('./JSHandle');
|
||||
const {Events} = require('./Events');
|
||||
const {FrameManager} = require('./FrameManager');
|
||||
const {NetworkManager} = require('./NetworkManager');
|
||||
const {TimeoutSettings} = require('./TimeoutSettings');
|
||||
|
||||
const writeFileAsync = util.promisify(fs.writeFile);
|
||||
@ -74,17 +75,21 @@ class Page extends EventEmitter {
|
||||
this._mouse = new Mouse(session, this._keyboard);
|
||||
this._isClosed = false;
|
||||
this._frameManager = new FrameManager(session, this, this._timeoutSettings);
|
||||
this._networkManager = new NetworkManager(session, this._frameManager);
|
||||
this._eventListeners = [
|
||||
helper.addEventListener(this._session, 'Page.uncaughtError', this._onUncaughtError.bind(this)),
|
||||
helper.addEventListener(this._session, 'Page.consoleAPICalled', this._onConsole.bind(this)),
|
||||
helper.addEventListener(this._session, 'Page.dialogOpened', this._onDialogOpened.bind(this)),
|
||||
helper.addEventListener(this._session, 'Browser.tabClosed', this._onClosed.bind(this)),
|
||||
helper.addEventListener(this._session, 'Page.navigationCommitted', this._onNavigationCommitted.bind(this)),
|
||||
helper.addEventListener(this._session, 'Page.sameDocumentNavigation', this._onSameDocumentNavigation.bind(this)),
|
||||
helper.addEventListener(this._frameManager, Events.FrameManager.Load, () => this.emit(Events.Page.Load)),
|
||||
helper.addEventListener(this._frameManager, Events.FrameManager.DOMContentLoaded, () => this.emit(Events.Page.DOMContentLoaded)),
|
||||
helper.addEventListener(this._frameManager, Events.FrameManager.FrameAttached, frame => this.emit(Events.Page.FrameAttached, frame)),
|
||||
helper.addEventListener(this._frameManager, Events.FrameManager.FrameDetached, frame => this.emit(Events.Page.FrameDetached, frame)),
|
||||
helper.addEventListener(this._frameManager, Events.FrameManager.FrameNavigated, frame => this.emit(Events.Page.FrameNavigated, frame)),
|
||||
helper.addEventListener(this._networkManager, Events.NetworkManager.Request, request => this.emit(Events.Page.Request, request)),
|
||||
helper.addEventListener(this._networkManager, Events.NetworkManager.Response, response => this.emit(Events.Page.Response, response)),
|
||||
helper.addEventListener(this._networkManager, Events.NetworkManager.RequestFinished, request => this.emit(Events.Page.RequestFinished, request)),
|
||||
helper.addEventListener(this._networkManager, Events.NetworkManager.RequestFailed, request => this.emit(Events.Page.RequestFailed, request)),
|
||||
];
|
||||
this._viewport = null;
|
||||
}
|
||||
@ -206,20 +211,6 @@ class Page extends EventEmitter {
|
||||
return this._frameManager.mainFrame();
|
||||
}
|
||||
|
||||
_onNavigationCommitted(params) {
|
||||
const frame = this._frameManager.frame(params.frameId);
|
||||
frame._navigated(params.url, params.name, params.navigationId);
|
||||
frame._DOMContentLoadedFired = false;
|
||||
frame._loadFired = false;
|
||||
this.emit(Events.Page.FrameNavigated, frame);
|
||||
}
|
||||
|
||||
_onSameDocumentNavigation(params) {
|
||||
const frame = this._frameManager.frame(params.frameId);
|
||||
frame._url = params.url;
|
||||
this.emit(Events.Page.FrameNavigated, frame);
|
||||
}
|
||||
|
||||
get keyboard(){
|
||||
return this._keyboard;
|
||||
}
|
||||
@ -272,10 +263,10 @@ class Page extends EventEmitter {
|
||||
if (!navigationId) {
|
||||
// Same document navigation happened.
|
||||
clearTimeout(timeoutId);
|
||||
return;
|
||||
return null;
|
||||
}
|
||||
|
||||
const watchDog = new NavigationWatchdog(this._session, frame, navigationId, url, normalizedWaitUntil);
|
||||
const watchDog = new NavigationWatchdog(this._session, frame, this._networkManager, navigationId, url, normalizedWaitUntil);
|
||||
const error = await Promise.race([
|
||||
timeoutPromise,
|
||||
watchDog.promise(),
|
||||
@ -284,6 +275,7 @@ class Page extends EventEmitter {
|
||||
clearTimeout(timeoutId);
|
||||
if (error)
|
||||
throw error;
|
||||
return watchDog.navigationResponse();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -309,7 +301,7 @@ class Page extends EventEmitter {
|
||||
const timeoutPromise = new Promise(resolve => timeoutCallback = resolve.bind(null, timeoutError));
|
||||
const timeoutId = timeout ? setTimeout(timeoutCallback, timeout) : null;
|
||||
|
||||
const watchDog = new NavigationWatchdog(this._session, frame, navigationId, url, normalizedWaitUntil);
|
||||
const watchDog = new NavigationWatchdog(this._session, frame, this._networkManager, navigationId, url, normalizedWaitUntil);
|
||||
const error = await Promise.race([
|
||||
timeoutPromise,
|
||||
watchDog.promise(),
|
||||
@ -318,6 +310,7 @@ class Page extends EventEmitter {
|
||||
clearTimeout(timeoutId);
|
||||
if (error)
|
||||
throw error;
|
||||
return watchDog.navigationResponse();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -334,14 +327,14 @@ class Page extends EventEmitter {
|
||||
frameId: frame._frameId,
|
||||
});
|
||||
if (!navigationId)
|
||||
return;
|
||||
return null;
|
||||
|
||||
const timeoutError = new TimeoutError('Navigation Timeout Exceeded: ' + timeout + 'ms');
|
||||
let timeoutCallback;
|
||||
const timeoutPromise = new Promise(resolve => timeoutCallback = resolve.bind(null, timeoutError));
|
||||
const timeoutId = timeout ? setTimeout(timeoutCallback, timeout) : null;
|
||||
|
||||
const watchDog = new NavigationWatchdog(this._session, frame, navigationId, navigationURL, normalizedWaitUntil);
|
||||
const watchDog = new NavigationWatchdog(this._session, frame, this._networkManager, navigationId, navigationURL, normalizedWaitUntil);
|
||||
const error = await Promise.race([
|
||||
timeoutPromise,
|
||||
watchDog.promise(),
|
||||
@ -350,6 +343,7 @@ class Page extends EventEmitter {
|
||||
clearTimeout(timeoutId);
|
||||
if (error)
|
||||
throw error;
|
||||
return watchDog.navigationResponse();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -366,14 +360,14 @@ class Page extends EventEmitter {
|
||||
frameId: frame._frameId,
|
||||
});
|
||||
if (!navigationId)
|
||||
return;
|
||||
return null;
|
||||
|
||||
const timeoutError = new TimeoutError('Navigation Timeout Exceeded: ' + timeout + 'ms');
|
||||
let timeoutCallback;
|
||||
const timeoutPromise = new Promise(resolve => timeoutCallback = resolve.bind(null, timeoutError));
|
||||
const timeoutId = timeout ? setTimeout(timeoutCallback, timeout) : null;
|
||||
|
||||
const watchDog = new NavigationWatchdog(this._session, frame, navigationId, navigationURL, normalizedWaitUntil);
|
||||
const watchDog = new NavigationWatchdog(this._session, frame, this._networkManager, navigationId, navigationURL, normalizedWaitUntil);
|
||||
const error = await Promise.race([
|
||||
timeoutPromise,
|
||||
watchDog.promise(),
|
||||
@ -382,6 +376,7 @@ class Page extends EventEmitter {
|
||||
clearTimeout(timeoutId);
|
||||
if (error)
|
||||
throw error;
|
||||
return watchDog.navigationResponse();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -398,14 +393,14 @@ class Page extends EventEmitter {
|
||||
frameId: frame._frameId,
|
||||
});
|
||||
if (!navigationId)
|
||||
return;
|
||||
return null;
|
||||
|
||||
const timeoutError = new TimeoutError('Navigation Timeout Exceeded: ' + timeout + 'ms');
|
||||
let timeoutCallback;
|
||||
const timeoutPromise = new Promise(resolve => timeoutCallback = resolve.bind(null, timeoutError));
|
||||
const timeoutId = timeout ? setTimeout(timeoutCallback, timeout) : null;
|
||||
|
||||
const watchDog = new NavigationWatchdog(this._session, frame, navigationId, navigationURL, normalizedWaitUntil);
|
||||
const watchDog = new NavigationWatchdog(this._session, frame, this._networkManager, navigationId, navigationURL, normalizedWaitUntil);
|
||||
const error = await Promise.race([
|
||||
timeoutPromise,
|
||||
watchDog.promise(),
|
||||
@ -414,6 +409,7 @@ class Page extends EventEmitter {
|
||||
clearTimeout(timeoutId);
|
||||
if (error)
|
||||
throw error;
|
||||
return watchDog.navigationResponse();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -724,13 +720,14 @@ class NextNavigationWatchdog {
|
||||
* @internal
|
||||
*/
|
||||
class NavigationWatchdog {
|
||||
constructor(session, navigatedFrame, targetNavigationId, targetURL, firedEvents) {
|
||||
constructor(session, navigatedFrame, networkManager, targetNavigationId, targetURL, firedEvents) {
|
||||
this._navigatedFrame = navigatedFrame;
|
||||
this._targetNavigationId = targetNavigationId;
|
||||
this._firedEvents = firedEvents;
|
||||
this._targetURL = targetURL;
|
||||
|
||||
this._promise = new Promise(x => this._resolveCallback = x);
|
||||
this._navigationRequest = null;
|
||||
|
||||
const check = this._checkNavigationComplete.bind(this);
|
||||
this._eventListeners = [
|
||||
@ -740,10 +737,21 @@ class NavigationWatchdog {
|
||||
helper.addEventListener(session, 'Page.navigationStarted', check),
|
||||
helper.addEventListener(session, 'Page.navigationCommitted', check),
|
||||
helper.addEventListener(session, 'Page.navigationAborted', this._onNavigationAborted.bind(this)),
|
||||
helper.addEventListener(networkManager, Events.NetworkManager.Request, this._onRequest.bind(this)),
|
||||
];
|
||||
check();
|
||||
}
|
||||
|
||||
_onRequest(request) {
|
||||
if (request.frame() !== this._navigatedFrame || !request.isNavigationRequest())
|
||||
return;
|
||||
this._navigationRequest = request;
|
||||
}
|
||||
|
||||
navigationResponse() {
|
||||
return this._navigationRequest ? this._navigationRequest.response() : null;
|
||||
}
|
||||
|
||||
_checkNavigationComplete() {
|
||||
if (this._navigatedFrame._lastCommittedNavigationId === this._targetNavigationId
|
||||
&& checkFiredEvents(this._navigatedFrame, this._firedEvents)) {
|
||||
|
@ -12,6 +12,8 @@ module.exports = {
|
||||
Mouse: require('./Input').Mouse,
|
||||
Page: require('./Page').Page,
|
||||
Puppeteer: require('./Puppeteer').Puppeteer,
|
||||
Request: require('./NetworkManager').Request,
|
||||
Response: require('./NetworkManager').Response,
|
||||
Target: require('./Browser').Target,
|
||||
TimeoutError: require('./Errors').TimeoutError,
|
||||
};
|
||||
|
@ -9,7 +9,7 @@
|
||||
"node": ">=8.9.4"
|
||||
},
|
||||
"puppeteer": {
|
||||
"firefox_revision": "592ca01fa3d2566a9f494e2df8ca6876c5b5b4bb"
|
||||
"firefox_revision": "668e06245e539adf0d453b447401b8eb6e9acb44"
|
||||
},
|
||||
"scripts": {
|
||||
"install": "node install.js",
|
||||
|
@ -33,11 +33,11 @@ module.exports.addTests = function({testRunner, expect, Errors, CHROME}) {
|
||||
await page.goto(server.PREFIX + '/redirect/1.html');
|
||||
expect(page.url()).toBe(server.EMPTY_PAGE);
|
||||
});
|
||||
it_fails_ffox('should navigate to about:blank', async({page, server}) => {
|
||||
it('should navigate to about:blank', async({page, server}) => {
|
||||
const response = await page.goto('about:blank');
|
||||
expect(response).toBe(null);
|
||||
});
|
||||
it_fails_ffox('should return response when page changes its URL after load', async({page, server}) => {
|
||||
it('should return response when page changes its URL after load', async({page, server}) => {
|
||||
const response = await page.goto(server.PREFIX + '/historyapi.html');
|
||||
expect(response.status()).toBe(200);
|
||||
});
|
||||
@ -66,7 +66,7 @@ module.exports.addTests = function({testRunner, expect, Errors, CHROME}) {
|
||||
expect(response.status()).toBe(200);
|
||||
expect(response.securityDetails()).toBe(null);
|
||||
});
|
||||
it_fails_ffox('should work when page calls history API in beforeunload', async({page, server}) => {
|
||||
it('should work when page calls history API in beforeunload', async({page, server}) => {
|
||||
await page.goto(server.EMPTY_PAGE);
|
||||
await page.evaluate(() => {
|
||||
window.addEventListener('beforeunload', () => history.replaceState(null, 'initial', window.location.href), false);
|
||||
@ -90,7 +90,7 @@ module.exports.addTests = function({testRunner, expect, Errors, CHROME}) {
|
||||
else
|
||||
expect(error.message).toContain('Invalid url');
|
||||
});
|
||||
it_fails_ffox('should fail when navigating to bad SSL', async({page, httpsServer}) => {
|
||||
it('should fail when navigating to bad SSL', async({page, httpsServer}) => {
|
||||
// Make sure that network events do not emit 'undefined'.
|
||||
// @see https://crbug.com/750469
|
||||
page.on('request', request => expect(request).toBeTruthy());
|
||||
@ -98,7 +98,10 @@ module.exports.addTests = function({testRunner, expect, Errors, CHROME}) {
|
||||
page.on('requestfailed', request => expect(request).toBeTruthy());
|
||||
let error = null;
|
||||
await page.goto(httpsServer.EMPTY_PAGE).catch(e => error = e);
|
||||
expect(error.message).toContain('net::ERR_CERT_AUTHORITY_INVALID');
|
||||
if (CHROME)
|
||||
expect(error.message).toContain('net::ERR_CERT_AUTHORITY_INVALID');
|
||||
else
|
||||
expect(error.message).toContain('SSL_ERROR_UNKNOWN');
|
||||
});
|
||||
it('should fail when navigating to bad SSL after redirects', async({page, server, httpsServer}) => {
|
||||
server.setRedirect('/redirect/1.html', '/redirect/2.html');
|
||||
@ -167,7 +170,7 @@ module.exports.addTests = function({testRunner, expect, Errors, CHROME}) {
|
||||
expect(error).toBe(null);
|
||||
expect(loaded).toBe(true);
|
||||
});
|
||||
it_fails_ffox('should work when navigating to valid url', async({page, server}) => {
|
||||
it('should work when navigating to valid url', async({page, server}) => {
|
||||
const response = await page.goto(server.EMPTY_PAGE);
|
||||
expect(response.ok()).toBe(true);
|
||||
});
|
||||
@ -175,12 +178,12 @@ module.exports.addTests = function({testRunner, expect, Errors, CHROME}) {
|
||||
const response = await page.goto('data:text/html,hello');
|
||||
expect(response.ok()).toBe(true);
|
||||
});
|
||||
it_fails_ffox('should work when navigating to 404', async({page, server}) => {
|
||||
it('should work when navigating to 404', async({page, server}) => {
|
||||
const response = await page.goto(server.PREFIX + '/not-found');
|
||||
expect(response.ok()).toBe(false);
|
||||
expect(response.status()).toBe(404);
|
||||
});
|
||||
it_fails_ffox('should return last response in redirect chain', async({page, server}) => {
|
||||
it('should return last response in redirect chain', async({page, server}) => {
|
||||
server.setRedirect('/redirect/1.html', '/redirect/2.html');
|
||||
server.setRedirect('/redirect/2.html', '/redirect/3.html');
|
||||
server.setRedirect('/redirect/3.html', server.EMPTY_PAGE);
|
||||
@ -293,7 +296,7 @@ module.exports.addTests = function({testRunner, expect, Errors, CHROME}) {
|
||||
expect(requests.length).toBe(1);
|
||||
expect(requests[0].url()).toBe(server.EMPTY_PAGE);
|
||||
});
|
||||
it_fails_ffox('should work with self requesting page', async({page, server}) => {
|
||||
it('should work with self requesting page', async({page, server}) => {
|
||||
const response = await page.goto(server.PREFIX + '/self-request.html');
|
||||
expect(response.status()).toBe(200);
|
||||
expect(response.url()).toContain('self-request.html');
|
||||
@ -323,7 +326,7 @@ module.exports.addTests = function({testRunner, expect, Errors, CHROME}) {
|
||||
});
|
||||
|
||||
describe('Page.waitForNavigation', function() {
|
||||
it_fails_ffox('should work', async({page, server}) => {
|
||||
it('should work', async({page, server}) => {
|
||||
await page.goto(server.EMPTY_PAGE);
|
||||
const [response] = await Promise.all([
|
||||
page.waitForNavigation(),
|
||||
@ -352,7 +355,7 @@ module.exports.addTests = function({testRunner, expect, Errors, CHROME}) {
|
||||
await bothFiredPromise;
|
||||
await navigationPromise;
|
||||
});
|
||||
it_fails_ffox('should work with clicking on anchor links', async({page, server}) => {
|
||||
it('should work with clicking on anchor links', async({page, server}) => {
|
||||
await page.goto(server.EMPTY_PAGE);
|
||||
await page.setContent(`<a href='#foobar'>foobar</a>`);
|
||||
const [response] = await Promise.all([
|
||||
@ -362,7 +365,7 @@ module.exports.addTests = function({testRunner, expect, Errors, CHROME}) {
|
||||
expect(response).toBe(null);
|
||||
expect(page.url()).toBe(server.EMPTY_PAGE + '#foobar');
|
||||
});
|
||||
it_fails_ffox('should work with history.pushState()', async({page, server}) => {
|
||||
it('should work with history.pushState()', async({page, server}) => {
|
||||
await page.goto(server.EMPTY_PAGE);
|
||||
await page.setContent(`
|
||||
<a onclick='javascript:pushState()'>SPA</a>
|
||||
@ -377,7 +380,7 @@ module.exports.addTests = function({testRunner, expect, Errors, CHROME}) {
|
||||
expect(response).toBe(null);
|
||||
expect(page.url()).toBe(server.PREFIX + '/wow.html');
|
||||
});
|
||||
it_fails_ffox('should work with history.replaceState()', async({page, server}) => {
|
||||
it('should work with history.replaceState()', async({page, server}) => {
|
||||
await page.goto(server.EMPTY_PAGE);
|
||||
await page.setContent(`
|
||||
<a onclick='javascript:replaceState()'>SPA</a>
|
||||
@ -436,7 +439,7 @@ module.exports.addTests = function({testRunner, expect, Errors, CHROME}) {
|
||||
});
|
||||
|
||||
describe('Page.goBack', function() {
|
||||
it_fails_ffox('should work', async({page, server}) => {
|
||||
it('should work', async({page, server}) => {
|
||||
await page.goto(server.EMPTY_PAGE);
|
||||
await page.goto(server.PREFIX + '/grid.html');
|
||||
|
||||
|
@ -20,10 +20,10 @@ const utils = require('./utils');
|
||||
|
||||
module.exports.addTests = function({testRunner, expect}) {
|
||||
const {describe, xdescribe, fdescribe, describe_fails_ffox} = testRunner;
|
||||
const {it, fit, xit} = testRunner;
|
||||
const {it, fit, xit, it_fails_ffox} = testRunner;
|
||||
const {beforeAll, beforeEach, afterAll, afterEach} = testRunner;
|
||||
|
||||
describe_fails_ffox('Network Events', function() {
|
||||
describe('Network Events', function() {
|
||||
it('Page.Events.Request', async({page, server}) => {
|
||||
const requests = [];
|
||||
page.on('request', request => requests.push(request));
|
||||
@ -36,7 +36,7 @@ module.exports.addTests = function({testRunner, expect}) {
|
||||
expect(requests[0].frame() === page.mainFrame()).toBe(true);
|
||||
expect(requests[0].frame().url()).toBe(server.EMPTY_PAGE);
|
||||
});
|
||||
it('Page.Events.Request should report post data', async({page, server}) => {
|
||||
it_fails_ffox('Page.Events.Request should report post data', async({page, server}) => {
|
||||
await page.goto(server.EMPTY_PAGE);
|
||||
server.setRoute('/post', (req, res) => res.end());
|
||||
let request = null;
|
||||
@ -45,7 +45,7 @@ module.exports.addTests = function({testRunner, expect}) {
|
||||
expect(request).toBeTruthy();
|
||||
expect(request.postData()).toBe('{"foo":"bar"}');
|
||||
});
|
||||
it('Page.Events.Response', async({page, server}) => {
|
||||
it_fails_ffox('Page.Events.Response', async({page, server}) => {
|
||||
const responses = [];
|
||||
page.on('response', response => responses.push(response));
|
||||
await page.goto(server.EMPTY_PAGE);
|
||||
@ -71,7 +71,7 @@ module.exports.addTests = function({testRunner, expect}) {
|
||||
expect(response.statusText()).toBe('cool!');
|
||||
});
|
||||
|
||||
it('Response.fromCache()', async({page, server}) => {
|
||||
it_fails_ffox('Response.fromCache()', async({page, server}) => {
|
||||
const responses = new Map();
|
||||
page.on('response', r => responses.set(r.url().split('/').pop(), r));
|
||||
|
||||
@ -85,7 +85,7 @@ module.exports.addTests = function({testRunner, expect}) {
|
||||
expect(responses.get('one-style.css').status()).toBe(200);
|
||||
expect(responses.get('one-style.css').fromCache()).toBe(true);
|
||||
});
|
||||
it('Response.fromServiceWorker', async({page, server}) => {
|
||||
it_fails_ffox('Response.fromServiceWorker', async({page, server}) => {
|
||||
const responses = new Map();
|
||||
page.on('response', r => responses.set(r.url().split('/').pop(), r));
|
||||
|
||||
@ -101,7 +101,7 @@ module.exports.addTests = function({testRunner, expect}) {
|
||||
expect(responses.get('style.css').fromServiceWorker()).toBe(true);
|
||||
});
|
||||
|
||||
it('Page.Events.Response should provide body', async({page, server}) => {
|
||||
it_fails_ffox('Page.Events.Response should provide body', async({page, server}) => {
|
||||
let response = null;
|
||||
page.on('response', r => response = r);
|
||||
await page.goto(server.PREFIX + '/simple.json');
|
||||
@ -109,7 +109,7 @@ module.exports.addTests = function({testRunner, expect}) {
|
||||
expect(await response.text()).toBe('{"foo": "bar"}\n');
|
||||
expect(await response.json()).toEqual({foo: 'bar'});
|
||||
});
|
||||
it('Page.Events.Response should throw when requesting body of redirected response', async({page, server}) => {
|
||||
it_fails_ffox('Page.Events.Response should throw when requesting body of redirected response', async({page, server}) => {
|
||||
server.setRedirect('/foo.html', '/empty.html');
|
||||
const response = await page.goto(server.PREFIX + '/foo.html');
|
||||
const redirectChain = response.request().redirectChain();
|
||||
@ -120,7 +120,7 @@ module.exports.addTests = function({testRunner, expect}) {
|
||||
await redirected.text().catch(e => error = e);
|
||||
expect(error.message).toContain('Response body is unavailable for redirect responses');
|
||||
});
|
||||
it('Page.Events.Response should not report body unless request is finished', async({page, server}) => {
|
||||
it_fails_ffox('Page.Events.Response should not report body unless request is finished', async({page, server}) => {
|
||||
await page.goto(server.EMPTY_PAGE);
|
||||
// Setup server to trap request.
|
||||
let serverResponse = null;
|
||||
@ -151,7 +151,7 @@ module.exports.addTests = function({testRunner, expect}) {
|
||||
await new Promise(x => serverResponse.end('ld!', x));
|
||||
expect(await responseText).toBe('hello world!');
|
||||
});
|
||||
it('Page.Events.RequestFailed', async({page, server}) => {
|
||||
it_fails_ffox('Page.Events.RequestFailed', async({page, server}) => {
|
||||
await page.setRequestInterception(true);
|
||||
page.on('request', request => {
|
||||
if (request.url().endsWith('css'))
|
||||
@ -213,7 +213,7 @@ module.exports.addTests = function({testRunner, expect}) {
|
||||
});
|
||||
});
|
||||
|
||||
describe_fails_ffox('Request.isNavigationRequest', () => {
|
||||
describe('Request.isNavigationRequest', () => {
|
||||
it('should work', async({page, server}) => {
|
||||
const requests = new Map();
|
||||
page.on('request', request => requests.set(request.url().split('/').pop(), request));
|
||||
@ -225,7 +225,7 @@ module.exports.addTests = function({testRunner, expect}) {
|
||||
expect(requests.get('script.js').isNavigationRequest()).toBe(false);
|
||||
expect(requests.get('style.css').isNavigationRequest()).toBe(false);
|
||||
});
|
||||
it('should work with request interception', async({page, server}) => {
|
||||
it_fails_ffox('should work with request interception', async({page, server}) => {
|
||||
const requests = new Map();
|
||||
page.on('request', request => {
|
||||
requests.set(request.url().split('/').pop(), request);
|
||||
@ -632,7 +632,7 @@ module.exports.addTests = function({testRunner, expect}) {
|
||||
});
|
||||
});
|
||||
|
||||
describe_fails_ffox('Page.Events.Request', function() {
|
||||
describe('Page.Events.Request', function() {
|
||||
it('should fire', async({page, server}) => {
|
||||
const requests = [];
|
||||
page.on('request', request => requests.push(request));
|
||||
|
@ -38,7 +38,7 @@ module.exports.addTests = ({testRunner, product, puppeteer, Errors, DeviceDescri
|
||||
executablePath: CHROME ? process.env.CHROME : process.env.FFOX,
|
||||
slowMo,
|
||||
headless,
|
||||
dumpio: (process.env.DUMPIO || 'false').trim().toLowerCase() === 'true',
|
||||
dumpio: !!process.env.DUMPIO,
|
||||
};
|
||||
|
||||
if (defaultBrowserOptions.executablePath) {
|
||||
|
Loading…
Reference in New Issue
Block a user