mirror of
https://github.com/microsoft/playwright.git
synced 2025-06-26 21:40:17 +00:00
feat(popups): add BrowserContext.evaluateOnNewDocument (#1136)
This commit is contained in:
parent
dc161df063
commit
7682865d73
44
docs/api.md
44
docs/api.md
@ -268,6 +268,7 @@ await context.close();
|
|||||||
- [browserContext.clearPermissions()](#browsercontextclearpermissions)
|
- [browserContext.clearPermissions()](#browsercontextclearpermissions)
|
||||||
- [browserContext.close()](#browsercontextclose)
|
- [browserContext.close()](#browsercontextclose)
|
||||||
- [browserContext.cookies([...urls])](#browsercontextcookiesurls)
|
- [browserContext.cookies([...urls])](#browsercontextcookiesurls)
|
||||||
|
- [browserContext.evaluateOnNewDocument(pageFunction[, ...args])](#browsercontextevaluateonnewdocumentpagefunction-args)
|
||||||
- [browserContext.newPage()](#browsercontextnewpage)
|
- [browserContext.newPage()](#browsercontextnewpage)
|
||||||
- [browserContext.pages()](#browsercontextpages)
|
- [browserContext.pages()](#browsercontextpages)
|
||||||
- [browserContext.setCookies(cookies)](#browsercontextsetcookiescookies)
|
- [browserContext.setCookies(cookies)](#browsercontextsetcookiescookies)
|
||||||
@ -308,7 +309,7 @@ context.clearPermissions();
|
|||||||
Closes the browser context. All the targets that belong to the browser context
|
Closes the browser context. All the targets that belong to the browser context
|
||||||
will be closed.
|
will be closed.
|
||||||
|
|
||||||
> **NOTE** only incognito browser contexts can be closed.
|
> **NOTE** the default browser context cannot be closed.
|
||||||
|
|
||||||
#### browserContext.cookies([...urls])
|
#### browserContext.cookies([...urls])
|
||||||
- `...urls` <...[string]>
|
- `...urls` <...[string]>
|
||||||
@ -327,7 +328,29 @@ will be closed.
|
|||||||
If no URLs are specified, this method returns all cookies.
|
If no URLs are specified, this method returns all cookies.
|
||||||
If URLs are specified, only cookies that affect those URLs are returned.
|
If URLs are specified, only cookies that affect those URLs are returned.
|
||||||
|
|
||||||
> **NOTE** the default browser context cannot be closed.
|
#### browserContext.evaluateOnNewDocument(pageFunction[, ...args])
|
||||||
|
- `pageFunction` <[function]|[string]> Function to be evaluated in all pages in the browser context
|
||||||
|
- `...args` <...[Serializable]> Arguments to pass to `pageFunction`
|
||||||
|
- returns: <[Promise]>
|
||||||
|
|
||||||
|
Adds a function which would be invoked in one of the following scenarios:
|
||||||
|
- Whenever a page is created in the browser context or is navigated.
|
||||||
|
- Whenever a child frame is attached or navigated in any page in the browser context. In this case, the function is invoked in the context of the newly attached frame.
|
||||||
|
|
||||||
|
The function is invoked after the document was created but before any of its scripts were run. This is useful to amend the JavaScript environment, e.g. to seed `Math.random`.
|
||||||
|
|
||||||
|
An example of overriding `Math.random` before the page loads:
|
||||||
|
|
||||||
|
```js
|
||||||
|
// preload.js
|
||||||
|
Math.random = () => 42;
|
||||||
|
|
||||||
|
// In your playwright script, assuming the preload.js file is in same folder
|
||||||
|
const preloadFile = fs.readFileSync('./preload.js', 'utf8');
|
||||||
|
await browserContext.evaluateOnNewDocument(preloadFile);
|
||||||
|
```
|
||||||
|
|
||||||
|
> **NOTE** The order of evaluation of multiple scripts installed via [browserContext.evaluateOnNewDocument(pageFunction[, ...args])](#browsercontextevaluateonnewdocumentpagefunction-args) and [page.evaluateOnNewDocument(pageFunction[, ...args])](#pageevaluateonnewdocumentpagefunction-args) is not defined.
|
||||||
|
|
||||||
#### browserContext.newPage()
|
#### browserContext.newPage()
|
||||||
- returns: <[Promise]<[Page]>>
|
- returns: <[Promise]<[Page]>>
|
||||||
@ -944,7 +967,7 @@ await resultHandle.dispose();
|
|||||||
```
|
```
|
||||||
|
|
||||||
#### page.evaluateOnNewDocument(pageFunction[, ...args])
|
#### page.evaluateOnNewDocument(pageFunction[, ...args])
|
||||||
- `pageFunction` <[function]|[string]> Function to be evaluated in browser context
|
- `pageFunction` <[function]|[string]> Function to be evaluated in the page
|
||||||
- `...args` <...[Serializable]> Arguments to pass to `pageFunction`
|
- `...args` <...[Serializable]> Arguments to pass to `pageFunction`
|
||||||
- returns: <[Promise]>
|
- returns: <[Promise]>
|
||||||
|
|
||||||
@ -954,23 +977,19 @@ Adds a function which would be invoked in one of the following scenarios:
|
|||||||
|
|
||||||
The function is invoked after the document was created but before any of its scripts were run. This is useful to amend the JavaScript environment, e.g. to seed `Math.random`.
|
The function is invoked after the document was created but before any of its scripts were run. This is useful to amend the JavaScript environment, e.g. to seed `Math.random`.
|
||||||
|
|
||||||
An example of overriding the navigator.languages property before the page loads:
|
An example of overriding `Math.random` before the page loads:
|
||||||
|
|
||||||
```js
|
```js
|
||||||
// preload.js
|
// preload.js
|
||||||
|
Math.random = () => 42;
|
||||||
|
|
||||||
// overwrite the `languages` property to use a custom getter
|
// In your playwright script, assuming the preload.js file is in same folder
|
||||||
Object.defineProperty(navigator, "languages", {
|
|
||||||
get: function() {
|
|
||||||
return ["en-US", "en", "bn"];
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
// In your playwright script, assuming the preload.js file is in same folder of our script
|
|
||||||
const preloadFile = fs.readFileSync('./preload.js', 'utf8');
|
const preloadFile = fs.readFileSync('./preload.js', 'utf8');
|
||||||
await page.evaluateOnNewDocument(preloadFile);
|
await page.evaluateOnNewDocument(preloadFile);
|
||||||
```
|
```
|
||||||
|
|
||||||
|
> **NOTE** The order of evaluation of multiple scripts installed via [browserContext.evaluateOnNewDocument(pageFunction[, ...args])](#browsercontextevaluateonnewdocumentpagefunction-args) and [page.evaluateOnNewDocument(pageFunction[, ...args])](#pageevaluateonnewdocumentpagefunction-args) is not defined.
|
||||||
|
|
||||||
#### page.exposeFunction(name, playwrightFunction)
|
#### page.exposeFunction(name, playwrightFunction)
|
||||||
- `name` <[string]> Name of the function on the window object
|
- `name` <[string]> Name of the function on the window object
|
||||||
- `playwrightFunction` <[function]> Callback function which will be called in Playwright's context.
|
- `playwrightFunction` <[function]> Callback function which will be called in Playwright's context.
|
||||||
@ -3591,6 +3610,7 @@ const backgroundPage = await backroundPageTarget.page();
|
|||||||
- [browserContext.clearPermissions()](#browsercontextclearpermissions)
|
- [browserContext.clearPermissions()](#browsercontextclearpermissions)
|
||||||
- [browserContext.close()](#browsercontextclose)
|
- [browserContext.close()](#browsercontextclose)
|
||||||
- [browserContext.cookies([...urls])](#browsercontextcookiesurls)
|
- [browserContext.cookies([...urls])](#browsercontextcookiesurls)
|
||||||
|
- [browserContext.evaluateOnNewDocument(pageFunction[, ...args])](#browsercontextevaluateonnewdocumentpagefunction-args)
|
||||||
- [browserContext.newPage()](#browsercontextnewpage)
|
- [browserContext.newPage()](#browsercontextnewpage)
|
||||||
- [browserContext.pages()](#browsercontextpages)
|
- [browserContext.pages()](#browsercontextpages)
|
||||||
- [browserContext.setCookies(cookies)](#browsercontextsetcookiescookies)
|
- [browserContext.setCookies(cookies)](#browsercontextsetcookiescookies)
|
||||||
|
@ -9,7 +9,7 @@
|
|||||||
"main": "index.js",
|
"main": "index.js",
|
||||||
"playwright": {
|
"playwright": {
|
||||||
"chromium_revision": "744254",
|
"chromium_revision": "744254",
|
||||||
"firefox_revision": "1031",
|
"firefox_revision": "1032",
|
||||||
"webkit_revision": "1162"
|
"webkit_revision": "1162"
|
||||||
},
|
},
|
||||||
"scripts": {
|
"scripts": {
|
||||||
|
@ -46,6 +46,7 @@ export interface BrowserContext {
|
|||||||
clearPermissions(): Promise<void>;
|
clearPermissions(): Promise<void>;
|
||||||
setGeolocation(geolocation: types.Geolocation | null): Promise<void>;
|
setGeolocation(geolocation: types.Geolocation | null): Promise<void>;
|
||||||
setExtraHTTPHeaders(headers: network.Headers): Promise<void>;
|
setExtraHTTPHeaders(headers: network.Headers): Promise<void>;
|
||||||
|
evaluateOnNewDocument(pageFunction: Function | string, ...args: any[]): Promise<void>;
|
||||||
close(): Promise<void>;
|
close(): Promise<void>;
|
||||||
|
|
||||||
_existingPages(): Page[];
|
_existingPages(): Page[];
|
||||||
|
@ -187,6 +187,7 @@ export class CRBrowserContext extends platform.EventEmitter implements BrowserCo
|
|||||||
readonly _browserContextId: string | null;
|
readonly _browserContextId: string | null;
|
||||||
readonly _options: BrowserContextOptions;
|
readonly _options: BrowserContextOptions;
|
||||||
readonly _timeoutSettings: TimeoutSettings;
|
readonly _timeoutSettings: TimeoutSettings;
|
||||||
|
readonly _evaluateOnNewDocumentSources: string[];
|
||||||
private _closed = false;
|
private _closed = false;
|
||||||
|
|
||||||
constructor(browser: CRBrowser, browserContextId: string | null, options: BrowserContextOptions) {
|
constructor(browser: CRBrowser, browserContextId: string | null, options: BrowserContextOptions) {
|
||||||
@ -195,6 +196,7 @@ export class CRBrowserContext extends platform.EventEmitter implements BrowserCo
|
|||||||
this._browserContextId = browserContextId;
|
this._browserContextId = browserContextId;
|
||||||
this._timeoutSettings = new TimeoutSettings();
|
this._timeoutSettings = new TimeoutSettings();
|
||||||
this._options = options;
|
this._options = options;
|
||||||
|
this._evaluateOnNewDocumentSources = [];
|
||||||
}
|
}
|
||||||
|
|
||||||
async _initialize() {
|
async _initialize() {
|
||||||
@ -300,6 +302,13 @@ export class CRBrowserContext extends platform.EventEmitter implements BrowserCo
|
|||||||
await (page._delegate as CRPage).updateExtraHTTPHeaders();
|
await (page._delegate as CRPage).updateExtraHTTPHeaders();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async evaluateOnNewDocument(pageFunction: Function | string, ...args: any[]) {
|
||||||
|
const source = helper.evaluationString(pageFunction, ...args);
|
||||||
|
this._evaluateOnNewDocumentSources.push(source);
|
||||||
|
for (const page of this._existingPages())
|
||||||
|
await (page._delegate as CRPage).evaluateOnNewDocument(source);
|
||||||
|
}
|
||||||
|
|
||||||
async close() {
|
async close() {
|
||||||
if (this._closed)
|
if (this._closed)
|
||||||
return;
|
return;
|
||||||
|
@ -33,8 +33,7 @@ import { RawMouseImpl, RawKeyboardImpl } from './crInput';
|
|||||||
import { getAccessibilityTree } from './crAccessibility';
|
import { getAccessibilityTree } from './crAccessibility';
|
||||||
import { CRCoverage } from './crCoverage';
|
import { CRCoverage } from './crCoverage';
|
||||||
import { CRPDF } from './crPdf';
|
import { CRPDF } from './crPdf';
|
||||||
import { CRBrowser } from './crBrowser';
|
import { CRBrowser, CRBrowserContext } from './crBrowser';
|
||||||
import { BrowserContext } from '../browserContext';
|
|
||||||
import * as types from '../types';
|
import * as types from '../types';
|
||||||
import { ConsoleMessage } from '../console';
|
import { ConsoleMessage } from '../console';
|
||||||
import * as platform from '../platform';
|
import * as platform from '../platform';
|
||||||
@ -54,14 +53,16 @@ export class CRPage implements PageDelegate {
|
|||||||
private _browser: CRBrowser;
|
private _browser: CRBrowser;
|
||||||
private _pdf: CRPDF;
|
private _pdf: CRPDF;
|
||||||
private _coverage: CRCoverage;
|
private _coverage: CRCoverage;
|
||||||
|
private readonly _browserContext: CRBrowserContext;
|
||||||
|
|
||||||
constructor(client: CRSession, browser: CRBrowser, browserContext: BrowserContext) {
|
constructor(client: CRSession, browser: CRBrowser, browserContext: CRBrowserContext) {
|
||||||
this._client = client;
|
this._client = client;
|
||||||
this._browser = browser;
|
this._browser = browser;
|
||||||
this.rawKeyboard = new RawKeyboardImpl(client);
|
this.rawKeyboard = new RawKeyboardImpl(client);
|
||||||
this.rawMouse = new RawMouseImpl(client);
|
this.rawMouse = new RawMouseImpl(client);
|
||||||
this._pdf = new CRPDF(client);
|
this._pdf = new CRPDF(client);
|
||||||
this._coverage = new CRCoverage(client);
|
this._coverage = new CRCoverage(client);
|
||||||
|
this._browserContext = browserContext;
|
||||||
this._page = new Page(this, browserContext);
|
this._page = new Page(this, browserContext);
|
||||||
this._networkManager = new CRNetworkManager(client, this._page);
|
this._networkManager = new CRNetworkManager(client, this._page);
|
||||||
|
|
||||||
@ -119,6 +120,8 @@ export class CRPage implements PageDelegate {
|
|||||||
if (options.geolocation)
|
if (options.geolocation)
|
||||||
promises.push(this._client.send('Emulation.setGeolocationOverride', options.geolocation));
|
promises.push(this._client.send('Emulation.setGeolocationOverride', options.geolocation));
|
||||||
promises.push(this.updateExtraHTTPHeaders());
|
promises.push(this.updateExtraHTTPHeaders());
|
||||||
|
for (const source of this._browserContext._evaluateOnNewDocumentSources)
|
||||||
|
promises.push(this.evaluateOnNewDocument(source));
|
||||||
await Promise.all(promises);
|
await Promise.all(promises);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -33,7 +33,7 @@ import { headersArray } from './ffNetworkManager';
|
|||||||
export class FFBrowser extends platform.EventEmitter implements Browser {
|
export class FFBrowser extends platform.EventEmitter implements Browser {
|
||||||
_connection: FFConnection;
|
_connection: FFConnection;
|
||||||
_targets: Map<string, Target>;
|
_targets: Map<string, Target>;
|
||||||
readonly _defaultContext: BrowserContext;
|
readonly _defaultContext: FFBrowserContext;
|
||||||
readonly _contexts: Map<string, FFBrowserContext>;
|
readonly _contexts: Map<string, FFBrowserContext>;
|
||||||
private _eventListeners: RegisteredListener[];
|
private _eventListeners: RegisteredListener[];
|
||||||
|
|
||||||
@ -261,6 +261,7 @@ export class FFBrowserContext extends platform.EventEmitter implements BrowserCo
|
|||||||
readonly _options: BrowserContextOptions;
|
readonly _options: BrowserContextOptions;
|
||||||
readonly _timeoutSettings: TimeoutSettings;
|
readonly _timeoutSettings: TimeoutSettings;
|
||||||
private _closed = false;
|
private _closed = false;
|
||||||
|
private readonly _evaluateOnNewDocumentSources: string[];
|
||||||
|
|
||||||
constructor(browser: FFBrowser, browserContextId: string | null, options: BrowserContextOptions) {
|
constructor(browser: FFBrowser, browserContextId: string | null, options: BrowserContextOptions) {
|
||||||
super();
|
super();
|
||||||
@ -268,6 +269,7 @@ export class FFBrowserContext extends platform.EventEmitter implements BrowserCo
|
|||||||
this._browserContextId = browserContextId;
|
this._browserContextId = browserContextId;
|
||||||
this._timeoutSettings = new TimeoutSettings();
|
this._timeoutSettings = new TimeoutSettings();
|
||||||
this._options = options;
|
this._options = options;
|
||||||
|
this._evaluateOnNewDocumentSources = [];
|
||||||
}
|
}
|
||||||
|
|
||||||
async _initialize() {
|
async _initialize() {
|
||||||
@ -357,6 +359,12 @@ export class FFBrowserContext extends platform.EventEmitter implements BrowserCo
|
|||||||
await this._browser._connection.send('Browser.setExtraHTTPHeaders', { browserContextId: this._browserContextId || undefined, headers: headersArray(this._options.extraHTTPHeaders) });
|
await this._browser._connection.send('Browser.setExtraHTTPHeaders', { browserContextId: this._browserContextId || undefined, headers: headersArray(this._options.extraHTTPHeaders) });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async evaluateOnNewDocument(pageFunction: Function | string, ...args: any[]) {
|
||||||
|
const source = helper.evaluationString(pageFunction, ...args);
|
||||||
|
this._evaluateOnNewDocumentSources.push(source);
|
||||||
|
await this._browser._connection.send('Browser.addScriptToEvaluateOnNewDocument', { browserContextId: this._browserContextId || undefined, script: source });
|
||||||
|
}
|
||||||
|
|
||||||
async close() {
|
async close() {
|
||||||
if (this._closed)
|
if (this._closed)
|
||||||
return;
|
return;
|
||||||
|
@ -36,7 +36,7 @@ export class WKBrowser extends platform.EventEmitter implements Browser {
|
|||||||
private readonly _connection: WKConnection;
|
private readonly _connection: WKConnection;
|
||||||
private readonly _attachToDefaultContext: boolean;
|
private readonly _attachToDefaultContext: boolean;
|
||||||
readonly _browserSession: WKSession;
|
readonly _browserSession: WKSession;
|
||||||
readonly _defaultContext: BrowserContext;
|
readonly _defaultContext: WKBrowserContext;
|
||||||
readonly _contexts = new Map<string, WKBrowserContext>();
|
readonly _contexts = new Map<string, WKBrowserContext>();
|
||||||
readonly _pageProxies = new Map<string, WKPageProxy>();
|
readonly _pageProxies = new Map<string, WKPageProxy>();
|
||||||
private readonly _eventListeners: RegisteredListener[];
|
private readonly _eventListeners: RegisteredListener[];
|
||||||
@ -174,6 +174,7 @@ export class WKBrowserContext extends platform.EventEmitter implements BrowserCo
|
|||||||
readonly _options: BrowserContextOptions;
|
readonly _options: BrowserContextOptions;
|
||||||
readonly _timeoutSettings: TimeoutSettings;
|
readonly _timeoutSettings: TimeoutSettings;
|
||||||
private _closed = false;
|
private _closed = false;
|
||||||
|
readonly _evaluateOnNewDocumentSources: string[];
|
||||||
|
|
||||||
constructor(browser: WKBrowser, browserContextId: string | undefined, options: BrowserContextOptions) {
|
constructor(browser: WKBrowser, browserContextId: string | undefined, options: BrowserContextOptions) {
|
||||||
super();
|
super();
|
||||||
@ -181,6 +182,7 @@ export class WKBrowserContext extends platform.EventEmitter implements BrowserCo
|
|||||||
this._browserContextId = browserContextId;
|
this._browserContextId = browserContextId;
|
||||||
this._timeoutSettings = new TimeoutSettings();
|
this._timeoutSettings = new TimeoutSettings();
|
||||||
this._options = options;
|
this._options = options;
|
||||||
|
this._evaluateOnNewDocumentSources = [];
|
||||||
}
|
}
|
||||||
|
|
||||||
async _initialize() {
|
async _initialize() {
|
||||||
@ -276,6 +278,13 @@ export class WKBrowserContext extends platform.EventEmitter implements BrowserCo
|
|||||||
await (page._delegate as WKPage).updateExtraHTTPHeaders();
|
await (page._delegate as WKPage).updateExtraHTTPHeaders();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async evaluateOnNewDocument(pageFunction: Function | string, ...args: any[]) {
|
||||||
|
const source = helper.evaluationString(pageFunction, ...args);
|
||||||
|
this._evaluateOnNewDocumentSources.push(source);
|
||||||
|
for (const page of this._existingPages())
|
||||||
|
await (page._delegate as WKPage)._updateBootstrapScript();
|
||||||
|
}
|
||||||
|
|
||||||
async close() {
|
async close() {
|
||||||
if (this._closed)
|
if (this._closed)
|
||||||
return;
|
return;
|
||||||
|
@ -27,7 +27,6 @@ import { WKWorkers } from './wkWorkers';
|
|||||||
import { Page, PageDelegate } from '../page';
|
import { Page, PageDelegate } from '../page';
|
||||||
import { Protocol } from './protocol';
|
import { Protocol } from './protocol';
|
||||||
import * as dialog from '../dialog';
|
import * as dialog from '../dialog';
|
||||||
import { BrowserContext } from '../browserContext';
|
|
||||||
import { RawMouseImpl, RawKeyboardImpl } from './wkInput';
|
import { RawMouseImpl, RawKeyboardImpl } from './wkInput';
|
||||||
import * as types from '../types';
|
import * as types from '../types';
|
||||||
import * as accessibility from '../accessibility';
|
import * as accessibility from '../accessibility';
|
||||||
@ -35,6 +34,7 @@ import * as platform from '../platform';
|
|||||||
import { getAccessibilityTree } from './wkAccessibility';
|
import { getAccessibilityTree } from './wkAccessibility';
|
||||||
import { WKProvisionalPage } from './wkProvisionalPage';
|
import { WKProvisionalPage } from './wkProvisionalPage';
|
||||||
import { WKPageProxy } from './wkPageProxy';
|
import { WKPageProxy } from './wkPageProxy';
|
||||||
|
import { WKBrowserContext } from './wkBrowser';
|
||||||
|
|
||||||
const UTILITY_WORLD_NAME = '__playwright_utility_world__';
|
const UTILITY_WORLD_NAME = '__playwright_utility_world__';
|
||||||
const BINDING_CALL_MESSAGE = '__playwright_binding_call__';
|
const BINDING_CALL_MESSAGE = '__playwright_binding_call__';
|
||||||
@ -53,8 +53,9 @@ export class WKPage implements PageDelegate {
|
|||||||
private _mainFrameContextId?: number;
|
private _mainFrameContextId?: number;
|
||||||
private _sessionListeners: RegisteredListener[] = [];
|
private _sessionListeners: RegisteredListener[] = [];
|
||||||
private readonly _bootstrapScripts: string[] = [];
|
private readonly _bootstrapScripts: string[] = [];
|
||||||
|
private readonly _browserContext: WKBrowserContext;
|
||||||
|
|
||||||
constructor(browserContext: BrowserContext, pageProxySession: WKSession, opener: WKPageProxy | null) {
|
constructor(browserContext: WKBrowserContext, pageProxySession: WKSession, opener: WKPageProxy | null) {
|
||||||
this._pageProxySession = pageProxySession;
|
this._pageProxySession = pageProxySession;
|
||||||
this._opener = opener;
|
this._opener = opener;
|
||||||
this.rawKeyboard = new RawKeyboardImpl(pageProxySession);
|
this.rawKeyboard = new RawKeyboardImpl(pageProxySession);
|
||||||
@ -63,6 +64,7 @@ export class WKPage implements PageDelegate {
|
|||||||
this._page = new Page(this, browserContext);
|
this._page = new Page(this, browserContext);
|
||||||
this._workers = new WKWorkers(this._page);
|
this._workers = new WKWorkers(this._page);
|
||||||
this._session = undefined as any as WKSession;
|
this._session = undefined as any as WKSession;
|
||||||
|
this._browserContext = browserContext;
|
||||||
this._page.on(Events.Page.FrameDetached, frame => this._removeContextsForFrame(frame, false));
|
this._page.on(Events.Page.FrameDetached, frame => this._removeContextsForFrame(frame, false));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -137,10 +139,7 @@ export class WKPage implements PageDelegate {
|
|||||||
promises.push(session.send('Page.overrideUserAgent', { value: contextOptions.userAgent }));
|
promises.push(session.send('Page.overrideUserAgent', { value: contextOptions.userAgent }));
|
||||||
if (this._page._state.mediaType || this._page._state.colorScheme)
|
if (this._page._state.mediaType || this._page._state.colorScheme)
|
||||||
promises.push(WKPage._setEmulateMedia(session, this._page._state.mediaType, this._page._state.colorScheme));
|
promises.push(WKPage._setEmulateMedia(session, this._page._state.mediaType, this._page._state.colorScheme));
|
||||||
if (this._bootstrapScripts.length) {
|
promises.push(session.send('Page.setBootstrapScript', { source: this._calculateBootstrapScript() }));
|
||||||
const source = this._bootstrapScripts.join(';');
|
|
||||||
promises.push(session.send('Page.setBootstrapScript', { source }));
|
|
||||||
}
|
|
||||||
if (contextOptions.bypassCSP)
|
if (contextOptions.bypassCSP)
|
||||||
promises.push(session.send('Page.setBypassCSP', { enabled: true }));
|
promises.push(session.send('Page.setBypassCSP', { enabled: true }));
|
||||||
promises.push(session.send('Network.setExtraHTTPHeaders', { headers: this._calculateExtraHTTPHeaders() }));
|
promises.push(session.send('Network.setExtraHTTPHeaders', { headers: this._calculateExtraHTTPHeaders() }));
|
||||||
@ -465,18 +464,21 @@ export class WKPage implements PageDelegate {
|
|||||||
async exposeBinding(name: string, bindingFunction: string): Promise<void> {
|
async exposeBinding(name: string, bindingFunction: string): Promise<void> {
|
||||||
const script = `self.${name} = (param) => console.debug('${BINDING_CALL_MESSAGE}', {}, param); ${bindingFunction}`;
|
const script = `self.${name} = (param) => console.debug('${BINDING_CALL_MESSAGE}', {}, param); ${bindingFunction}`;
|
||||||
this._bootstrapScripts.unshift(script);
|
this._bootstrapScripts.unshift(script);
|
||||||
await this._setBootstrapScripts();
|
await this._updateBootstrapScript();
|
||||||
await Promise.all(this._page.frames().map(frame => frame.evaluate(script).catch(debugError)));
|
await Promise.all(this._page.frames().map(frame => frame.evaluate(script).catch(debugError)));
|
||||||
}
|
}
|
||||||
|
|
||||||
async evaluateOnNewDocument(script: string): Promise<void> {
|
async evaluateOnNewDocument(script: string): Promise<void> {
|
||||||
this._bootstrapScripts.push(script);
|
this._bootstrapScripts.push(script);
|
||||||
await this._setBootstrapScripts();
|
await this._updateBootstrapScript();
|
||||||
}
|
}
|
||||||
|
|
||||||
private async _setBootstrapScripts() {
|
private _calculateBootstrapScript(): string {
|
||||||
const source = this._bootstrapScripts.join(';');
|
return [...this._browserContext._evaluateOnNewDocumentSources, ...this._bootstrapScripts].join(';');
|
||||||
await this._updateState('Page.setBootstrapScript', { source });
|
}
|
||||||
|
|
||||||
|
async _updateBootstrapScript(): Promise<void> {
|
||||||
|
await this._updateState('Page.setBootstrapScript', { source: this._calculateBootstrapScript() });
|
||||||
}
|
}
|
||||||
|
|
||||||
async closePage(runBeforeUnload: boolean): Promise<void> {
|
async closePage(runBeforeUnload: boolean): Promise<void> {
|
||||||
|
@ -14,19 +14,19 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { BrowserContext } from '../browserContext';
|
|
||||||
import { Page } from '../page';
|
import { Page } from '../page';
|
||||||
import { Protocol } from './protocol';
|
import { Protocol } from './protocol';
|
||||||
import { WKSession } from './wkConnection';
|
import { WKSession } from './wkConnection';
|
||||||
import { WKPage } from './wkPage';
|
import { WKPage } from './wkPage';
|
||||||
import { RegisteredListener, helper, assert, debugError } from '../helper';
|
import { RegisteredListener, helper, assert, debugError } from '../helper';
|
||||||
import { Events } from '../events';
|
import { Events } from '../events';
|
||||||
|
import { WKBrowserContext } from './wkBrowser';
|
||||||
|
|
||||||
const isPovisionalSymbol = Symbol('isPovisional');
|
const isPovisionalSymbol = Symbol('isPovisional');
|
||||||
|
|
||||||
export class WKPageProxy {
|
export class WKPageProxy {
|
||||||
private readonly _pageProxySession: WKSession;
|
private readonly _pageProxySession: WKSession;
|
||||||
readonly _browserContext: BrowserContext;
|
readonly _browserContext: WKBrowserContext;
|
||||||
private readonly _opener: WKPageProxy | null;
|
private readonly _opener: WKPageProxy | null;
|
||||||
private readonly _pagePromise: Promise<Page | null>;
|
private readonly _pagePromise: Promise<Page | null>;
|
||||||
private _pagePromiseFulfill: (page: Page | null) => void = () => {};
|
private _pagePromiseFulfill: (page: Page | null) => void = () => {};
|
||||||
@ -36,7 +36,7 @@ export class WKPageProxy {
|
|||||||
private readonly _sessions = new Map<string, WKSession>();
|
private readonly _sessions = new Map<string, WKSession>();
|
||||||
private readonly _eventListeners: RegisteredListener[];
|
private readonly _eventListeners: RegisteredListener[];
|
||||||
|
|
||||||
constructor(pageProxySession: WKSession, browserContext: BrowserContext, opener: WKPageProxy | null) {
|
constructor(pageProxySession: WKSession, browserContext: WKBrowserContext, opener: WKPageProxy | null) {
|
||||||
this._pageProxySession = pageProxySession;
|
this._pageProxySession = pageProxySession;
|
||||||
this._browserContext = browserContext;
|
this._browserContext = browserContext;
|
||||||
this._opener = opener;
|
this._opener = opener;
|
||||||
|
@ -285,6 +285,24 @@ module.exports.describe = function({testRunner, expect, FFOX, CHROMIUM, WEBKIT})
|
|||||||
await page.goto(server.PREFIX + '/tamperable.html');
|
await page.goto(server.PREFIX + '/tamperable.html');
|
||||||
expect(await page.evaluate(() => window.result)).toBe(123);
|
expect(await page.evaluate(() => window.result)).toBe(123);
|
||||||
});
|
});
|
||||||
|
it('should work with browser context scripts', async({browser, server}) => {
|
||||||
|
const context = await browser.newContext();
|
||||||
|
await context.evaluateOnNewDocument(() => window.temp = 123);
|
||||||
|
const page = await context.newPage();
|
||||||
|
await page.evaluateOnNewDocument(() => window.injected = window.temp);
|
||||||
|
await page.goto(server.PREFIX + '/tamperable.html');
|
||||||
|
expect(await page.evaluate(() => window.result)).toBe(123);
|
||||||
|
await context.close();
|
||||||
|
});
|
||||||
|
it('should work with browser context scripts for already created pages', async({browser, server}) => {
|
||||||
|
const context = await browser.newContext();
|
||||||
|
const page = await context.newPage();
|
||||||
|
await context.evaluateOnNewDocument(() => window.temp = 123);
|
||||||
|
await page.evaluateOnNewDocument(() => window.injected = window.temp);
|
||||||
|
await page.goto(server.PREFIX + '/tamperable.html');
|
||||||
|
expect(await page.evaluate(() => window.result)).toBe(123);
|
||||||
|
await context.close();
|
||||||
|
});
|
||||||
it('should support multiple scripts', async({page, server}) => {
|
it('should support multiple scripts', async({page, server}) => {
|
||||||
await page.evaluateOnNewDocument(function(){
|
await page.evaluateOnNewDocument(function(){
|
||||||
window.script1 = 1;
|
window.script1 = 1;
|
||||||
|
@ -74,6 +74,18 @@ module.exports.describe = function({testRunner, expect, playwright, CHROMIUM, WE
|
|||||||
await context.close();
|
await context.close();
|
||||||
expect(size).toEqual({width: 400, height: 500});
|
expect(size).toEqual({width: 400, height: 500});
|
||||||
});
|
});
|
||||||
|
it.skip(CHROMIUM || WEBKIT)('should apply evaluateOnNewDocument from browser context', async function({browser, server}) {
|
||||||
|
const context = await browser.newContext();
|
||||||
|
await context.evaluateOnNewDocument(() => window.injected = 123);
|
||||||
|
const page = await context.newPage();
|
||||||
|
await page.goto(server.EMPTY_PAGE);
|
||||||
|
const injected = await page.evaluate(() => {
|
||||||
|
const win = window.open('about:blank');
|
||||||
|
return win.injected;
|
||||||
|
});
|
||||||
|
await context.close();
|
||||||
|
expect(injected).toBe(123);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('Page.Events.Popup', function() {
|
describe('Page.Events.Popup', function() {
|
||||||
|
@ -85,7 +85,6 @@ module.exports.describe = function({testRunner, expect, product, playwright, FFO
|
|||||||
await watchdog;
|
await watchdog;
|
||||||
});
|
});
|
||||||
it('should work when resolved right before execution context disposal', async({page, server}) => {
|
it('should work when resolved right before execution context disposal', async({page, server}) => {
|
||||||
// FIXME: implement Page.addScriptToEvaluateOnNewDocument in WebKit.
|
|
||||||
await page.evaluateOnNewDocument(() => window.__RELOADED = true);
|
await page.evaluateOnNewDocument(() => window.__RELOADED = true);
|
||||||
await page.waitForFunction(() => {
|
await page.waitForFunction(() => {
|
||||||
if (!window.__RELOADED)
|
if (!window.__RELOADED)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user