mirror of
https://github.com/microsoft/playwright.git
synced 2025-06-26 21:40:17 +00:00
feat(api): move targets from CRBrowser to CRBrowserContext (#1089)
This makes them work for default context.
This commit is contained in:
parent
de03f37a99
commit
6acc439450
106
docs/api.md
106
docs/api.md
@ -25,6 +25,7 @@
|
||||
- [class: BrowserServer](#class-browserserver)
|
||||
- [class: BrowserType](#class-browsertype)
|
||||
- [class: ChromiumBrowser](#class-chromiumbrowser)
|
||||
- [class: ChromiumBrowserContext](#class-chromiumbrowsercontext)
|
||||
- [class: ChromiumCoverage](#class-chromiumcoverage)
|
||||
- [class: ChromiumSession](#class-chromiumsession)
|
||||
- [class: ChromiumTarget](#class-chromiumtarget)
|
||||
@ -3532,15 +3533,9 @@ await browser.stopTracing();
|
||||
```
|
||||
|
||||
<!-- GEN:toc -->
|
||||
- [event: 'targetchanged'](#event-targetchanged)
|
||||
- [event: 'targetcreated'](#event-targetcreated)
|
||||
- [event: 'targetdestroyed'](#event-targetdestroyed)
|
||||
- [chromiumBrowser.browserTarget()](#chromiumbrowserbrowsertarget)
|
||||
- [chromiumBrowser.pageTarget(page)](#chromiumbrowserpagetargetpage)
|
||||
- [chromiumBrowser.startTracing(page, [options])](#chromiumbrowserstarttracingpage-options)
|
||||
- [chromiumBrowser.stopTracing()](#chromiumbrowserstoptracing)
|
||||
- [chromiumBrowser.targets(context)](#chromiumbrowsertargetscontext)
|
||||
- [chromiumBrowser.waitForTarget(predicate[, options])](#chromiumbrowserwaitfortargetpredicate-options)
|
||||
<!-- GEN:stop -->
|
||||
<!-- GEN:toc-extends-Browser -->
|
||||
- [event: 'disconnected'](#event-disconnected)
|
||||
@ -3551,37 +3546,11 @@ await browser.stopTracing();
|
||||
- [browser.newPage([options])](#browsernewpageoptions)
|
||||
<!-- GEN:stop -->
|
||||
|
||||
#### event: 'targetchanged'
|
||||
- <[ChromiumTarget]>
|
||||
|
||||
Emitted when the url of a target changes.
|
||||
|
||||
> **NOTE** This includes target changes in incognito browser contexts.
|
||||
|
||||
|
||||
#### event: 'targetcreated'
|
||||
- <[ChromiumTarget]>
|
||||
|
||||
Emitted when a target is created, for example when a new page is opened by [`window.open`](https://developer.mozilla.org/en-US/docs/Web/API/Window/open) or [`browserContext.newPage`](#browsercontextnewpage).
|
||||
|
||||
> **NOTE** This includes target creations in incognito browser contexts.
|
||||
|
||||
#### event: 'targetdestroyed'
|
||||
- <[ChromiumTarget]>
|
||||
|
||||
Emitted when a target is destroyed, for example when a page is closed.
|
||||
|
||||
> **NOTE** This includes target destructions in incognito browser contexts.
|
||||
|
||||
#### chromiumBrowser.browserTarget()
|
||||
- returns: <[ChromiumTarget]>
|
||||
|
||||
Returns browser target.
|
||||
|
||||
#### chromiumBrowser.pageTarget(page)
|
||||
- `page` <[Page]> Page to return target for.
|
||||
- returns: <[ChromiumTarget]> a target given page was created from.
|
||||
|
||||
#### chromiumBrowser.startTracing(page, [options])
|
||||
- `page` <[Page]> Optional, if specified, tracing includes screenshots of the given page.
|
||||
- `options` <[Object]>
|
||||
@ -3595,25 +3564,83 @@ Only one trace can be active at a time per browser.
|
||||
#### chromiumBrowser.stopTracing()
|
||||
- returns: <[Promise]<[Buffer]>> Promise which resolves to buffer with trace data.
|
||||
|
||||
#### chromiumBrowser.targets(context)
|
||||
- `context` <[BrowserContext]> Optional, if specified, only targets from this context are returned.
|
||||
### class: ChromiumBrowserContext
|
||||
|
||||
* extends: [BrowserContext]
|
||||
|
||||
Chromium-specific features including targets, service worker support, etc.
|
||||
|
||||
```js
|
||||
const backroundPageTarget = await context.waitForTarget(target => target.type() === 'background_page');
|
||||
const backgroundPage = await backroundPageTarget.page();
|
||||
```
|
||||
|
||||
<!-- GEN:toc -->
|
||||
- [event: 'targetchanged'](#event-targetchanged)
|
||||
- [event: 'targetcreated'](#event-targetcreated)
|
||||
- [event: 'targetdestroyed'](#event-targetdestroyed)
|
||||
- [chromiumBrowserContext.pageTarget(page)](#chromiumbrowsercontextpagetargetpage)
|
||||
- [chromiumBrowserContext.targets()](#chromiumbrowsercontexttargets)
|
||||
- [chromiumBrowserContext.waitForTarget(predicate[, options])](#chromiumbrowsercontextwaitfortargetpredicate-options)
|
||||
<!-- GEN:stop -->
|
||||
<!-- GEN:toc-extends-BrowserContext -->
|
||||
- [event: 'close'](#event-close)
|
||||
- [browserContext.clearCookies()](#browsercontextclearcookies)
|
||||
- [browserContext.clearPermissions()](#browsercontextclearpermissions)
|
||||
- [browserContext.close()](#browsercontextclose)
|
||||
- [browserContext.cookies([...urls])](#browsercontextcookiesurls)
|
||||
- [browserContext.newPage()](#browsercontextnewpage)
|
||||
- [browserContext.pages()](#browsercontextpages)
|
||||
- [browserContext.setCookies(cookies)](#browsercontextsetcookiescookies)
|
||||
- [browserContext.setDefaultNavigationTimeout(timeout)](#browsercontextsetdefaultnavigationtimeouttimeout)
|
||||
- [browserContext.setDefaultTimeout(timeout)](#browsercontextsetdefaulttimeouttimeout)
|
||||
- [browserContext.setGeolocation(geolocation)](#browsercontextsetgeolocationgeolocation)
|
||||
- [browserContext.setPermissions(origin, permissions[])](#browsercontextsetpermissionsorigin-permissions)
|
||||
<!-- GEN:stop -->
|
||||
|
||||
#### event: 'targetchanged'
|
||||
- <[ChromiumTarget]>
|
||||
|
||||
Emitted when the url of a target changes.
|
||||
|
||||
> **NOTE** Only includes targets from this browser context.
|
||||
|
||||
|
||||
#### event: 'targetcreated'
|
||||
- <[ChromiumTarget]>
|
||||
|
||||
Emitted when a target is created, for example when a new page is opened by [`window.open`](https://developer.mozilla.org/en-US/docs/Web/API/Window/open) or [`browserContext.newPage`](#browsercontextnewpage).
|
||||
|
||||
> **NOTE** Only includes targets from this browser context.
|
||||
|
||||
#### event: 'targetdestroyed'
|
||||
- <[ChromiumTarget]>
|
||||
|
||||
Emitted when a target is destroyed, for example when a page is closed.
|
||||
|
||||
> **NOTE** Only includes targets from this browser context.
|
||||
|
||||
#### chromiumBrowserContext.pageTarget(page)
|
||||
- `page` <[Page]> Page to return target for.
|
||||
- returns: <[ChromiumTarget]> a target given page was created from.
|
||||
|
||||
#### chromiumBrowserContext.targets()
|
||||
- returns: <[Array]<[ChromiumTarget]>>
|
||||
|
||||
An array of all active targets inside the Browser. In case of multiple browser contexts,
|
||||
the method will return an array with all the targets in all browser contexts.
|
||||
An array of all active targets inside the browser context.
|
||||
|
||||
#### chromiumBrowser.waitForTarget(predicate[, options])
|
||||
#### chromiumBrowserContext.waitForTarget(predicate[, options])
|
||||
- `predicate` <[function]\([ChromiumTarget]\):[boolean]> A function to be run for every target
|
||||
- `options` <[Object]>
|
||||
- `timeout` <[number]> Maximum wait time in milliseconds. Pass `0` to disable the timeout. Defaults to 30 seconds.
|
||||
- returns: <[Promise]<[ChromiumTarget]>> Promise which resolves to the first target found that matches the `predicate` function.
|
||||
|
||||
This searches for a target in all browser contexts.
|
||||
This searches for a target in the browser context.
|
||||
|
||||
An example of finding a target for a page opened via `window.open`:
|
||||
```js
|
||||
await page.evaluate(() => window.open('https://www.example.com/'));
|
||||
const newWindowTarget = await browser.chromium.waitForTarget(target => target.url() === 'https://www.example.com/');
|
||||
const newWindowTarget = await page.context().waitForTarget(target => target.url() === 'https://www.example.com/');
|
||||
```
|
||||
|
||||
### class: ChromiumCoverage
|
||||
@ -3875,6 +3902,7 @@ const { chromium } = require('playwright');
|
||||
[Buffer]: https://nodejs.org/api/buffer.html#buffer_class_buffer "Buffer"
|
||||
[ChildProcess]: https://nodejs.org/api/child_process.html "ChildProcess"
|
||||
[ChromiumBrowser]: #class-chromiumbrowser "ChromiumBrowser"
|
||||
[ChromiumBrowserContext]: #class-chromiumbrowsercontext "ChromiumBrowserContext"
|
||||
[ChromiumSession]: #class-chromiumsession "ChromiumSession"
|
||||
[ChromiumTarget]: #class-chromiumtarget "ChromiumTarget"
|
||||
[ConsoleMessage]: #class-consolemessage "ConsoleMessage"
|
||||
|
||||
@ -29,6 +29,7 @@ export { FileChooser, Page, Worker } from './page';
|
||||
export { Selectors } from './selectors';
|
||||
|
||||
export { CRBrowser as ChromiumBrowser } from './chromium/crBrowser';
|
||||
export { CRBrowserContext as ChromiumBrowserContext } from './chromium/crBrowser';
|
||||
export { CRCoverage as ChromiumCoverage } from './chromium/crCoverage';
|
||||
export { CRSession as ChromiumSession } from './chromium/crConnection';
|
||||
export { CRTarget as ChromiumTarget } from './chromium/crTarget';
|
||||
|
||||
@ -35,7 +35,7 @@ import { TimeoutSettings } from '../timeoutSettings';
|
||||
export class CRBrowser extends platform.EventEmitter implements Browser {
|
||||
_connection: CRConnection;
|
||||
_client: CRSession;
|
||||
readonly _defaultContext: BrowserContext;
|
||||
readonly _defaultContext: CRBrowserContext;
|
||||
readonly _contexts = new Map<string, CRBrowserContext>();
|
||||
_targets = new Map<string, CRTarget>();
|
||||
|
||||
@ -93,7 +93,7 @@ export class CRBrowser extends platform.EventEmitter implements Browser {
|
||||
this._targets.set(event.targetInfo.targetId, target);
|
||||
|
||||
if (target._isInitialized || await target._initializedPromise)
|
||||
this.emit(Events.CRBrowser.TargetCreated, target);
|
||||
context.emit(Events.CRBrowserContext.TargetCreated, target);
|
||||
}
|
||||
|
||||
async _targetDestroyed(event: { targetId: string; }) {
|
||||
@ -102,7 +102,7 @@ export class CRBrowser extends platform.EventEmitter implements Browser {
|
||||
this._targets.delete(event.targetId);
|
||||
target._didClose();
|
||||
if (await target._initializedPromise)
|
||||
this.emit(Events.CRBrowser.TargetDestroyed, target);
|
||||
target.context().emit(Events.CRBrowserContext.TargetDestroyed, target);
|
||||
}
|
||||
|
||||
_targetInfoChanged(event: Protocol.Target.targetInfoChangedPayload) {
|
||||
@ -112,7 +112,7 @@ export class CRBrowser extends platform.EventEmitter implements Browser {
|
||||
const wasInitialized = target._isInitialized;
|
||||
target._targetInfoChanged(event.targetInfo);
|
||||
if (wasInitialized && previousURL !== target.url())
|
||||
this.emit(Events.CRBrowser.TargetChanged, target);
|
||||
target.context().emit(Events.CRBrowserContext.TargetChanged, target);
|
||||
}
|
||||
|
||||
async _closePage(page: Page) {
|
||||
@ -123,32 +123,6 @@ export class CRBrowser extends platform.EventEmitter implements Browser {
|
||||
return Array.from(this._targets.values()).filter(target => target._isInitialized);
|
||||
}
|
||||
|
||||
async waitForTarget(predicate: (arg0: CRTarget) => boolean, options: { timeout?: number; } | undefined = {}): Promise<CRTarget> {
|
||||
const {
|
||||
timeout = 30000
|
||||
} = options;
|
||||
const existingTarget = this._allTargets().find(predicate);
|
||||
if (existingTarget)
|
||||
return existingTarget;
|
||||
let resolve: (target: CRTarget) => void;
|
||||
const targetPromise = new Promise<CRTarget>(x => resolve = x);
|
||||
this.on(Events.CRBrowser.TargetCreated, check);
|
||||
this.on(Events.CRBrowser.TargetChanged, check);
|
||||
try {
|
||||
if (!timeout)
|
||||
return await targetPromise;
|
||||
return await helper.waitWithTimeout(targetPromise, 'target', timeout);
|
||||
} finally {
|
||||
this.removeListener(Events.CRBrowser.TargetCreated, check);
|
||||
this.removeListener(Events.CRBrowser.TargetChanged, check);
|
||||
}
|
||||
|
||||
function check(target: CRTarget) {
|
||||
if (predicate(target))
|
||||
resolve(target);
|
||||
}
|
||||
}
|
||||
|
||||
async close() {
|
||||
const disconnected = new Promise(f => this._connection.once(ConnectionEvents.Disconnected, f));
|
||||
await Promise.all(this.contexts().map(context => context.close()));
|
||||
@ -199,15 +173,6 @@ export class CRBrowser extends platform.EventEmitter implements Browser {
|
||||
return contentPromise;
|
||||
}
|
||||
|
||||
targets(context?: BrowserContext): CRTarget[] {
|
||||
const targets = this._allTargets();
|
||||
return context ? targets.filter(t => t.context() === context) : targets;
|
||||
}
|
||||
|
||||
pageTarget(page: Page): CRTarget {
|
||||
return CRTarget.fromPage(page);
|
||||
}
|
||||
|
||||
isConnected(): boolean {
|
||||
return !this._connection._closed;
|
||||
}
|
||||
@ -339,6 +304,38 @@ export class CRBrowserContext extends platform.EventEmitter implements BrowserCo
|
||||
this.emit(CommonEvents.BrowserContext.Close);
|
||||
}
|
||||
|
||||
pageTarget(page: Page): CRTarget {
|
||||
return CRTarget.fromPage(page);
|
||||
}
|
||||
|
||||
targets(): CRTarget[] {
|
||||
return this._browser._allTargets().filter(t => t.context() === this);
|
||||
}
|
||||
|
||||
async waitForTarget(predicate: (arg0: CRTarget) => boolean, options: { timeout?: number; } = {}): Promise<CRTarget> {
|
||||
const { timeout = 30000 } = options;
|
||||
const existingTarget = this._browser._allTargets().find(predicate);
|
||||
if (existingTarget)
|
||||
return existingTarget;
|
||||
let resolve: (target: CRTarget) => void;
|
||||
const targetPromise = new Promise<CRTarget>(x => resolve = x);
|
||||
this.on(Events.CRBrowserContext.TargetCreated, check);
|
||||
this.on(Events.CRBrowserContext.TargetChanged, check);
|
||||
try {
|
||||
if (!timeout)
|
||||
return await targetPromise;
|
||||
return await helper.waitWithTimeout(targetPromise, 'target', timeout);
|
||||
} finally {
|
||||
this.removeListener(Events.CRBrowserContext.TargetCreated, check);
|
||||
this.removeListener(Events.CRBrowserContext.TargetChanged, check);
|
||||
}
|
||||
|
||||
function check(target: CRTarget) {
|
||||
if (predicate(target))
|
||||
resolve(target);
|
||||
}
|
||||
}
|
||||
|
||||
_browserClosed() {
|
||||
this._closed = true;
|
||||
for (const page of this._existingPages())
|
||||
|
||||
@ -15,8 +15,7 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { CRBrowser } from './crBrowser';
|
||||
import { BrowserContext } from '../browserContext';
|
||||
import { CRBrowser, CRBrowserContext } from './crBrowser';
|
||||
import { CRSession, CRSessionEvents } from './crConnection';
|
||||
import { Events } from '../events';
|
||||
import { Page, Worker } from '../page';
|
||||
@ -30,7 +29,7 @@ const targetSymbol = Symbol('target');
|
||||
export class CRTarget {
|
||||
private _targetInfo: Protocol.Target.TargetInfo;
|
||||
private readonly _browser: CRBrowser;
|
||||
private readonly _browserContext: BrowserContext;
|
||||
private readonly _browserContext: CRBrowserContext;
|
||||
readonly _targetId: string;
|
||||
private _sessionFactory: () => Promise<CRSession>;
|
||||
private _pagePromise: Promise<Page> | null = null;
|
||||
@ -47,7 +46,7 @@ export class CRTarget {
|
||||
constructor(
|
||||
browser: CRBrowser,
|
||||
targetInfo: Protocol.Target.TargetInfo,
|
||||
browserContext: BrowserContext,
|
||||
browserContext: CRBrowserContext,
|
||||
sessionFactory: () => Promise<CRSession>) {
|
||||
this._targetInfo = targetInfo;
|
||||
this._browser = browser;
|
||||
@ -120,7 +119,7 @@ export class CRTarget {
|
||||
return 'other';
|
||||
}
|
||||
|
||||
context(): BrowserContext {
|
||||
context(): CRBrowserContext {
|
||||
return this._browserContext;
|
||||
}
|
||||
|
||||
|
||||
@ -16,7 +16,7 @@
|
||||
*/
|
||||
|
||||
export const Events = {
|
||||
CRBrowser: {
|
||||
CRBrowserContext: {
|
||||
TargetCreated: 'targetcreated',
|
||||
TargetDestroyed: 'targetdestroyed',
|
||||
TargetChanged: 'targetchanged',
|
||||
|
||||
@ -68,7 +68,7 @@ export class Chromium implements BrowserType {
|
||||
const { timeout = 30000 } = options || {};
|
||||
const { browserServer, transport } = await this._launchServer(options, 'persistent', userDataDir);
|
||||
const browser = await CRBrowser.connect(transport!);
|
||||
await helper.waitWithTimeout(browser.waitForTarget(t => t.type() === 'page'), 'first page', timeout);
|
||||
await helper.waitWithTimeout(browser._defaultContext.waitForTarget(t => t.type() === 'page'), 'first page', timeout);
|
||||
// Hack: for typical launch scenario, ensure that close waits for actual process termination.
|
||||
const browserContext = browser._defaultContext;
|
||||
browserContext.close = () => browserServer.close();
|
||||
|
||||
@ -38,11 +38,11 @@ module.exports.describe = function({testRunner, expect, playwright, CHROMIUM, WE
|
||||
const context = await browser.newContext();
|
||||
const page = await context.newPage();
|
||||
await page.goto(server.EMPTY_PAGE);
|
||||
const [popupTarget] = await Promise.all([
|
||||
const [popup] = await Promise.all([
|
||||
utils.waitEvent(page, 'popup'),
|
||||
page.evaluate(url => window.open(url), server.EMPTY_PAGE)
|
||||
]);
|
||||
expect(popupTarget.context()).toBe(context);
|
||||
expect(popup.context()).toBe(context);
|
||||
await context.close();
|
||||
});
|
||||
it('should isolate localStorage and cookies', async function({browser, server}) {
|
||||
|
||||
@ -25,28 +25,31 @@ module.exports.describe = function({testRunner, expect, playwright, FFOX, CHROMI
|
||||
const {beforeAll, beforeEach, afterAll, afterEach} = testRunner;
|
||||
|
||||
describe('Target', function() {
|
||||
it('Chromium.targets should return all of the targets', async({page, server, browser}) => {
|
||||
// The pages will be the testing page and the original newtab page
|
||||
const targets = browser.targets();
|
||||
expect(targets.some(target => target.type() === 'page' &&
|
||||
target.url() === 'about:blank')).toBeTruthy('Missing blank page');
|
||||
expect(targets.some(target => target.type() === 'browser')).toBeTruthy('Missing browser target');
|
||||
it('ChromiumBrowserContext.targets should return all of the targets', async({page, server, browser}) => {
|
||||
const second = await page.context().newPage();
|
||||
await second.goto(server.EMPTY_PAGE);
|
||||
const targets = page.context().targets();
|
||||
// The pages will be the testing page from the harness and the one created here.
|
||||
expect(targets.length).toBe(2);
|
||||
expect(targets.some(target => target.type() !== 'page')).toBe(false);
|
||||
expect(targets.some(target => target.url() === 'about:blank')).toBeTruthy('Missing blank page');
|
||||
expect(targets.some(target => target.url() === server.EMPTY_PAGE)).toBeTruthy('Missing new page');
|
||||
await second.close();
|
||||
});
|
||||
it('Browser.pages should return all of the pages', async({page, server, context}) => {
|
||||
// The pages will be the testing page
|
||||
it('BrowserContext.pages should return all of the pages', async({page, server, context}) => {
|
||||
const second = await page.context().newPage();
|
||||
const allPages = await context.pages();
|
||||
expect(allPages.length).toBe(1);
|
||||
expect(allPages.length).toBe(2);
|
||||
expect(allPages).toContain(page);
|
||||
expect(allPages[0]).not.toBe(allPages[1]);
|
||||
expect(allPages).toContain(second);
|
||||
await second.close();
|
||||
});
|
||||
it('should contain browser target', async({browser}) => {
|
||||
const targets = browser.targets();
|
||||
const browserTarget = targets.find(target => target.type() === 'browser');
|
||||
expect(browserTarget).toBe(browser.browserTarget());
|
||||
it('should report browser target', async({browser}) => {
|
||||
expect(browser.browserTarget()).toBeTruthy();
|
||||
});
|
||||
it('should report when a new page is created and closed', async({browser, page, server, context}) => {
|
||||
const [otherPage] = await Promise.all([
|
||||
browser.waitForTarget(target => target.url() === server.CROSS_PROCESS_PREFIX + '/empty.html').then(target => target.page()),
|
||||
page.context().waitForTarget(target => target.url() === server.CROSS_PROCESS_PREFIX + '/empty.html').then(target => target.page()),
|
||||
page.evaluate(url => window.open(url), server.CROSS_PROCESS_PREFIX + '/empty.html'),
|
||||
]);
|
||||
expect(otherPage.url()).toContain(server.CROSS_PROCESS_PREFIX);
|
||||
@ -57,31 +60,31 @@ module.exports.describe = function({testRunner, expect, playwright, FFOX, CHROMI
|
||||
expect(allPages).toContain(page);
|
||||
expect(allPages).toContain(otherPage);
|
||||
|
||||
const closePagePromise = new Promise(fulfill => browser.once('targetdestroyed', target => fulfill(target.page())));
|
||||
const closePagePromise = new Promise(fulfill => page.context().once('targetdestroyed', target => fulfill(target.page())));
|
||||
await otherPage.close();
|
||||
expect(await closePagePromise).toBe(otherPage);
|
||||
|
||||
allPages = await Promise.all(browser.targets().map(target => target.page()));
|
||||
allPages = await Promise.all(page.context().targets().map(target => target.page()));
|
||||
expect(allPages).toContain(page);
|
||||
expect(allPages).not.toContain(otherPage);
|
||||
});
|
||||
it('should report when a service worker is created and destroyed', async({browser, page, server, context}) => {
|
||||
await page.goto(server.EMPTY_PAGE);
|
||||
const createdTarget = new Promise(fulfill => browser.once('targetcreated', target => fulfill(target)));
|
||||
const createdTarget = new Promise(fulfill => page.context().once('targetcreated', target => fulfill(target)));
|
||||
|
||||
await page.goto(server.PREFIX + '/serviceworkers/empty/sw.html');
|
||||
|
||||
expect((await createdTarget).type()).toBe('service_worker');
|
||||
expect((await createdTarget).url()).toBe(server.PREFIX + '/serviceworkers/empty/sw.js');
|
||||
|
||||
const destroyedTarget = new Promise(fulfill => browser.once('targetdestroyed', target => fulfill(target)));
|
||||
const destroyedTarget = new Promise(fulfill => page.context().once('targetdestroyed', target => fulfill(target)));
|
||||
await page.evaluate(() => window.registrationPromise.then(registration => registration.unregister()));
|
||||
expect(await destroyedTarget).toBe(await createdTarget);
|
||||
});
|
||||
it('should create a worker from a service worker', async({browser, page, server, context}) => {
|
||||
await page.goto(server.PREFIX + '/serviceworkers/empty/sw.html');
|
||||
|
||||
const target = await browser.waitForTarget(target => target.type() === 'service_worker');
|
||||
const target = await page.context().waitForTarget(target => target.type() === 'service_worker');
|
||||
const worker = await target.serviceWorker();
|
||||
expect(await worker.evaluate(() => self.toString())).toBe('[object ServiceWorkerGlobalScope]');
|
||||
});
|
||||
@ -90,17 +93,17 @@ module.exports.describe = function({testRunner, expect, playwright, FFOX, CHROMI
|
||||
await page.evaluate(() => {
|
||||
new SharedWorker('data:text/javascript,console.log("hi")');
|
||||
});
|
||||
const target = await browser.waitForTarget(target => target.type() === 'shared_worker');
|
||||
const target = await page.context().waitForTarget(target => target.type() === 'shared_worker');
|
||||
const worker = await target.serviceWorker();
|
||||
expect(worker).toBe(null);
|
||||
});
|
||||
it('should report when a target url changes', async({browser, page, server, context}) => {
|
||||
await page.goto(server.EMPTY_PAGE);
|
||||
let changedTarget = new Promise(fulfill => browser.once('targetchanged', target => fulfill(target)));
|
||||
let changedTarget = new Promise(fulfill => page.context().once('targetchanged', target => fulfill(target)));
|
||||
await page.goto(server.CROSS_PROCESS_PREFIX + '/');
|
||||
expect((await changedTarget).url()).toBe(server.CROSS_PROCESS_PREFIX + '/');
|
||||
|
||||
changedTarget = new Promise(fulfill => browser.once('targetchanged', target => fulfill(target)));
|
||||
changedTarget = new Promise(fulfill => page.context().once('targetchanged', target => fulfill(target)));
|
||||
await page.goto(server.EMPTY_PAGE);
|
||||
expect((await changedTarget).url()).toBe(server.EMPTY_PAGE);
|
||||
});
|
||||
@ -108,13 +111,13 @@ module.exports.describe = function({testRunner, expect, playwright, FFOX, CHROMI
|
||||
let targetChanged = false;
|
||||
const listener = () => targetChanged = true;
|
||||
browser.on('targetchanged', listener);
|
||||
const targetPromise = new Promise(fulfill => browser.once('targetcreated', target => fulfill(target)));
|
||||
const targetPromise = new Promise(fulfill => context.once('targetcreated', target => fulfill(target)));
|
||||
const newPagePromise = context.newPage();
|
||||
const target = await targetPromise;
|
||||
expect(target.url()).toBe('about:blank');
|
||||
|
||||
const newPage = await newPagePromise;
|
||||
const targetPromise2 = new Promise(fulfill => browser.once('targetcreated', target => fulfill(target)));
|
||||
const targetPromise2 = new Promise(fulfill => context.once('targetcreated', target => fulfill(target)));
|
||||
const evaluatePromise = newPage.evaluate(() => window.open('about:blank'));
|
||||
const target2 = await targetPromise2;
|
||||
expect(target2.url()).toBe('about:blank');
|
||||
@ -132,7 +135,7 @@ module.exports.describe = function({testRunner, expect, playwright, FFOX, CHROMI
|
||||
server.waitForRequest('/one-style.css')
|
||||
]);
|
||||
// Connect to the opened page.
|
||||
const target = await browser.waitForTarget(target => target.url().includes('one-style.html'));
|
||||
const target = await page.context().waitForTarget(target => target.url().includes('one-style.html'));
|
||||
const newPage = await target.page();
|
||||
// Issue a redirect.
|
||||
serverResponse.writeHead(302, { location: '/injectedstyle.css' });
|
||||
@ -145,23 +148,21 @@ module.exports.describe = function({testRunner, expect, playwright, FFOX, CHROMI
|
||||
it('should have an opener', async({browser, page, server, context}) => {
|
||||
await page.goto(server.EMPTY_PAGE);
|
||||
const [createdTarget] = await Promise.all([
|
||||
new Promise(fulfill => browser.once('targetcreated', target => fulfill(target))),
|
||||
new Promise(fulfill => page.context().once('targetcreated', target => fulfill(target))),
|
||||
page.goto(server.PREFIX + '/popup/window-open.html')
|
||||
]);
|
||||
expect((await createdTarget.page()).url()).toBe(server.PREFIX + '/popup/popup.html');
|
||||
expect(createdTarget.opener()).toBe(browser.pageTarget(page));
|
||||
expect(browser.pageTarget(page).opener()).toBe(null);
|
||||
expect(createdTarget.opener()).toBe(page.context().pageTarget(page));
|
||||
expect(page.context().pageTarget(page).opener()).toBe(null);
|
||||
});
|
||||
it('should close all belonging targets once closing context', async function({browser}) {
|
||||
const targets = async (context) => (await browser.targets()).filter(t => t.type() === 'page' && t.context() === context);
|
||||
|
||||
const context = await browser.newContext();
|
||||
await context.newPage();
|
||||
expect((await targets(context)).length).toBe(1);
|
||||
expect((await context.targets()).length).toBe(1);
|
||||
expect((await context.pages()).length).toBe(1);
|
||||
|
||||
await context.close();
|
||||
expect((await targets(context)).length).toBe(0);
|
||||
expect((await context.targets()).length).toBe(0);
|
||||
});
|
||||
});
|
||||
|
||||
@ -169,7 +170,7 @@ module.exports.describe = function({testRunner, expect, playwright, FFOX, CHROMI
|
||||
it('should wait for a target', async function({server, browser}) {
|
||||
const context = await browser.newContext();
|
||||
let resolved = false;
|
||||
const targetPromise = browser.waitForTarget(target => target.context() === context && target.url() === server.EMPTY_PAGE);
|
||||
const targetPromise = context.waitForTarget(target => target.url() === server.EMPTY_PAGE);
|
||||
targetPromise.then(() => resolved = true);
|
||||
const page = await context.newPage();
|
||||
expect(resolved).toBe(false);
|
||||
@ -179,26 +180,27 @@ module.exports.describe = function({testRunner, expect, playwright, FFOX, CHROMI
|
||||
await context.close();
|
||||
});
|
||||
it('should timeout waiting for a non-existent target', async function({browser, context, server}) {
|
||||
const error = await browser.waitForTarget(target => target.context() === context && target.url() === server.EMPTY_PAGE, {timeout: 1}).catch(e => e);
|
||||
const error = await context.waitForTarget(target => target.url() === server.EMPTY_PAGE, {timeout: 1}).catch(e => e);
|
||||
expect(error).toBeInstanceOf(playwright.errors.TimeoutError);
|
||||
});
|
||||
it('should wait for a target', async function({browser, server}) {
|
||||
const context = await browser.newContext();
|
||||
let resolved = false;
|
||||
const targetPromise = browser.waitForTarget(target => target.url() === server.EMPTY_PAGE);
|
||||
const targetPromise = context.waitForTarget(target => target.url() === server.EMPTY_PAGE);
|
||||
targetPromise.then(() => resolved = true);
|
||||
const page = await browser.newPage();
|
||||
const page = await context.newPage();
|
||||
expect(resolved).toBe(false);
|
||||
await page.goto(server.EMPTY_PAGE);
|
||||
const target = await targetPromise;
|
||||
expect(await target.page()).toBe(page);
|
||||
await page.context().close();
|
||||
await context.close();
|
||||
});
|
||||
it('should fire target events', async function({browser, server}) {
|
||||
const context = await browser.newContext();
|
||||
const events = [];
|
||||
browser.on('targetcreated', target => events.push('CREATED: ' + target.url()));
|
||||
browser.on('targetchanged', target => events.push('CHANGED: ' + target.url()));
|
||||
browser.on('targetdestroyed', target => events.push('DESTROYED: ' + target.url()));
|
||||
context.on('targetcreated', target => events.push('CREATED: ' + target.url()));
|
||||
context.on('targetchanged', target => events.push('CHANGED: ' + target.url()));
|
||||
context.on('targetdestroyed', target => events.push('DESTROYED: ' + target.url()));
|
||||
const page = await context.newPage();
|
||||
await page.goto(server.EMPTY_PAGE);
|
||||
await page.close();
|
||||
|
||||
@ -51,17 +51,18 @@ module.exports.describe = function({testRunner, expect, playwright, defaultBrows
|
||||
it('background_page target type should be available', async() => {
|
||||
const browserWithExtension = await playwright.launch(extensionOptions);
|
||||
const page = await browserWithExtension.newPage();
|
||||
const backgroundPageTarget = await browserWithExtension.waitForTarget(target => target.type() === 'background_page');
|
||||
const backgroundPageTarget = await page.context().waitForTarget(target => target.type() === 'background_page');
|
||||
await page.close();
|
||||
await browserWithExtension.close();
|
||||
expect(backgroundPageTarget).toBeTruthy();
|
||||
});
|
||||
it('target.page() should return a background_page', async({}) => {
|
||||
const browserWithExtension = await playwright.launch(extensionOptions);
|
||||
const backgroundPageTarget = await browserWithExtension.waitForTarget(target => target.type() === 'background_page');
|
||||
const page = await backgroundPageTarget.page();
|
||||
expect(await page.evaluate(() => 2 * 3)).toBe(6);
|
||||
expect(await page.evaluate(() => window.MAGIC)).toBe(42);
|
||||
const page = await browserWithExtension.newPage();
|
||||
const backgroundPageTarget = await page.context().waitForTarget(target => target.type() === 'background_page');
|
||||
const backgroundPage = await backgroundPageTarget.page();
|
||||
expect(await backgroundPage.evaluate(() => 2 * 3)).toBe(6);
|
||||
expect(await backgroundPage.evaluate(() => window.MAGIC)).toBe(42);
|
||||
await browserWithExtension.close();
|
||||
});
|
||||
// TODO: Support OOOPIF. @see https://github.com/GoogleChrome/puppeteer/issues/2548
|
||||
@ -91,7 +92,7 @@ module.exports.describe = function({testRunner, expect, playwright, defaultBrows
|
||||
const context = await browser.newContext();
|
||||
await Promise.all([
|
||||
context.newPage(),
|
||||
browser.waitForTarget(target => target.context() === context && target.url().includes('devtools://')),
|
||||
context.waitForTarget(target => target.url().includes('devtools://')),
|
||||
]);
|
||||
await browser.close();
|
||||
});
|
||||
|
||||
@ -59,9 +59,9 @@ module.exports.describe = function({testRunner, expect, defaultBrowserOptions, p
|
||||
const browser = await playwright.launch(defaultBrowserOptions);
|
||||
const context = await browser.newContext();
|
||||
const events = [];
|
||||
browser.on('targetcreated', target => target.context() === context && events.push('CREATED'));
|
||||
browser.on('targetchanged', target => target.context() === context && events.push('CHANGED'));
|
||||
browser.on('targetdestroyed', target => target.context() === context && events.push('DESTROYED'));
|
||||
context.on('targetcreated', target => events.push('CREATED'));
|
||||
context.on('targetchanged', target => events.push('CHANGED'));
|
||||
context.on('targetdestroyed', target => events.push('DESTROYED'));
|
||||
const page = await context.newPage();
|
||||
await page.goto(server.EMPTY_PAGE);
|
||||
await page.close();
|
||||
|
||||
@ -43,18 +43,18 @@ module.exports.describe = function({testRunner, expect, defaultBrowserOptions, p
|
||||
});
|
||||
xit('should report oopif frames', async function({browser, page, server, context}) {
|
||||
await page.goto(server.PREFIX + '/dynamic-oopif.html');
|
||||
expect(oopifs(browser).length).toBe(1);
|
||||
expect(oopifs(page.context()).length).toBe(1);
|
||||
expect(page.frames().length).toBe(2);
|
||||
});
|
||||
it('should load oopif iframes with subresources and request interception', async function({browser, page, server, context}) {
|
||||
await page.route('*', request => request.continue());
|
||||
await page.goto(server.PREFIX + '/dynamic-oopif.html');
|
||||
expect(oopifs(browser).length).toBe(1);
|
||||
expect(oopifs(page.context()).length).toBe(1);
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
function oopifs(browser) {
|
||||
return browser.targets().filter(target => target._targetInfo.type === 'iframe');
|
||||
function oopifs(context) {
|
||||
return context.targets().filter(target => target._targetInfo.type === 'iframe');
|
||||
}
|
||||
|
||||
@ -26,7 +26,7 @@ module.exports.describe = function({testRunner, expect, FFOX, CHROMIUM, WEBKIT})
|
||||
|
||||
describe('Chromium.createCDPSession', function() {
|
||||
it('should work', async function({page, browser, server}) {
|
||||
const client = await browser.pageTarget(page).createCDPSession();
|
||||
const client = await page.context().pageTarget(page).createCDPSession();
|
||||
|
||||
await Promise.all([
|
||||
client.send('Runtime.enable'),
|
||||
@ -36,7 +36,7 @@ module.exports.describe = function({testRunner, expect, FFOX, CHROMIUM, WEBKIT})
|
||||
expect(foo).toBe('bar');
|
||||
});
|
||||
it('should send events', async function({page, browser, server}) {
|
||||
const client = await browser.pageTarget(page).createCDPSession();
|
||||
const client = await page.context().pageTarget(page).createCDPSession();
|
||||
await client.send('Network.enable');
|
||||
const events = [];
|
||||
client.on('Network.requestWillBeSent', event => events.push(event));
|
||||
@ -44,7 +44,7 @@ module.exports.describe = function({testRunner, expect, FFOX, CHROMIUM, WEBKIT})
|
||||
expect(events.length).toBe(1);
|
||||
});
|
||||
it('should enable and disable domains independently', async function({page, browser, server}) {
|
||||
const client = await browser.pageTarget(page).createCDPSession();
|
||||
const client = await page.context().pageTarget(page).createCDPSession();
|
||||
await client.send('Runtime.enable');
|
||||
await client.send('Debugger.enable');
|
||||
// JS coverage enables and then disables Debugger domain.
|
||||
@ -59,7 +59,7 @@ module.exports.describe = function({testRunner, expect, FFOX, CHROMIUM, WEBKIT})
|
||||
expect(event.url).toBe('foo.js');
|
||||
});
|
||||
it('should be able to detach session', async function({page, browser, server}) {
|
||||
const client = await browser.pageTarget(page).createCDPSession();
|
||||
const client = await page.context().pageTarget(page).createCDPSession();
|
||||
await client.send('Runtime.enable');
|
||||
const evalResponse = await client.send('Runtime.evaluate', {expression: '1 + 2', returnByValue: true});
|
||||
expect(evalResponse.result.value).toBe(3);
|
||||
@ -73,7 +73,7 @@ module.exports.describe = function({testRunner, expect, FFOX, CHROMIUM, WEBKIT})
|
||||
expect(error.message).toContain('Session closed.');
|
||||
});
|
||||
it('should throw nice errors', async function({page, browser}) {
|
||||
const client = await browser.pageTarget(page).createCDPSession();
|
||||
const client = await page.context().pageTarget(page).createCDPSession();
|
||||
const error = await theSourceOfTheProblems().catch(error => error);
|
||||
expect(error.stack).toContain('theSourceOfTheProblems');
|
||||
expect(error.message).toContain('ThisCommand.DoesNotExist');
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user