chore: move interception API into features/ (#43)
This commit is contained in:
parent
43836c9178
commit
e3dcac1d46
229
docs/api.md
229
docs/api.md
|
|
@ -116,6 +116,7 @@
|
|||
* [page.goForward([options])](#pagegoforwardoptions)
|
||||
* [page.goto(url[, options])](#pagegotourl-options)
|
||||
* [page.hover(selector[, options])](#pagehoverselector-options)
|
||||
* [page.interception](#pageinterception)
|
||||
* [page.isClosed()](#pageisclosed)
|
||||
* [page.keyboard](#pagekeyboard)
|
||||
* [page.mainFrame()](#pagemainframe)
|
||||
|
|
@ -133,7 +134,6 @@
|
|||
* [page.setExtraHTTPHeaders(headers)](#pagesetextrahttpheadersheaders)
|
||||
* [page.setJavaScriptEnabled(enabled)](#pagesetjavascriptenabledenabled)
|
||||
* [page.setOfflineMode(enabled)](#pagesetofflinemodeenabled)
|
||||
* [page.setRequestInterception(value)](#pagesetrequestinterceptionvalue)
|
||||
* [page.setUserAgent(userAgent)](#pagesetuseragentuseragent)
|
||||
* [page.setViewport(viewport)](#pagesetviewportviewport)
|
||||
* [page.target()](#pagetarget)
|
||||
|
|
@ -233,6 +233,12 @@
|
|||
* [executionContext.evaluate(pageFunction[, ...args])](#executioncontextevaluatepagefunction-args)
|
||||
* [executionContext.evaluateHandle(pageFunction[, ...args])](#executioncontextevaluatehandlepagefunction-args)
|
||||
* [executionContext.frame()](#executioncontextframe)
|
||||
- [class: Interception](#class-interception)
|
||||
* [interception.abort(request, [errorCode])](#interceptionabortrequest-errorcode)
|
||||
* [interception.continue(request, [overrides])](#interceptioncontinuerequest-overrides)
|
||||
* [interception.disable()](#interceptiondisable)
|
||||
* [interception.enable()](#interceptionenable)
|
||||
* [interception.fulfill(request, response)](#interceptionfulfillrequest-response)
|
||||
- [class: JSHandle](#class-jshandle)
|
||||
* [jsHandle.asElement()](#jshandleaselement)
|
||||
* [jsHandle.dispose()](#jshandledispose)
|
||||
|
|
@ -272,8 +278,6 @@
|
|||
* [elementHandle.type(text[, options])](#elementhandletypetext-options)
|
||||
* [elementHandle.uploadFile(...filePaths)](#elementhandleuploadfilefilepaths)
|
||||
- [class: Request](#class-request)
|
||||
* [request.abort([errorCode])](#requestaborterrorcode)
|
||||
* [request.continue([overrides])](#requestcontinueoverrides)
|
||||
* [request.failure()](#requestfailure)
|
||||
* [request.frame()](#requestframe)
|
||||
* [request.headers()](#requestheaders)
|
||||
|
|
@ -282,7 +286,6 @@
|
|||
* [request.postData()](#requestpostdata)
|
||||
* [request.redirectChain()](#requestredirectchain)
|
||||
* [request.resourceType()](#requestresourcetype)
|
||||
* [request.respond(response)](#requestrespondresponse)
|
||||
* [request.response()](#requestresponse)
|
||||
* [request.url()](#requesturl)
|
||||
- [class: Response](#class-response)
|
||||
|
|
@ -1035,7 +1038,7 @@ const [popup] = await Promise.all([
|
|||
- <[Request]>
|
||||
|
||||
Emitted when a page issues a request. The [request] object is read-only.
|
||||
In order to intercept and mutate requests, see `page.setRequestInterception`.
|
||||
In order to intercept and mutate requests, see `page.interception.enable()`.
|
||||
|
||||
#### event: 'requestfailed'
|
||||
- <[Request]>
|
||||
|
|
@ -1604,6 +1607,9 @@ If there's no element matching `selector`, the method throws an error.
|
|||
|
||||
Shortcut for [page.mainFrame().hover(selector)](#framehoverselector).
|
||||
|
||||
#### page.interception
|
||||
- returns: <[Interception]>
|
||||
|
||||
#### page.isClosed()
|
||||
|
||||
- returns: <[boolean]>
|
||||
|
|
@ -1763,36 +1769,6 @@ The extra HTTP headers will be sent with every request the page initiates.
|
|||
- `enabled` <[boolean]> When `true`, enables offline mode for the page.
|
||||
- returns: <[Promise]>
|
||||
|
||||
#### page.setRequestInterception(value)
|
||||
- `value` <[boolean]> Whether to enable request interception.
|
||||
- returns: <[Promise]>
|
||||
|
||||
Activating request interception enables `request.abort`, `request.continue` and
|
||||
`request.respond` methods. This provides the capability to modify network requests that are made by a page.
|
||||
|
||||
Once request interception is enabled, every request will stall unless it's continued, responded or aborted.
|
||||
An example of a naïve request interceptor that aborts all image requests:
|
||||
|
||||
```js
|
||||
const playwright = require('playwright');
|
||||
|
||||
(async () => {
|
||||
const browser = await playwright.launch();
|
||||
const page = await browser.newPage();
|
||||
await page.setRequestInterception(true);
|
||||
page.on('request', interceptedRequest => {
|
||||
if (interceptedRequest.url().endsWith('.png') || interceptedRequest.url().endsWith('.jpg'))
|
||||
interceptedRequest.abort();
|
||||
else
|
||||
interceptedRequest.continue();
|
||||
});
|
||||
await page.goto('https://example.com');
|
||||
await browser.close();
|
||||
})();
|
||||
```
|
||||
|
||||
> **NOTE** Enabling request interception disables page caching.
|
||||
|
||||
#### page.setUserAgent(userAgent)
|
||||
- `userAgent` <[string]> Specific user agent to use in this page
|
||||
- returns: <[Promise]> Promise which resolves when the user agent is set.
|
||||
|
|
@ -3150,6 +3126,115 @@ await resultHandle.dispose();
|
|||
|
||||
> **NOTE** Not every execution context is associated with a frame. For example, workers and extensions have execution contexts that are not associated with frames.
|
||||
|
||||
### class: Interception
|
||||
|
||||
#### interception.abort(request, [errorCode])
|
||||
- `request` <[Request]>
|
||||
- `errorCode` <[string]> Optional error code. Defaults to `failed`, could be
|
||||
one of the following:
|
||||
- `aborted` - An operation was aborted (due to user action)
|
||||
- `accessdenied` - Permission to access a resource, other than the network, was denied
|
||||
- `addressunreachable` - The IP address is unreachable. This usually means
|
||||
that there is no route to the specified host or network.
|
||||
- `blockedbyclient` - The client chose to block the request.
|
||||
- `blockedbyresponse` - The request failed because the response was delivered along with requirements which are not met ('X-Frame-Options' and 'Content-Security-Policy' ancestor checks, for instance).
|
||||
- `connectionaborted` - A connection timed out as a result of not receiving an ACK for data sent.
|
||||
- `connectionclosed` - A connection was closed (corresponding to a TCP FIN).
|
||||
- `connectionfailed` - A connection attempt failed.
|
||||
- `connectionrefused` - A connection attempt was refused.
|
||||
- `connectionreset` - A connection was reset (corresponding to a TCP RST).
|
||||
- `internetdisconnected` - The Internet connection has been lost.
|
||||
- `namenotresolved` - The host name could not be resolved.
|
||||
- `timedout` - An operation timed out.
|
||||
- `failed` - A generic failure occurred.
|
||||
- returns: <[Promise]>
|
||||
|
||||
Aborts request. To use this, request interception should be enabled with `page.interception.enable()`.
|
||||
Exception is immediately thrown if the request interception is not enabled.
|
||||
|
||||
#### interception.continue(request, [overrides])
|
||||
- `request` <[Request]>
|
||||
- `overrides` <[Object]> Optional request overwrites, which can be one of the following:
|
||||
- `url` <[string]> If set, the request url will be changed. This is not a redirect. The request will be silently forwarded to the new url. For example, the address bar will show the original url.
|
||||
- `method` <[string]> If set changes the request method (e.g. `GET` or `POST`)
|
||||
- `postData` <[string]> If set changes the post data of request
|
||||
- `headers` <[Object]> If set changes the request HTTP headers. Header values will be converted to a string.
|
||||
- returns: <[Promise]>
|
||||
|
||||
Continues request with optional request overrides. To use this, request interception should be enabled with `page.interception.enable()`.
|
||||
Exception is immediately thrown if the request interception is not enabled.
|
||||
|
||||
```js
|
||||
await page.interception.enable();
|
||||
page.on('request', request => {
|
||||
// Override headers
|
||||
const headers = Object.assign({}, request.headers(), {
|
||||
foo: 'bar', // set "foo" header
|
||||
origin: undefined, // remove "origin" header
|
||||
});
|
||||
page.interception.continue(request, {headers});
|
||||
});
|
||||
```
|
||||
|
||||
#### interception.disable()
|
||||
|
||||
Disables network request interception.
|
||||
|
||||
#### interception.enable()
|
||||
|
||||
Once request interception is enabled, every request will stall unless it's continued, responded or aborted.
|
||||
An example of a naïve request interceptor that aborts all image requests:
|
||||
|
||||
```js
|
||||
const playwright = require('playwright');
|
||||
|
||||
(async () => {
|
||||
const browser = await playwright.launch();
|
||||
const page = await browser.newPage();
|
||||
await page.interception.enable();
|
||||
page.on('request', interceptedRequest => {
|
||||
if (interceptedRequest.url().endsWith('.png') || interceptedRequest.url().endsWith('.jpg'))
|
||||
page.interception.abort(interceptedRequest);
|
||||
else
|
||||
page.interception.continue(interceptedRequest);
|
||||
});
|
||||
await page.goto('https://example.com');
|
||||
await browser.close();
|
||||
})();
|
||||
```
|
||||
|
||||
> **NOTE** Enabling request interception disables page caching.
|
||||
|
||||
#### interception.fulfill(request, response)
|
||||
- `request` <[Request]>
|
||||
- `response` <[Object]> Response that will fulfill this request
|
||||
- `status` <[number]> Response status code, defaults to `200`.
|
||||
- `headers` <[Object]> Optional response headers. Header values will be converted to a string.
|
||||
- `contentType` <[string]> If set, equals to setting `Content-Type` response header
|
||||
- `body` <[string]|[Buffer]> Optional response body
|
||||
- returns: <[Promise]>
|
||||
|
||||
Fulfills request with given response. To use this, request interception should
|
||||
be enabled with `page.interception.enable()`. Exception is thrown if
|
||||
request interception is not enabled.
|
||||
|
||||
An example of fulfilling all requests with 404 responses:
|
||||
|
||||
```js
|
||||
await page.interception.enable();
|
||||
page.on('request', request => {
|
||||
page.interception.respond(request, {
|
||||
status: 404,
|
||||
contentType: 'text/plain',
|
||||
body: 'Not Found!'
|
||||
});
|
||||
});
|
||||
```
|
||||
|
||||
> **NOTE** Mocking responses for dataURL requests is not supported.
|
||||
> Calling `request.respond` for a dataURL request is a noop.
|
||||
|
||||
|
||||
### class: JSHandle
|
||||
|
||||
JSHandle represents an in-page JavaScript object. JSHandles can be created with the [page.evaluateHandle](#pageevaluatehandlepagefunction-args) method.
|
||||
|
|
@ -3544,52 +3629,6 @@ If request fails at some point, then instead of `'requestfinished'` event (and p
|
|||
|
||||
If request gets a 'redirect' response, the request is successfully finished with the 'requestfinished' event, and a new request is issued to a redirected url.
|
||||
|
||||
#### request.abort([errorCode])
|
||||
- `errorCode` <[string]> Optional error code. Defaults to `failed`, could be
|
||||
one of the following:
|
||||
- `aborted` - An operation was aborted (due to user action)
|
||||
- `accessdenied` - Permission to access a resource, other than the network, was denied
|
||||
- `addressunreachable` - The IP address is unreachable. This usually means
|
||||
that there is no route to the specified host or network.
|
||||
- `blockedbyclient` - The client chose to block the request.
|
||||
- `blockedbyresponse` - The request failed because the response was delivered along with requirements which are not met ('X-Frame-Options' and 'Content-Security-Policy' ancestor checks, for instance).
|
||||
- `connectionaborted` - A connection timed out as a result of not receiving an ACK for data sent.
|
||||
- `connectionclosed` - A connection was closed (corresponding to a TCP FIN).
|
||||
- `connectionfailed` - A connection attempt failed.
|
||||
- `connectionrefused` - A connection attempt was refused.
|
||||
- `connectionreset` - A connection was reset (corresponding to a TCP RST).
|
||||
- `internetdisconnected` - The Internet connection has been lost.
|
||||
- `namenotresolved` - The host name could not be resolved.
|
||||
- `timedout` - An operation timed out.
|
||||
- `failed` - A generic failure occurred.
|
||||
- returns: <[Promise]>
|
||||
|
||||
Aborts request. To use this, request interception should be enabled with `page.setRequestInterception`.
|
||||
Exception is immediately thrown if the request interception is not enabled.
|
||||
|
||||
#### request.continue([overrides])
|
||||
- `overrides` <[Object]> Optional request overwrites, which can be one of the following:
|
||||
- `url` <[string]> If set, the request url will be changed. This is not a redirect. The request will be silently forwarded to the new url. For example, the address bar will show the original url.
|
||||
- `method` <[string]> If set changes the request method (e.g. `GET` or `POST`)
|
||||
- `postData` <[string]> If set changes the post data of request
|
||||
- `headers` <[Object]> If set changes the request HTTP headers. Header values will be converted to a string.
|
||||
- returns: <[Promise]>
|
||||
|
||||
Continues request with optional request overrides. To use this, request interception should be enabled with `page.setRequestInterception`.
|
||||
Exception is immediately thrown if the request interception is not enabled.
|
||||
|
||||
```js
|
||||
await page.setRequestInterception(true);
|
||||
page.on('request', request => {
|
||||
// Override headers
|
||||
const headers = Object.assign({}, request.headers(), {
|
||||
foo: 'bar', // set "foo" header
|
||||
origin: undefined, // remove "origin" header
|
||||
});
|
||||
request.continue({headers});
|
||||
});
|
||||
```
|
||||
|
||||
#### request.failure()
|
||||
- returns: <?[Object]> Object describing request failure, if any
|
||||
- `errorText` <[string]> Human-readable error message, e.g. `'net::ERR_FAILED'`.
|
||||
|
|
@ -3655,34 +3694,6 @@ console.log(chain.length); // 0
|
|||
Contains the request's resource type as it was perceived by the rendering engine.
|
||||
ResourceType will be one of the following: `document`, `stylesheet`, `image`, `media`, `font`, `script`, `texttrack`, `xhr`, `fetch`, `eventsource`, `websocket`, `manifest`, `other`.
|
||||
|
||||
#### request.respond(response)
|
||||
- `response` <[Object]> Response that will fulfill this request
|
||||
- `status` <[number]> Response status code, defaults to `200`.
|
||||
- `headers` <[Object]> Optional response headers. Header values will be converted to a string.
|
||||
- `contentType` <[string]> If set, equals to setting `Content-Type` response header
|
||||
- `body` <[string]|[Buffer]> Optional response body
|
||||
- returns: <[Promise]>
|
||||
|
||||
Fulfills request with given response. To use this, request interception should
|
||||
be enabled with `page.setRequestInterception`. Exception is thrown if
|
||||
request interception is not enabled.
|
||||
|
||||
An example of fulfilling all requests with 404 responses:
|
||||
|
||||
```js
|
||||
await page.setRequestInterception(true);
|
||||
page.on('request', request => {
|
||||
request.respond({
|
||||
status: 404,
|
||||
contentType: 'text/plain',
|
||||
body: 'Not Found!'
|
||||
});
|
||||
});
|
||||
```
|
||||
|
||||
> **NOTE** Mocking responses for dataURL requests is not supported.
|
||||
> Calling `request.respond` for a dataURL request is a noop.
|
||||
|
||||
#### request.response()
|
||||
- returns: <?[Response]> A matching [Response] object, or `null` if the response has not been received yet.
|
||||
|
||||
|
|
|
|||
|
|
@ -21,7 +21,7 @@ const playwright = require('playwright');
|
|||
(async() => {
|
||||
const browser = await playwright.launch();
|
||||
const page = await browser.newPage();
|
||||
await page.setRequestInterception(true);
|
||||
await page.interception.enable();
|
||||
page.on('request', request => {
|
||||
if (request.resourceType() === 'image')
|
||||
request.abort();
|
||||
|
|
|
|||
|
|
@ -334,7 +334,7 @@ export class Request {
|
|||
};
|
||||
}
|
||||
|
||||
async continue(overrides: { url?: string; method?: string; postData?: string; headers?: {[key: string]: string}; } = {}) {
|
||||
async _continue(overrides: { url?: string; method?: string; postData?: string; headers?: {[key: string]: string}; } = {}) {
|
||||
// Request interception is not supported for data: urls.
|
||||
if (this._url.startsWith('data:'))
|
||||
return;
|
||||
|
|
@ -360,7 +360,7 @@ export class Request {
|
|||
});
|
||||
}
|
||||
|
||||
async respond(response: { status: number; headers: {[key: string]: string}; contentType: string; body: (string | Buffer); }) {
|
||||
async _fulfill(response: { status: number; headers: {[key: string]: string}; contentType: string; body: (string | Buffer); }) {
|
||||
// Mocking responses for dataURL requests is not currently supported.
|
||||
if (this._url.startsWith('data:'))
|
||||
return;
|
||||
|
|
@ -393,7 +393,7 @@ export class Request {
|
|||
});
|
||||
}
|
||||
|
||||
async abort(errorCode: string = 'failed') {
|
||||
async _abort(errorCode: string = 'failed') {
|
||||
// Request interception is not supported for data: urls.
|
||||
if (this._url.startsWith('data:'))
|
||||
return;
|
||||
|
|
|
|||
|
|
@ -42,6 +42,7 @@ import { TaskQueue } from './TaskQueue';
|
|||
import { Geolocation } from './features/geolocation';
|
||||
import { Tracing } from './features/tracing';
|
||||
import { Workers } from './features/workers';
|
||||
import { Interception } from './features/interception';
|
||||
|
||||
const writeFileAsync = helper.promisify(fs.writeFile);
|
||||
|
||||
|
|
@ -66,6 +67,7 @@ export class Page extends EventEmitter {
|
|||
readonly accessibility: Accessibility;
|
||||
readonly coverage: Coverage;
|
||||
readonly geolocation: Geolocation;
|
||||
readonly interception: Interception;
|
||||
readonly pdf: PDF;
|
||||
readonly workers: Workers;
|
||||
readonly tracing: Tracing;
|
||||
|
|
@ -100,6 +102,7 @@ export class Page extends EventEmitter {
|
|||
this.pdf = new PDF(client);
|
||||
this.workers = new Workers(client, this._addConsoleMessage.bind(this), this._handleException.bind(this));
|
||||
this.geolocation = new Geolocation(client);
|
||||
this.interception = new Interception(this._frameManager.networkManager());
|
||||
|
||||
this._screenshotTaskQueue = screenshotTaskQueue;
|
||||
|
||||
|
|
@ -213,10 +216,6 @@ export class Page extends EventEmitter {
|
|||
return this._frameManager.frames();
|
||||
}
|
||||
|
||||
async setRequestInterception(value: boolean) {
|
||||
return this._frameManager.networkManager().setRequestInterception(value);
|
||||
}
|
||||
|
||||
setOfflineMode(enabled: boolean) {
|
||||
return this._frameManager.networkManager().setOfflineMode(enabled);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@ export { ExecutionContext } from './ExecutionContext';
|
|||
export { Accessibility } from './features/accessibility';
|
||||
export { Coverage } from './features/coverage';
|
||||
export { Geolocation } from './features/geolocation';
|
||||
export { Interception } from './features/interception';
|
||||
export { PDF } from './features/pdf';
|
||||
export { Permissions } from './features/permissions';
|
||||
export { Tracing } from './features/tracing';
|
||||
|
|
@ -22,3 +23,4 @@ export { Request, Response } from './NetworkManager';
|
|||
export { ConsoleMessage, FileChooser, Page } from './Page';
|
||||
export { Playwright } from './Playwright';
|
||||
export { Target } from './Target';
|
||||
|
||||
|
|
|
|||
32
src/chromium/features/interception.ts
Normal file
32
src/chromium/features/interception.ts
Normal file
|
|
@ -0,0 +1,32 @@
|
|||
// Copyright (c) Microsoft Corporation.
|
||||
// Licensed under the MIT license.
|
||||
|
||||
import { NetworkManager, Request } from '../NetworkManager';
|
||||
|
||||
export class Interception {
|
||||
private _networkManager: NetworkManager;
|
||||
|
||||
constructor(networkManager: NetworkManager) {
|
||||
this._networkManager = networkManager;
|
||||
}
|
||||
|
||||
enable() {
|
||||
this._networkManager.setRequestInterception(true);
|
||||
}
|
||||
|
||||
disable() {
|
||||
this._networkManager.setRequestInterception(false);
|
||||
}
|
||||
|
||||
async continue(request: Request, overrides: { url?: string; method?: string; postData?: string; headers?: {[key: string]: string}; } = {}) {
|
||||
return request._continue(overrides);
|
||||
}
|
||||
|
||||
async fulfill(request: Request, response: { status: number; headers: {[key: string]: string}; contentType: string; body: (string | Buffer); }) {
|
||||
return request._fulfill(response);
|
||||
}
|
||||
|
||||
async abort(request: Request, errorCode: string = 'failed') {
|
||||
return request._abort(errorCode);
|
||||
}
|
||||
}
|
||||
|
|
@ -169,7 +169,7 @@ export class Request {
|
|||
return this._errorText ? {errorText: this._errorText} : null;
|
||||
}
|
||||
|
||||
async continue(overrides: any = {}) {
|
||||
async _continue(overrides: any = {}) {
|
||||
assert(!overrides.url, 'Playwright-Firefox does not support overriding URL');
|
||||
assert(!overrides.method, 'Playwright-Firefox does not support overriding method');
|
||||
assert(!overrides.postData, 'Playwright-Firefox does not support overriding postData');
|
||||
|
|
@ -187,7 +187,7 @@ export class Request {
|
|||
});
|
||||
}
|
||||
|
||||
async abort() {
|
||||
async _abort() {
|
||||
assert(this._suspended, 'Request Interception is not enabled!');
|
||||
assert(!this._interceptionHandled, 'Request is already handled!');
|
||||
this._interceptionHandled = true;
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@ import { Connection, JugglerSession, JugglerSessionEvents } from './Connection';
|
|||
import { Dialog } from './Dialog';
|
||||
import { Events } from './events';
|
||||
import { Accessibility } from './features/accessibility';
|
||||
import { Interception } from './features/interception';
|
||||
import { FrameManager, FrameManagerEvents, normalizeWaitUntil } from './FrameManager';
|
||||
import { Keyboard, Mouse } from './Input';
|
||||
import { createHandle, ElementHandle, JSHandle } from './JSHandle';
|
||||
|
|
@ -25,6 +26,7 @@ export class Page extends EventEmitter {
|
|||
private _keyboard: Keyboard;
|
||||
private _mouse: Mouse;
|
||||
readonly accessibility: Accessibility;
|
||||
readonly interception: Interception;
|
||||
private _closed: boolean;
|
||||
private _pageBindings: Map<string, Function>;
|
||||
private _networkManager: NetworkManager;
|
||||
|
|
@ -59,6 +61,7 @@ export class Page extends EventEmitter {
|
|||
this._networkManager = new NetworkManager(session);
|
||||
this._frameManager = new FrameManager(session, this, this._networkManager, this._timeoutSettings);
|
||||
this._networkManager.setFrameManager(this._frameManager);
|
||||
this.interception = new Interception(this._networkManager);
|
||||
this._eventListeners = [
|
||||
helper.addEventListener(this._session, 'Page.uncaughtError', this._onUncaughtError.bind(this)),
|
||||
helper.addEventListener(this._session, 'Runtime.console', this._onConsole.bind(this)),
|
||||
|
|
@ -137,10 +140,6 @@ export class Page extends EventEmitter {
|
|||
}
|
||||
}
|
||||
|
||||
async setRequestInterception(enabled) {
|
||||
await this._networkManager.setRequestInterception(enabled);
|
||||
}
|
||||
|
||||
async setExtraHTTPHeaders(headers) {
|
||||
await this._networkManager.setExtraHTTPHeaders(headers);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@ export { BrowserFetcher } from './BrowserFetcher';
|
|||
export { Dialog } from './Dialog';
|
||||
export { ExecutionContext } from './ExecutionContext';
|
||||
export { Accessibility } from './features/accessibility';
|
||||
export { Interception } from './features/interception';
|
||||
export { Permissions } from './features/permissions';
|
||||
export { Frame } from './FrameManager';
|
||||
export { Keyboard, Mouse } from './Input';
|
||||
|
|
@ -14,3 +15,4 @@ export { ElementHandle, JSHandle } from './JSHandle';
|
|||
export { Request, Response } from './NetworkManager';
|
||||
export { ConsoleMessage, Page } from './Page';
|
||||
export { Playwright } from './Playwright';
|
||||
|
||||
|
|
|
|||
32
src/firefox/features/interception.ts
Normal file
32
src/firefox/features/interception.ts
Normal file
|
|
@ -0,0 +1,32 @@
|
|||
// Copyright (c) Microsoft Corporation.
|
||||
// Licensed under the MIT license.
|
||||
|
||||
import { NetworkManager, Request } from '../NetworkManager';
|
||||
|
||||
export class Interception {
|
||||
private _networkManager: NetworkManager;
|
||||
|
||||
constructor(networkManager: NetworkManager) {
|
||||
this._networkManager = networkManager;
|
||||
}
|
||||
|
||||
enable() {
|
||||
this._networkManager.setRequestInterception(true);
|
||||
}
|
||||
|
||||
disable() {
|
||||
this._networkManager.setRequestInterception(false);
|
||||
}
|
||||
|
||||
async continue(request: Request, overrides: { url?: string; method?: string; postData?: string; headers?: {[key: string]: string}; } = {}) {
|
||||
return request._continue(overrides);
|
||||
}
|
||||
|
||||
async fulfill(request: Request, response: { status: number; headers: {[key: string]: string}; contentType: string; body: (string | Buffer); }) {
|
||||
throw new Error('Not implemented');
|
||||
}
|
||||
|
||||
async abort(request: Request, errorCode: string = 'failed') {
|
||||
return request._abort();
|
||||
}
|
||||
}
|
||||
|
|
@ -132,8 +132,8 @@ module.exports.addPageTests = function({testRunner, expect}) {
|
|||
res.end('console.log(1);');
|
||||
});
|
||||
|
||||
await page.setRequestInterception(true);
|
||||
page.on('request', request => request.continue());
|
||||
await page.interception.enable();
|
||||
page.on('request', request => page.interception.continue(request));
|
||||
await page.goto(server.PREFIX + '/intervention');
|
||||
// Check for feature URL substring rather than https://www.chromestatus.com to
|
||||
// make it work with Edgium.
|
||||
|
|
|
|||
|
|
@ -93,7 +93,7 @@ module.exports.addTests = function({testRunner, expect, playwright, defaultBrows
|
|||
const browser = await playwright.launch(headfulOptions);
|
||||
const page = await browser.newPage();
|
||||
await page.goto(server.EMPTY_PAGE);
|
||||
await page.setRequestInterception(true);
|
||||
await page.interception.enable();
|
||||
page.on('request', r => r.respond({body: 'YO, GOOGLE.COM'}));
|
||||
await page.evaluate(() => {
|
||||
const frame = document.createElement('iframe');
|
||||
|
|
|
|||
|
|
@ -43,7 +43,7 @@ module.exports.addTests = function({testRunner, expect, defaultBrowserOptions, p
|
|||
expect(response.ok()).toBe(true);
|
||||
});
|
||||
it('should work with request interception', async({page, server, httpsServer}) => {
|
||||
await page.setRequestInterception(true);
|
||||
await page.interception.enable();
|
||||
page.on('request', request => request.continue());
|
||||
const response = await page.goto(httpsServer.EMPTY_PAGE);
|
||||
expect(response.status()).toBe(200);
|
||||
|
|
|
|||
|
|
@ -235,7 +235,7 @@ module.exports.addTests = function({testRunner, expect, FFOX, CHROME, WEBKIT}) {
|
|||
|
||||
// FIXME: requires request interception.
|
||||
it.skip(WEBKIT)('Page.Events.RequestFailed', async({page, server}) => {
|
||||
await page.setRequestInterception(true);
|
||||
await page.interception.enable();
|
||||
page.on('request', request => {
|
||||
if (request.url().endsWith('css'))
|
||||
request.abort();
|
||||
|
|
@ -318,7 +318,7 @@ module.exports.addTests = function({testRunner, expect, FFOX, CHROME, WEBKIT}) {
|
|||
requests.set(request.url().split('/').pop(), request);
|
||||
request.continue();
|
||||
});
|
||||
await page.setRequestInterception(true);
|
||||
await page.interception.enable();
|
||||
server.setRedirect('/rrredirect', '/frames/one-frame.html');
|
||||
await page.goto(server.PREFIX + '/rrredirect');
|
||||
expect(requests.get('rrredirect').isNavigationRequest()).toBe(true);
|
||||
|
|
|
|||
|
|
@ -44,7 +44,7 @@ module.exports.addTests = function({testRunner, expect, defaultBrowserOptions, p
|
|||
expect(page.frames().length).toBe(2);
|
||||
});
|
||||
it('should load oopif iframes with subresources and request interception', async function({page, server, context}) {
|
||||
await page.setRequestInterception(true);
|
||||
await page.interception.enable();
|
||||
page.on('request', request => request.continue());
|
||||
await page.goto(server.PREFIX + '/dynamic-oopif.html');
|
||||
expect(oopifs(context).length).toBe(1);
|
||||
|
|
|
|||
|
|
@ -864,8 +864,8 @@ module.exports.addTests = function({testRunner, expect, headless, playwright, FF
|
|||
});
|
||||
it.skip(WEBKIT)('should stay disabled when toggling request interception on/off', async({page, server}) => {
|
||||
await page.setCacheEnabled(false);
|
||||
await page.setRequestInterception(true);
|
||||
await page.setRequestInterception(false);
|
||||
await page.interception.enable();
|
||||
await page.interception.disable();
|
||||
|
||||
await page.goto(server.PREFIX + '/cached/one-style.html');
|
||||
const [nonCachedRequest] = await Promise.all([
|
||||
|
|
|
|||
|
|
@ -23,12 +23,12 @@ module.exports.addTests = function({testRunner, expect, FFOX, CHROME, WEBKIT}) {
|
|||
const {it, fit, xit} = testRunner;
|
||||
const {beforeAll, beforeEach, afterAll, afterEach} = testRunner;
|
||||
|
||||
describe.skip(WEBKIT)('Page.setRequestInterception', function() {
|
||||
describe.skip(WEBKIT)('Interception.enable', function() {
|
||||
it('should intercept', async({page, server}) => {
|
||||
await page.setRequestInterception(true);
|
||||
await page.interception.enable();
|
||||
page.on('request', request => {
|
||||
if (utils.isFavicon(request)) {
|
||||
request.continue();
|
||||
page.interception.continue(request);
|
||||
return;
|
||||
}
|
||||
expect(request.url()).toContain('empty.html');
|
||||
|
|
@ -39,7 +39,7 @@ module.exports.addTests = function({testRunner, expect, FFOX, CHROME, WEBKIT}) {
|
|||
expect(request.resourceType()).toBe('document');
|
||||
expect(request.frame() === page.mainFrame()).toBe(true);
|
||||
expect(request.frame().url()).toBe('about:blank');
|
||||
request.continue();
|
||||
page.interception.continue(request);
|
||||
});
|
||||
const response = await page.goto(server.EMPTY_PAGE);
|
||||
expect(response.ok()).toBe(true);
|
||||
|
|
@ -48,8 +48,8 @@ module.exports.addTests = function({testRunner, expect, FFOX, CHROME, WEBKIT}) {
|
|||
it('should work when POST is redirected with 302', async({page, server}) => {
|
||||
server.setRedirect('/rredirect', '/empty.html');
|
||||
await page.goto(server.EMPTY_PAGE);
|
||||
await page.setRequestInterception(true);
|
||||
page.on('request', request => request.continue());
|
||||
await page.interception.enable();
|
||||
page.on('request', request => page.interception.continue(request));
|
||||
await page.setContent(`
|
||||
<form action='/rredirect' method='post'>
|
||||
<input type="hidden" id="foo" name="foo" value="FOOBAR">
|
||||
|
|
@ -63,24 +63,24 @@ module.exports.addTests = function({testRunner, expect, FFOX, CHROME, WEBKIT}) {
|
|||
// @see https://github.com/GoogleChrome/puppeteer/issues/3973
|
||||
it('should work when header manipulation headers with redirect', async({page, server}) => {
|
||||
server.setRedirect('/rrredirect', '/empty.html');
|
||||
await page.setRequestInterception(true);
|
||||
await page.interception.enable();
|
||||
page.on('request', request => {
|
||||
const headers = Object.assign({}, request.headers(), {
|
||||
foo: 'bar'
|
||||
});
|
||||
request.continue({ headers });
|
||||
page.interception.continue(request, { headers });
|
||||
});
|
||||
await page.goto(server.PREFIX + '/rrredirect');
|
||||
});
|
||||
// @see https://github.com/GoogleChrome/puppeteer/issues/4743
|
||||
it('should be able to remove headers', async({page, server}) => {
|
||||
await page.setRequestInterception(true);
|
||||
await page.interception.enable();
|
||||
page.on('request', request => {
|
||||
const headers = Object.assign({}, request.headers(), {
|
||||
foo: 'bar',
|
||||
origin: undefined, // remove "origin" header
|
||||
});
|
||||
request.continue({ headers });
|
||||
page.interception.continue(request, { headers });
|
||||
});
|
||||
|
||||
const [serverRequest] = await Promise.all([
|
||||
|
|
@ -91,12 +91,12 @@ module.exports.addTests = function({testRunner, expect, FFOX, CHROME, WEBKIT}) {
|
|||
expect(serverRequest.headers.origin).toBe(undefined);
|
||||
});
|
||||
it('should contain referer header', async({page, server}) => {
|
||||
await page.setRequestInterception(true);
|
||||
await page.interception.enable();
|
||||
const requests = [];
|
||||
page.on('request', request => {
|
||||
if (!utils.isFavicon(request))
|
||||
requests.push(request);
|
||||
request.continue();
|
||||
page.interception.continue(request);
|
||||
});
|
||||
await page.goto(server.PREFIX + '/one-style.html');
|
||||
expect(requests[1].url()).toContain('/one-style.css');
|
||||
|
|
@ -108,26 +108,26 @@ module.exports.addTests = function({testRunner, expect, FFOX, CHROME, WEBKIT}) {
|
|||
await page.setCookie({ name: 'foo', value: 'bar'});
|
||||
|
||||
// Setup request interception.
|
||||
await page.setRequestInterception(true);
|
||||
page.on('request', request => request.continue());
|
||||
await page.interception.enable();
|
||||
page.on('request', request => page.interception.continue(request));
|
||||
const response = await page.reload();
|
||||
expect(response.status()).toBe(200);
|
||||
});
|
||||
it('should stop intercepting', async({page, server}) => {
|
||||
await page.setRequestInterception(true);
|
||||
page.once('request', request => request.continue());
|
||||
await page.interception.enable();
|
||||
page.once('request', request => page.interception.continue(request));
|
||||
await page.goto(server.EMPTY_PAGE);
|
||||
await page.setRequestInterception(false);
|
||||
await page.interception.disable();
|
||||
await page.goto(server.EMPTY_PAGE);
|
||||
});
|
||||
it('should show custom HTTP headers', async({page, server}) => {
|
||||
await page.setExtraHTTPHeaders({
|
||||
foo: 'bar'
|
||||
});
|
||||
await page.setRequestInterception(true);
|
||||
await page.interception.enable();
|
||||
page.on('request', request => {
|
||||
expect(request.headers()['foo']).toBe('bar');
|
||||
request.continue();
|
||||
page.interception.continue(request);
|
||||
});
|
||||
const response = await page.goto(server.EMPTY_PAGE);
|
||||
expect(response.ok()).toBe(true);
|
||||
|
|
@ -136,8 +136,8 @@ module.exports.addTests = function({testRunner, expect, FFOX, CHROME, WEBKIT}) {
|
|||
it('should work with redirect inside sync XHR', async({page, server}) => {
|
||||
await page.goto(server.EMPTY_PAGE);
|
||||
server.setRedirect('/logo.png', '/pptr.png');
|
||||
await page.setRequestInterception(true);
|
||||
page.on('request', request => request.continue());
|
||||
await page.interception.enable();
|
||||
page.on('request', request => page.interception.continue(request));
|
||||
const status = await page.evaluate(async() => {
|
||||
const request = new XMLHttpRequest();
|
||||
request.open('GET', '/logo.png', false); // `false` makes the request synchronous
|
||||
|
|
@ -148,21 +148,21 @@ module.exports.addTests = function({testRunner, expect, FFOX, CHROME, WEBKIT}) {
|
|||
});
|
||||
it('should work with custom referer headers', async({page, server}) => {
|
||||
await page.setExtraHTTPHeaders({ 'referer': server.EMPTY_PAGE });
|
||||
await page.setRequestInterception(true);
|
||||
await page.interception.enable();
|
||||
page.on('request', request => {
|
||||
expect(request.headers()['referer']).toBe(server.EMPTY_PAGE);
|
||||
request.continue();
|
||||
page.interception.continue(request);
|
||||
});
|
||||
const response = await page.goto(server.EMPTY_PAGE);
|
||||
expect(response.ok()).toBe(true);
|
||||
});
|
||||
it('should be abortable', async({page, server}) => {
|
||||
await page.setRequestInterception(true);
|
||||
await page.interception.enable();
|
||||
page.on('request', request => {
|
||||
if (request.url().endsWith('.css'))
|
||||
request.abort();
|
||||
page.interception.abort(request);
|
||||
else
|
||||
request.continue();
|
||||
page.interception.continue(request);
|
||||
});
|
||||
let failedRequests = 0;
|
||||
page.on('requestfailed', event => ++failedRequests);
|
||||
|
|
@ -172,9 +172,9 @@ module.exports.addTests = function({testRunner, expect, FFOX, CHROME, WEBKIT}) {
|
|||
expect(failedRequests).toBe(1);
|
||||
});
|
||||
it.skip(FFOX)('should be abortable with custom error codes', async({page, server}) => {
|
||||
await page.setRequestInterception(true);
|
||||
await page.interception.enable();
|
||||
page.on('request', request => {
|
||||
request.abort('internetdisconnected');
|
||||
page.interception.abort(request, 'internetdisconnected');
|
||||
});
|
||||
let failedRequest = null;
|
||||
page.on('requestfailed', request => failedRequest = request);
|
||||
|
|
@ -186,8 +186,8 @@ module.exports.addTests = function({testRunner, expect, FFOX, CHROME, WEBKIT}) {
|
|||
await page.setExtraHTTPHeaders({
|
||||
referer: 'http://google.com/'
|
||||
});
|
||||
await page.setRequestInterception(true);
|
||||
page.on('request', request => request.continue());
|
||||
await page.interception.enable();
|
||||
page.on('request', request => page.interception.continue(request));
|
||||
const [request] = await Promise.all([
|
||||
server.waitForRequest('/grid.html'),
|
||||
page.goto(server.PREFIX + '/grid.html'),
|
||||
|
|
@ -195,8 +195,8 @@ module.exports.addTests = function({testRunner, expect, FFOX, CHROME, WEBKIT}) {
|
|||
expect(request.headers['referer']).toBe('http://google.com/');
|
||||
});
|
||||
it('should fail navigation when aborting main resource', async({page, server}) => {
|
||||
await page.setRequestInterception(true);
|
||||
page.on('request', request => request.abort());
|
||||
await page.interception.enable();
|
||||
page.on('request', request => page.interception.abort(request));
|
||||
let error = null;
|
||||
await page.goto(server.EMPTY_PAGE).catch(e => error = e);
|
||||
expect(error).toBeTruthy();
|
||||
|
|
@ -206,10 +206,10 @@ module.exports.addTests = function({testRunner, expect, FFOX, CHROME, WEBKIT}) {
|
|||
expect(error.message).toContain('NS_ERROR_FAILURE');
|
||||
});
|
||||
it('should work with redirects', async({page, server}) => {
|
||||
await page.setRequestInterception(true);
|
||||
await page.interception.enable();
|
||||
const requests = [];
|
||||
page.on('request', request => {
|
||||
request.continue();
|
||||
page.interception.continue(request);
|
||||
requests.push(request);
|
||||
});
|
||||
server.setRedirect('/non-existing-page.html', '/non-existing-page-2.html');
|
||||
|
|
@ -233,10 +233,10 @@ module.exports.addTests = function({testRunner, expect, FFOX, CHROME, WEBKIT}) {
|
|||
}
|
||||
});
|
||||
it('should work with redirects for subresources', async({page, server}) => {
|
||||
await page.setRequestInterception(true);
|
||||
await page.interception.enable();
|
||||
const requests = [];
|
||||
page.on('request', request => {
|
||||
request.continue();
|
||||
page.interception.continue(request);
|
||||
if (!utils.isFavicon(request))
|
||||
requests.push(request);
|
||||
});
|
||||
|
|
@ -258,14 +258,14 @@ module.exports.addTests = function({testRunner, expect, FFOX, CHROME, WEBKIT}) {
|
|||
expect(redirectChain[2].url()).toContain('/three-style.css');
|
||||
});
|
||||
it('should be able to abort redirects', async({page, server}) => {
|
||||
await page.setRequestInterception(true);
|
||||
await page.interception.enable();
|
||||
server.setRedirect('/non-existing.json', '/non-existing-2.json');
|
||||
server.setRedirect('/non-existing-2.json', '/simple.html');
|
||||
page.on('request', request => {
|
||||
if (request.url().includes('non-existing-2'))
|
||||
request.abort();
|
||||
page.interception.abort(request);
|
||||
else
|
||||
request.continue();
|
||||
page.interception.continue(request);
|
||||
});
|
||||
await page.goto(server.EMPTY_PAGE);
|
||||
const result = await page.evaluate(async() => {
|
||||
|
|
@ -284,16 +284,16 @@ module.exports.addTests = function({testRunner, expect, FFOX, CHROME, WEBKIT}) {
|
|||
await page.goto(server.EMPTY_PAGE);
|
||||
let responseCount = 1;
|
||||
server.setRoute('/zzz', (req, res) => res.end((responseCount++) * 11 + ''));
|
||||
await page.setRequestInterception(true);
|
||||
await page.interception.enable();
|
||||
|
||||
let spinner = false;
|
||||
// Cancel 2nd request.
|
||||
page.on('request', request => {
|
||||
if (utils.isFavicon(request)) {
|
||||
request.continue();
|
||||
page.interception.continue(request);
|
||||
return;
|
||||
}
|
||||
spinner ? request.abort() : request.continue();
|
||||
spinner ? page.interception.abort(request) : page.interception.continue(request);
|
||||
spinner = !spinner;
|
||||
});
|
||||
const results = await page.evaluate(() => Promise.all([
|
||||
|
|
@ -304,11 +304,11 @@ module.exports.addTests = function({testRunner, expect, FFOX, CHROME, WEBKIT}) {
|
|||
expect(results).toEqual(['11', 'FAILED', '22']);
|
||||
});
|
||||
it.skip(FFOX)('should navigate to dataURL and fire dataURL requests', async({page, server}) => {
|
||||
await page.setRequestInterception(true);
|
||||
await page.interception.enable();
|
||||
const requests = [];
|
||||
page.on('request', request => {
|
||||
requests.push(request);
|
||||
request.continue();
|
||||
page.interception.continue(request);
|
||||
});
|
||||
const dataURL = 'data:text/html,<div>yo</div>';
|
||||
const response = await page.goto(dataURL);
|
||||
|
|
@ -318,11 +318,11 @@ module.exports.addTests = function({testRunner, expect, FFOX, CHROME, WEBKIT}) {
|
|||
});
|
||||
it.skip(FFOX)('should be able to fetch dataURL and fire dataURL requests', async({page, server}) => {
|
||||
await page.goto(server.EMPTY_PAGE);
|
||||
await page.setRequestInterception(true);
|
||||
await page.interception.enable();
|
||||
const requests = [];
|
||||
page.on('request', request => {
|
||||
requests.push(request);
|
||||
request.continue();
|
||||
page.interception.continue(request);
|
||||
});
|
||||
const dataURL = 'data:text/html,<div>yo</div>';
|
||||
const text = await page.evaluate(url => fetch(url).then(r => r.text()), dataURL);
|
||||
|
|
@ -331,11 +331,11 @@ module.exports.addTests = function({testRunner, expect, FFOX, CHROME, WEBKIT}) {
|
|||
expect(requests[0].url()).toBe(dataURL);
|
||||
});
|
||||
it.skip(FFOX)('should navigate to URL with hash and and fire requests without hash', async({page, server}) => {
|
||||
await page.setRequestInterception(true);
|
||||
await page.interception.enable();
|
||||
const requests = [];
|
||||
page.on('request', request => {
|
||||
requests.push(request);
|
||||
request.continue();
|
||||
page.interception.continue(request);
|
||||
});
|
||||
const response = await page.goto(server.EMPTY_PAGE + '#hash');
|
||||
expect(response.status()).toBe(200);
|
||||
|
|
@ -346,25 +346,25 @@ module.exports.addTests = function({testRunner, expect, FFOX, CHROME, WEBKIT}) {
|
|||
it('should work with encoded server', async({page, server}) => {
|
||||
// The requestWillBeSent will report encoded URL, whereas interception will
|
||||
// report URL as-is. @see crbug.com/759388
|
||||
await page.setRequestInterception(true);
|
||||
page.on('request', request => request.continue());
|
||||
await page.interception.enable();
|
||||
page.on('request', request => page.interception.continue(request));
|
||||
const response = await page.goto(server.PREFIX + '/some nonexisting page');
|
||||
expect(response.status()).toBe(404);
|
||||
});
|
||||
it('should work with badly encoded server', async({page, server}) => {
|
||||
await page.setRequestInterception(true);
|
||||
await page.interception.enable();
|
||||
server.setRoute('/malformed?rnd=%911', (req, res) => res.end());
|
||||
page.on('request', request => request.continue());
|
||||
page.on('request', request => page.interception.continue(request));
|
||||
const response = await page.goto(server.PREFIX + '/malformed?rnd=%911');
|
||||
expect(response.status()).toBe(200);
|
||||
});
|
||||
it.skip(FFOX)('should work with encoded server - 2', async({page, server}) => {
|
||||
// The requestWillBeSent will report URL as-is, whereas interception will
|
||||
// report encoded URL for stylesheet. @see crbug.com/759388
|
||||
await page.setRequestInterception(true);
|
||||
await page.interception.enable();
|
||||
const requests = [];
|
||||
page.on('request', request => {
|
||||
request.continue();
|
||||
page.interception.continue(request);
|
||||
requests.push(request);
|
||||
});
|
||||
const response = await page.goto(`data:text/html,<link rel="stylesheet" href="${server.PREFIX}/fonts?helvetica|arial"/>`);
|
||||
|
|
@ -374,7 +374,7 @@ module.exports.addTests = function({testRunner, expect, FFOX, CHROME, WEBKIT}) {
|
|||
});
|
||||
it.skip(FFOX)('should not throw "Invalid Interception Id" if the request was cancelled', async({page, server}) => {
|
||||
await page.setContent('<iframe></iframe>');
|
||||
await page.setRequestInterception(true);
|
||||
await page.interception.enable();
|
||||
let request = null;
|
||||
page.on('request', async r => request = r);
|
||||
page.$eval('iframe', (frame, url) => frame.src = url, server.EMPTY_PAGE),
|
||||
|
|
@ -383,14 +383,14 @@ module.exports.addTests = function({testRunner, expect, FFOX, CHROME, WEBKIT}) {
|
|||
// Delete frame to cause request to be canceled.
|
||||
await page.$eval('iframe', frame => frame.remove());
|
||||
let error = null;
|
||||
await request.continue().catch(e => error = e);
|
||||
await page.interception.continue(request).catch(e => error = e);
|
||||
expect(error).toBe(null);
|
||||
});
|
||||
it('should throw if interception is not enabled', async({page, server}) => {
|
||||
let error = null;
|
||||
page.on('request', async request => {
|
||||
try {
|
||||
await request.continue();
|
||||
await page.interception.continue(request);
|
||||
} catch (e) {
|
||||
error = e;
|
||||
}
|
||||
|
|
@ -399,11 +399,11 @@ module.exports.addTests = function({testRunner, expect, FFOX, CHROME, WEBKIT}) {
|
|||
expect(error.message).toContain('Request Interception is not enabled');
|
||||
});
|
||||
it.skip(FFOX)('should work with file URLs', async({page, server}) => {
|
||||
await page.setRequestInterception(true);
|
||||
await page.interception.enable();
|
||||
const urls = new Set();
|
||||
page.on('request', request => {
|
||||
urls.add(request.url().split('/').pop());
|
||||
request.continue();
|
||||
page.interception.continue(request);
|
||||
});
|
||||
await page.goto(pathToFileURL(path.join(__dirname, 'assets', 'one-style.html')));
|
||||
expect(urls.size).toBe(2);
|
||||
|
|
@ -412,18 +412,18 @@ module.exports.addTests = function({testRunner, expect, FFOX, CHROME, WEBKIT}) {
|
|||
});
|
||||
});
|
||||
|
||||
describe.skip(WEBKIT)('Request.continue', function() {
|
||||
describe.skip(WEBKIT)('Interception.continue', function() {
|
||||
it('should work', async({page, server}) => {
|
||||
await page.setRequestInterception(true);
|
||||
page.on('request', request => request.continue());
|
||||
await page.interception.enable();
|
||||
page.on('request', request => page.interception.continue(request));
|
||||
await page.goto(server.EMPTY_PAGE);
|
||||
});
|
||||
it('should amend HTTP headers', async({page, server}) => {
|
||||
await page.setRequestInterception(true);
|
||||
await page.interception.enable();
|
||||
page.on('request', request => {
|
||||
const headers = Object.assign({}, request.headers());
|
||||
headers['FOO'] = 'bar';
|
||||
request.continue({ headers });
|
||||
page.interception.continue(request, { headers });
|
||||
});
|
||||
await page.goto(server.EMPTY_PAGE);
|
||||
const [request] = await Promise.all([
|
||||
|
|
@ -433,10 +433,10 @@ module.exports.addTests = function({testRunner, expect, FFOX, CHROME, WEBKIT}) {
|
|||
expect(request.headers['foo']).toBe('bar');
|
||||
});
|
||||
it.skip(FFOX)('should redirect in a way non-observable to page', async({page, server}) => {
|
||||
await page.setRequestInterception(true);
|
||||
await page.interception.enable();
|
||||
page.on('request', request => {
|
||||
const redirectURL = request.url().includes('/empty.html') ? server.PREFIX + '/consolelog.html' : undefined;
|
||||
request.continue({ url: redirectURL });
|
||||
page.interception.continue(request, { url: redirectURL });
|
||||
});
|
||||
let consoleMessage = null;
|
||||
page.on('console', msg => consoleMessage = msg);
|
||||
|
|
@ -447,9 +447,9 @@ module.exports.addTests = function({testRunner, expect, FFOX, CHROME, WEBKIT}) {
|
|||
it.skip(FFOX)('should amend method', async({page, server}) => {
|
||||
await page.goto(server.EMPTY_PAGE);
|
||||
|
||||
await page.setRequestInterception(true);
|
||||
await page.interception.enable();
|
||||
page.on('request', request => {
|
||||
request.continue({ method: 'POST' });
|
||||
page.interception.continue(request, { method: 'POST' });
|
||||
});
|
||||
const [request] = await Promise.all([
|
||||
server.waitForRequest('/sleep.zzz'),
|
||||
|
|
@ -460,9 +460,9 @@ module.exports.addTests = function({testRunner, expect, FFOX, CHROME, WEBKIT}) {
|
|||
it.skip(FFOX)('should amend post data', async({page, server}) => {
|
||||
await page.goto(server.EMPTY_PAGE);
|
||||
|
||||
await page.setRequestInterception(true);
|
||||
await page.interception.enable();
|
||||
page.on('request', request => {
|
||||
request.continue({ postData: 'doggo' });
|
||||
page.interception.continue(request, { postData: 'doggo' });
|
||||
});
|
||||
const [serverRequest] = await Promise.all([
|
||||
server.waitForRequest('/sleep.zzz'),
|
||||
|
|
@ -471,9 +471,9 @@ module.exports.addTests = function({testRunner, expect, FFOX, CHROME, WEBKIT}) {
|
|||
expect(await serverRequest.postBody).toBe('doggo');
|
||||
});
|
||||
it.skip(FFOX)('should amend both post data and method on navigation', async({page, server}) => {
|
||||
await page.setRequestInterception(true);
|
||||
await page.interception.enable();
|
||||
page.on('request', request => {
|
||||
request.continue({ method: 'POST', postData: 'doggo' });
|
||||
page.interception.continue(request, { method: 'POST', postData: 'doggo' });
|
||||
});
|
||||
const [serverRequest] = await Promise.all([
|
||||
server.waitForRequest('/empty.html'),
|
||||
|
|
@ -484,11 +484,11 @@ module.exports.addTests = function({testRunner, expect, FFOX, CHROME, WEBKIT}) {
|
|||
});
|
||||
});
|
||||
|
||||
describe.skip(FFOX || WEBKIT)('Request.respond', function() {
|
||||
describe.skip(FFOX || WEBKIT)('interception.fulfill', function() {
|
||||
it('should work', async({page, server}) => {
|
||||
await page.setRequestInterception(true);
|
||||
await page.interception.enable();
|
||||
page.on('request', request => {
|
||||
request.respond({
|
||||
page.interception.fulfill(request, {
|
||||
status: 201,
|
||||
headers: {
|
||||
foo: 'bar'
|
||||
|
|
@ -502,9 +502,9 @@ module.exports.addTests = function({testRunner, expect, FFOX, CHROME, WEBKIT}) {
|
|||
expect(await page.evaluate(() => document.body.textContent)).toBe('Yo, page!');
|
||||
});
|
||||
it('should work with status code 422', async({page, server}) => {
|
||||
await page.setRequestInterception(true);
|
||||
await page.interception.enable();
|
||||
page.on('request', request => {
|
||||
request.respond({
|
||||
page.interception.fulfill(request, {
|
||||
status: 422,
|
||||
body: 'Yo, page!'
|
||||
});
|
||||
|
|
@ -515,13 +515,13 @@ module.exports.addTests = function({testRunner, expect, FFOX, CHROME, WEBKIT}) {
|
|||
expect(await page.evaluate(() => document.body.textContent)).toBe('Yo, page!');
|
||||
});
|
||||
it('should redirect', async({page, server}) => {
|
||||
await page.setRequestInterception(true);
|
||||
await page.interception.enable();
|
||||
page.on('request', request => {
|
||||
if (!request.url().includes('rrredirect')) {
|
||||
request.continue();
|
||||
page.interception.continue(request);
|
||||
return;
|
||||
}
|
||||
request.respond({
|
||||
page.interception.fulfill(request, {
|
||||
status: 302,
|
||||
headers: {
|
||||
location: server.EMPTY_PAGE,
|
||||
|
|
@ -534,10 +534,10 @@ module.exports.addTests = function({testRunner, expect, FFOX, CHROME, WEBKIT}) {
|
|||
expect(response.url()).toBe(server.EMPTY_PAGE);
|
||||
});
|
||||
it('should allow mocking binary responses', async({page, server}) => {
|
||||
await page.setRequestInterception(true);
|
||||
await page.interception.enable();
|
||||
page.on('request', request => {
|
||||
const imageBuffer = fs.readFileSync(path.join(__dirname, 'assets', 'pptr.png'));
|
||||
request.respond({
|
||||
page.interception.fulfill(request, {
|
||||
contentType: 'image/png',
|
||||
body: imageBuffer
|
||||
});
|
||||
|
|
@ -552,9 +552,9 @@ module.exports.addTests = function({testRunner, expect, FFOX, CHROME, WEBKIT}) {
|
|||
expect(await img.screenshot()).toBeGolden('mock-binary-response.png');
|
||||
});
|
||||
it('should stringify intercepted request response headers', async({page, server}) => {
|
||||
await page.setRequestInterception(true);
|
||||
await page.interception.enable();
|
||||
page.on('request', request => {
|
||||
request.respond({
|
||||
page.interception.fulfill(request, {
|
||||
status: 200,
|
||||
headers: {
|
||||
'foo': true
|
||||
|
|
|
|||
|
|
@ -99,7 +99,7 @@ playwright.launch().then(async browser => {
|
|||
await page.emulateMedia("screen");
|
||||
await page.pdf({ path: "page.pdf" });
|
||||
|
||||
await page.setRequestInterception(true);
|
||||
await page.interception.enable();
|
||||
page.on("request", interceptedRequest => {
|
||||
if (
|
||||
interceptedRequest.url().endsWith(".png") ||
|
||||
|
|
|
|||
Loading…
Reference in a new issue