fix(webkit): fix a couple of navigation tests (#217)

This commit is contained in:
Pavel Feldman 2019-12-11 17:46:26 -08:00 committed by Dmitry Gozman
parent cdace02e62
commit 7c7c13e89d
4 changed files with 44 additions and 23 deletions

View File

@ -638,7 +638,7 @@ export class LifecycleWatcher {
frame._page._lifecycleWatchers.add(this);
this._listeners = [
helper.addEventListener(this._frame._page, Events.Page.Request, (request: network.Request) => {
if (request.frame() === this._frame && request.isNavigationRequest())
if (request.frame() === this._frame && request.isNavigationRequest() && (!this._navigationRequest || request.redirectChain().includes(this._navigationRequest)))
this._navigationRequest = request;
}),
];
@ -681,7 +681,7 @@ export class LifecycleWatcher {
}
navigationResponse(): Promise<network.Response | null> {
return this._navigationRequest ? this._navigationRequest._waitForFinishedResponse() : null;
return this._navigationRequest ? this._navigationRequest._waitForFinished() : null;
}
private _createTimeoutPromise(timeout: number): Promise<Error | null> {

View File

@ -82,6 +82,8 @@ export class Request {
private _frame: frames.Frame;
private _waitForResponsePromise: Promise<Response>;
private _waitForResponsePromiseCallback: (value?: Response) => void;
private _waitForFinishedPromise: Promise<Response | undefined>;
private _waitForFinishedPromiseCallback: (value?: Response | undefined) => void;
constructor(frame: frames.Frame | null, redirectChain: Request[], isNavigationRequest: boolean,
url: string, resourceType: string, method: string, postData: string, headers: Headers) {
@ -94,10 +96,12 @@ export class Request {
this._postData = postData;
this._headers = headers;
this._waitForResponsePromise = new Promise(f => this._waitForResponsePromiseCallback = f);
this._waitForFinishedPromise = new Promise(f => this._waitForFinishedPromiseCallback = f);
}
_setFailureText(failureText: string) {
this._failureText = failureText;
this._waitForFinishedPromiseCallback();
}
url(): string {
@ -124,15 +128,20 @@ export class Request {
return this._response;
}
async _waitForFinishedResponse(): Promise<Response> {
async _waitForFinished(): Promise<Response | undefined> {
return this._waitForFinishedPromise;
}
async _waitForResponse(): Promise<Response> {
const response = await this._waitForResponsePromise;
await response._requestFinishedPromise;
await response._finishedPromise;
return response;
}
_setResponse(response: Response) {
this._response = response;
this._waitForResponsePromiseCallback(response);
response._finishedPromise.then(() => this._waitForFinishedPromiseCallback(response));
}
frame(): frames.Frame | null {
@ -166,8 +175,8 @@ type GetResponseBodyCallback = () => Promise<Buffer>;
export class Response {
private _request: Request;
private _contentPromise: Promise<Buffer> | null = null;
_requestFinishedPromise: Promise<Error | null>;
private _requestFinishedPromiseCallback: any;
_finishedPromise: Promise<Error | null>;
private _finishedPromiseCallback: any;
private _remoteAddress: RemoteAddress;
private _status: number;
private _statusText: string;
@ -177,20 +186,20 @@ export class Response {
constructor(request: Request, status: number, statusText: string, headers: Headers, remoteAddress: RemoteAddress, getResponseBodyCallback: GetResponseBodyCallback) {
this._request = request;
this._request._setResponse(this);
this._status = status;
this._statusText = statusText;
this._url = request.url();
this._headers = headers;
this._remoteAddress = remoteAddress;
this._getResponseBodyCallback = getResponseBodyCallback;
this._requestFinishedPromise = new Promise(f => {
this._requestFinishedPromiseCallback = f;
this._finishedPromise = new Promise(f => {
this._finishedPromiseCallback = f;
});
this._request._setResponse(this);
}
_requestFinished(error?: Error) {
this._requestFinishedPromiseCallback.call(null, error);
this._finishedPromiseCallback.call(null, error);
}
remoteAddress(): RemoteAddress {
@ -219,7 +228,7 @@ export class Response {
buffer(): Promise<Buffer> {
if (!this._contentPromise) {
this._contentPromise = this._requestFinishedPromise.then(async error => {
this._contentPromise = this._finishedPromise.then(async error => {
if (error)
throw error;
return this._getResponseBodyCallback();

View File

@ -79,7 +79,7 @@ export class FrameManager extends EventEmitter implements PageDelegate {
this._page = new Page(this, browserContext);
this._networkManager.on(NetworkManagerEvents.Request, event => this._page.emit(Events.Page.Request, event));
this._networkManager.on(NetworkManagerEvents.Response, event => this._page.emit(Events.Page.Response, event));
this._networkManager.on(NetworkManagerEvents.RequestFailed, event => this._page.emit(Events.Page.RequestFailed, event));
this._networkManager.on(NetworkManagerEvents.RequestFailed, event => this._requestFailed(event));
this._networkManager.on(NetworkManagerEvents.RequestFinished, event => this._page.emit(Events.Page.RequestFinished, event));
}
@ -551,4 +551,12 @@ export class FrameManager extends EventEmitter implements PageDelegate {
async resetViewport(oldSize: types.Size): Promise<void> {
await this._session.send('Emulation.setDeviceMetricsOverride', { ...oldSize, deviceScaleFactor: 0 });
}
private _requestFailed(request: network.Request) {
if (request.isNavigationRequest() && request.failure().errorText !== 'Load request cancelled') {
request.frame()._onExpectedNewDocumentNavigation('fake-loader-id', request.url());
request.frame()._onAbortedNewDocumentNavigation('fake-loader-id', request.failure().errorText);
}
this._page.emit(Events.Page.RequestFailed, request);
}
}

View File

@ -73,7 +73,7 @@ module.exports.addTests = function({testRunner, expect, playwright, FFOX, CHROME
const response = await page.goto(server.EMPTY_PAGE, {waitUntil: 'domcontentloaded'});
expect(response.status()).toBe(200);
});
it('should work when page calls history API in beforeunload', async({page, server}) => {
it.skip(WEBKIT)('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);
@ -98,7 +98,7 @@ module.exports.addTests = function({testRunner, expect, playwright, FFOX, CHROME
else
expect(error.message).toContain('Invalid url');
});
it.skip(WEBKIT)('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());
@ -106,20 +106,22 @@ module.exports.addTests = function({testRunner, expect, playwright, FFOX, CHROME
page.on('requestfailed', request => expect(request).toBeTruthy());
let error = null;
await page.goto(httpsServer.EMPTY_PAGE).catch(e => error = e);
// FIXME: shows dialog in WebKit.
if (CHROME || WEBKIT)
if (CHROME)
expect(error.message).toContain('net::ERR_CERT_AUTHORITY_INVALID');
else if (WEBKIT)
expect(error.message).toContain('Unacceptable TLS certificate');
else
expect(error.message).toContain('SSL_ERROR_UNKNOWN');
});
it.skip(WEBKIT)('should fail when navigating to bad SSL after redirects', async({page, server, httpsServer}) => {
it('should fail when navigating to bad SSL after redirects', async({page, server, httpsServer}) => {
server.setRedirect('/redirect/1.html', '/redirect/2.html');
server.setRedirect('/redirect/2.html', '/empty.html');
let error = null;
await page.goto(httpsServer.PREFIX + '/redirect/1.html').catch(e => error = e);
// FIXME: shows dialog in WebKit.
if (CHROME || WEBKIT)
if (CHROME)
expect(error.message).toContain('net::ERR_CERT_AUTHORITY_INVALID');
else if (WEBKIT)
expect(error.message).toContain('Unacceptable TLS certificate');
else
expect(error.message).toContain('SSL_ERROR_UNKNOWN');
});
@ -128,11 +130,13 @@ module.exports.addTests = function({testRunner, expect, playwright, FFOX, CHROME
await page.goto(server.EMPTY_PAGE, {waitUntil: 'networkidle'}).catch(err => error = err);
expect(error.message).toContain('"networkidle" option is no longer supported');
});
it.skip(WEBKIT)('should fail when main resources failed to load', async({page, server}) => {
it('should fail when main resources failed to load', async({page, server}) => {
let error = null;
await page.goto('http://localhost:44123/non-existing-url').catch(e => error = e);
if (CHROME || WEBKIT)
if (CHROME)
expect(error.message).toContain('net::ERR_CONNECTION_REFUSED');
else if (WEBKIT)
expect(error.message).toContain('Could not connect: Connection refused');
else
expect(error.message).toContain('NS_ERROR_CONNECTION_REFUSED');
});
@ -311,12 +315,12 @@ module.exports.addTests = function({testRunner, expect, playwright, FFOX, CHROME
expect(requests.length).toBe(1);
expect(requests[0].url()).toBe(server.EMPTY_PAGE);
});
it.skip(WEBKIT)('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');
});
it.skip(WEBKIT)('should fail when navigating and show the url at the error message', async function({page, server, httpsServer}) {
it('should fail when navigating and show the url at the error message', async function({page, server, httpsServer}) {
const url = httpsServer.PREFIX + '/redirect/1.html';
let error = null;
try {