diff --git a/docs/api.md b/docs/api.md
index f5e531f9b7..6a915b18b8 100644
--- a/docs/api.md
+++ b/docs/api.md
@@ -3565,6 +3565,8 @@ Browser websocket endpoint which can be used as an argument to [firefoxPlaywrigh
#### webkitPlaywright.defaultArgs([options])
- `options` <[Object]> Set of configurable options to set on the browser. Can have the following fields:
+ - `headless` <[boolean]> Whether to run WebKit in headless mode. Defaults to `true`.
+ - `userDataDir` <[string]> Path to a User Data Directory, which stores browser session data like cookies and local storage.
- `args` <[Array]<[string]>> Additional arguments to pass to the browser instance.
- returns: <[Array]<[string]>>
@@ -3575,6 +3577,7 @@ The default flags that WebKit will be launched with.
- `headless` <[boolean]> Whether to run WebKit in headless mode. Defaults to `true`.
- `executablePath` <[string]> Path to a WebKit executable to run instead of the bundled WebKit. If `executablePath` is a relative path, then it is resolved relative to [current working directory](https://nodejs.org/api/process.html#process_process_cwd). **BEWARE**: Playwright is only guaranteed to work with the bundled WebKit, use at your own risk.
- `slowMo` <[number]> Slows down Playwright operations by the specified amount of milliseconds. Useful so that you can see what is going on.
+ - `userDataDir` <[string]> Path to a User Data Directory, which stores browser session data like cookies and local storage.
- `args` <[Array]<[string]>> Additional arguments to pass to the browser instance.
- `ignoreDefaultArgs` <[boolean]|[Array]<[string]>> If `true`, then do not use [`webKitPlaywright.defaultArgs()`](#webkitplaywrightdefaultargsoptions). If an array is given, then filter out the given default arguments. Dangerous option; use with care. Defaults to `false`.
- `handleSIGINT` <[boolean]> Close the browser process on Ctrl-C. Defaults to `true`.
@@ -3598,6 +3601,7 @@ const browser = await playwright.launch({
- `headless` <[boolean]> Whether to run WebKit in headless mode. Defaults to `true`.
- `executablePath` <[string]> Path to a WebKit executable to run instead of the bundled WebKit. If `executablePath` is a relative path, then it is resolved relative to [current working directory](https://nodejs.org/api/process.html#process_process_cwd). **BEWARE**: Playwright is only guaranteed to work with the bundled WebKit, use at your own risk.
- `slowMo` <[number]> Slows down Playwright operations by the specified amount of milliseconds. Useful so that you can see what is going on.
+ - `userDataDir` <[string]> Path to a User Data Directory, which stores browser session data like cookies and local storage.
- `args` <[Array]<[string]>> Additional arguments to pass to the browser instance.
- `ignoreDefaultArgs` <[boolean]|[Array]<[string]>> If `true`, then do not use [`webKitPlaywright.defaultArgs()`](#webkitplaywrightdefaultargsoptions). If an array is given, then filter out the given default arguments. Dangerous option; use with care. Defaults to `false`.
- `handleSIGINT` <[boolean]> Close the browser process on Ctrl-C. Defaults to `true`.
diff --git a/src/frames.ts b/src/frames.ts
index fccb725512..dc8546adbf 100644
--- a/src/frames.ts
+++ b/src/frames.ts
@@ -191,16 +191,19 @@ export class FrameManager {
for (const watcher of this._lifecycleWatchers)
watcher._onNavigationRequest(frame, request);
}
- this._page.emit(Events.Page.Request, request);
+ if (!request._isFavicon)
+ this._page.emit(Events.Page.Request, request);
}
requestReceivedResponse(response: network.Response) {
- this._page.emit(Events.Page.Response, response);
+ if (!response.request()._isFavicon)
+ this._page.emit(Events.Page.Response, response);
}
requestFinished(request: network.Request) {
this._inflightRequestFinished(request);
- this._page.emit(Events.Page.RequestFinished, request);
+ if (!request._isFavicon)
+ this._page.emit(Events.Page.RequestFinished, request);
}
requestFailed(request: network.Request, canceled: boolean) {
@@ -216,7 +219,8 @@ export class FrameManager {
watcher._onAbortedNewDocumentNavigation(frame, request._documentId, errorText);
}
}
- this._page.emit(Events.Page.RequestFailed, request);
+ if (!request._isFavicon)
+ this._page.emit(Events.Page.RequestFailed, request);
}
provisionalLoadFailed(documentId: string, error: string) {
@@ -236,7 +240,7 @@ export class FrameManager {
private _inflightRequestFinished(request: network.Request) {
const frame = request.frame();
- if (!frame || request.url().endsWith('favicon.ico'))
+ if (!frame || request._isFavicon)
return;
if (!frame._inflightRequests.has(request))
return;
@@ -249,7 +253,7 @@ export class FrameManager {
private _inflightRequestStarted(request: network.Request) {
const frame = request.frame();
- if (!frame || request.url().endsWith('favicon.ico'))
+ if (!frame || request._isFavicon)
return;
frame._inflightRequests.add(request);
if (frame._inflightRequests.size === 1)
diff --git a/src/network.ts b/src/network.ts
index 16312e732d..b4bea283f5 100644
--- a/src/network.ts
+++ b/src/network.ts
@@ -97,6 +97,7 @@ export class Request {
_redirectChain: Request[];
_finalRequest: Request;
readonly _documentId?: string;
+ readonly _isFavicon: boolean;
private _failureText: string | null = null;
private _url: string;
private _resourceType: string;
@@ -127,6 +128,7 @@ export class Request {
this._headers = headers;
this._waitForResponsePromise = new Promise(f => this._waitForResponsePromiseCallback = f);
this._waitForFinishedPromise = new Promise(f => this._waitForFinishedPromiseCallback = f);
+ this._isFavicon = url.endsWith('/favicon.ico');
}
_setFailureText(failureText: string) {
diff --git a/test/interception.spec.js b/test/interception.spec.js
index b9a759a7fa..b11d0309d1 100644
--- a/test/interception.spec.js
+++ b/test/interception.spec.js
@@ -28,10 +28,6 @@ module.exports.describe = function({testRunner, expect, defaultBrowserOptions, p
it('should intercept', async({page, server}) => {
await page.setRequestInterception(true);
page.on('request', request => {
- if (utils.isFavicon(request)) {
- request.continue();
- return;
- }
expect(request.url()).toContain('empty.html');
expect(request.headers()['user-agent']).toBeTruthy();
expect(request.method()).toBe('GET');
@@ -94,8 +90,7 @@ module.exports.describe = function({testRunner, expect, defaultBrowserOptions, p
await page.setRequestInterception(true);
const requests = [];
page.on('request', request => {
- if (!utils.isFavicon(request))
- requests.push(request);
+ requests.push(request);
request.continue();
});
await page.goto(server.PREFIX + '/one-style.html');
@@ -217,8 +212,7 @@ module.exports.describe = function({testRunner, expect, defaultBrowserOptions, p
const requests = [];
page.on('request', request => {
request.continue();
- if (!utils.isFavicon(request))
- requests.push(request);
+ requests.push(request);
});
server.setRedirect('/non-existing-page.html', '/non-existing-page-2.html');
server.setRedirect('/non-existing-page-2.html', '/non-existing-page-3.html');
@@ -245,8 +239,7 @@ module.exports.describe = function({testRunner, expect, defaultBrowserOptions, p
const requests = [];
page.on('request', request => {
request.continue();
- if (!utils.isFavicon(request))
- requests.push(request);
+ requests.push(request);
});
server.setRedirect('/one-style.css', '/two-style.css');
server.setRedirect('/two-style.css', '/three-style.css');
@@ -274,10 +267,6 @@ module.exports.describe = function({testRunner, expect, defaultBrowserOptions, p
let spinner = false;
// Cancel 2nd request.
page.on('request', request => {
- if (utils.isFavicon(request)) {
- request.continue();
- return;
- }
spinner ? request.abort() : request.continue();
spinner = !spinner;
});
@@ -292,8 +281,7 @@ module.exports.describe = function({testRunner, expect, defaultBrowserOptions, p
await page.setRequestInterception(true);
const requests = [];
page.on('request', request => {
- if (!utils.isFavicon(request))
- requests.push(request);
+ requests.push(request);
request.continue();
});
const dataURL = 'data:text/html,