diff --git a/docs/api.md b/docs/api.md index 51f638f985..c38e50f580 100644 --- a/docs/api.md +++ b/docs/api.md @@ -78,8 +78,6 @@ * [event: 'requestfailed'](#event-requestfailed) * [event: 'requestfinished'](#event-requestfinished) * [event: 'response'](#event-response) - * [event: 'workercreated'](#event-workercreated) - * [event: 'workerdestroyed'](#event-workerdestroyed) * [page.$(selector)](#pageselector) * [page.$$(selector)](#pageselector-1) * [page.$$eval(selector, pageFunction[, ...args])](#pageevalselector-pagefunction-args) @@ -154,12 +152,6 @@ * [page.waitForResponse(urlOrPredicate[, options])](#pagewaitforresponseurlorpredicate-options) * [page.waitForSelector(selector[, options])](#pagewaitforselectorselector-options) * [page.waitForXPath(xpath[, options])](#pagewaitforxpathxpath-options) - * [page.workers()](#pageworkers) -- [class: Worker](#class-worker) - * [worker.evaluate(pageFunction[, ...args])](#workerevaluatepagefunction-args) - * [worker.evaluateHandle(pageFunction[, ...args])](#workerevaluatehandlepagefunction-args) - * [worker.executionContext()](#workerexecutioncontext) - * [worker.url()](#workerurl) - [class: Accessibility](#class-accessibility) * [accessibility.snapshot([options])](#accessibilitysnapshotoptions) - [class: Keyboard](#class-keyboard) @@ -317,7 +309,6 @@ * [target.page()](#targetpage) * [target.type()](#targettype) * [target.url()](#targeturl) - * [target.worker()](#targetworker) - [class: CDPSession](#class-cdpsession) * [cdpSession.detach()](#cdpsessiondetach) * [cdpSession.send(method[, params])](#cdpsessionsendmethod-params) @@ -344,7 +335,6 @@ The Playwright API is hierarchical and mirrors the browser structure. - [`BrowserContext`](#class-browsercontext) instance defines a browsing session and can own multiple pages. - [`Page`](#class-page) has at least one frame: main frame. There might be other frames created by [iframe](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/iframe) or [frame](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/frame) tags. - [`Frame`](#class-frame) has at least one execution context - the default execution context - where the frame's JavaScript is executed. A Frame might have additional execution contexts that are associated with [extensions](https://developer.chrome.com/extensions). -- [`Worker`](#class-worker) has a single execution context and facilitates interacting with [WebWorkers](https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API). (Diagram source: [link](https://docs.google.com/drawings/d/1Q_AM6KYs9kbyLZF-Lpp5mtpAWth73Cq8IKCsWYgi8MM/edit?usp=sharing)) @@ -391,36 +381,6 @@ If Playwright doesn't find them in the environment during the installation step, > **NOTE** PLAYWRIGHT_* env variables are not accounted for in the [`playwright-core`](https://www.npmjs.com/package/playwright-core) package. - -### Working with Chrome Extensions - -Playwright can be used for testing Chrome Extensions. - -> **NOTE** Extensions in Chrome / Chromium currently only work in non-headless mode. - -The following is code for getting a handle to the [background page](https://developer.chrome.com/extensions/background_pages) of an extension whose source is located in `./my-extension`: -```js -const playwright = require('playwright'); - -(async () => { - const pathToExtension = require('path').join(__dirname, 'my-extension'); - const browser = await playwright.launch({ - headless: false, - args: [ - `--disable-extensions-except=${pathToExtension}`, - `--load-extension=${pathToExtension}` - ] - }); - const targets = await browser.targets(); - const backgroundPageTarget = targets.find(target => target.type() === 'background_page'); - const backgroundPage = await backgroundPageTarget.page(); - // Test the background page as you would any other page. - await browser.close(); -})(); -``` - -> **NOTE** It is not yet possible to test extension popups or content scripts. - ### class: Playwright Playwright module provides a method to launch a Chromium instance. @@ -918,7 +878,7 @@ const newWindowTarget = await browserContext.waitForTarget(target => target.url( * extends: [EventEmitter](https://nodejs.org/api/events.html#events_class_eventemitter) -Page provides methods to interact with a single tab or [extension background page](https://developer.chrome.com/extensions/background_pages) in Chromium. One [Browser] instance might have multiple [Page] instances. +Page provides methods to interact with a single tab. One [Browser] instance might have multiple [Page] instances. This example creates a page, navigates it to a URL, and then saves a screenshot: ```js @@ -1062,16 +1022,6 @@ Emitted when a request finishes successfully. Emitted when a [response] is received. -#### event: 'workercreated' -- <[Worker]> - -Emitted when a dedicated [WebWorker](https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API) is spawned by the page. - -#### event: 'workerdestroyed' -- <[Worker]> - -Emitted when a dedicated [WebWorker](https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API) is terminated. - #### page.$(selector) - `selector` <[string]> A [selector] to query page for - returns: <[Promise]> @@ -2171,54 +2121,6 @@ const playwright = require('playwright'); ``` Shortcut for [page.mainFrame().waitForXPath(xpath[, options])](#framewaitforxpathxpath-options). -#### page.workers() -- returns: <[Array]<[Worker]>> -This method returns all of the dedicated [WebWorkers](https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API) associated with the page. - -> **NOTE** This does not contain ServiceWorkers - -### class: Worker - -The Worker class represents a [WebWorker](https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API). -The events `workercreated` and `workerdestroyed` are emitted on the page object to signal the worker lifecycle. - -```js -page.on('workercreated', worker => console.log('Worker created: ' + worker.url())); -page.on('workerdestroyed', worker => console.log('Worker destroyed: ' + worker.url())); - -console.log('Current workers:'); -for (const worker of page.workers()) - console.log(' ' + worker.url()); -``` - -#### worker.evaluate(pageFunction[, ...args]) -- `pageFunction` <[function]|[string]> Function to be evaluated in the worker context -- `...args` <...[Serializable]|[JSHandle]> Arguments to pass to `pageFunction` -- returns: <[Promise]<[Serializable]>> Promise which resolves to the return value of `pageFunction` - -If the function passed to the `worker.evaluate` returns a [Promise], then `worker.evaluate` would wait for the promise to resolve and return its value. - -If the function passed to the `worker.evaluate` returns a non-[Serializable] value, then `worker.evaluate` resolves to `undefined`. DevTools Protocol also supports transferring some additional values that are not serializable by `JSON`: `-0`, `NaN`, `Infinity`, `-Infinity`, and bigint literals. - -Shortcut for [(await worker.executionContext()).evaluate(pageFunction, ...args)](#executioncontextevaluatepagefunction-args). - -#### worker.evaluateHandle(pageFunction[, ...args]) -- `pageFunction` <[function]|[string]> Function to be evaluated in the page context -- `...args` <...[Serializable]|[JSHandle]> Arguments to pass to `pageFunction` -- returns: <[Promise]<[JSHandle]>> Promise which resolves to the return value of `pageFunction` as in-page object (JSHandle) - -The only difference between `worker.evaluate` and `worker.evaluateHandle` is that `worker.evaluateHandle` returns in-page object (JSHandle). - -If the function passed to the `worker.evaluateHandle` returns a [Promise], then `worker.evaluateHandle` would wait for the promise to resolve and return its value. - -Shortcut for [(await worker.executionContext()).evaluateHandle(pageFunction, ...args)](#executioncontextevaluatehandlepagefunction-args). - -#### worker.executionContext() -- returns: <[Promise]<[ExecutionContext]>> - -#### worker.url() -- returns: <[string]> - ### class: Accessibility The Accessibility class provides methods for inspecting Chromium's accessibility tree. The accessibility tree is used by assistive technology such as [screen readers](https://en.wikipedia.org/wiki/Screen_reader) or [switches](https://en.wikipedia.org/wiki/Switch_access). @@ -3096,8 +2998,6 @@ The class represents a context for JavaScript execution. A [Page] might have man always created after frame is attached to DOM. This context is returned by the [`frame.executionContext()`](#frameexecutioncontext) method. - [Extensions](https://developer.chrome.com/extensions)'s content scripts create additional execution contexts. -Besides pages, execution contexts can be found in [workers](https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API). - #### executionContext.evaluate(pageFunction[, ...args]) - `pageFunction` <[function]|[string]> Function to be evaluated in `executionContext` - `...args` <...[Serializable]|[JSHandle]> Arguments to pass to `pageFunction` @@ -3162,8 +3062,6 @@ await resultHandle.dispose(); #### executionContext.frame() - returns: Frame associated with this execution context. -> **NOTE** Not every execution context is associated with a frame. For example, workers and extensions have execution contexts that are not associated with frames. - #### executionContext.queryObjects(prototypeHandle) - `prototypeHandle` <[JSHandle]> A handle to the object prototype. @@ -3871,11 +3769,6 @@ Identifies what kind of target this is. Can be `"page"`, [`"background_page"`](h #### target.url() - returns: <[string]> -#### target.worker() -- returns: <[Promise]> - -If the target is not of type `"service_worker"` or `"shared_worker"`, returns `null`. - ### class: CDPSession * extends: [EventEmitter](https://nodejs.org/api/events.html#events_class_eventemitter) @@ -4024,7 +3917,6 @@ TimeoutError is emitted whenever certain operations are terminated due to timeou [UIEvent.detail]: https://developer.mozilla.org/en-US/docs/Web/API/UIEvent/detail "UIEvent.detail" [USKeyboardLayout]: ../lib/USKeyboardLayout.js "USKeyboardLayout" [UnixTime]: https://en.wikipedia.org/wiki/Unix_time "Unix Time" -[Worker]: #class-worker "Worker" [boolean]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures#Boolean_type "Boolean" [function]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function "Function" [iterator]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Iteration_protocols "Iterator" diff --git a/src/Events.ts b/src/Events.ts index 580565de1c..78ec6c1353 100644 --- a/src/Events.ts +++ b/src/Events.ts @@ -35,8 +35,6 @@ export const Events = { Load: 'load', Metrics: 'metrics', Popup: 'popup', - WorkerCreated: 'workercreated', - WorkerDestroyed: 'workerdestroyed', }, Browser: { diff --git a/src/api.ts b/src/api.ts index db511c21fe..3557d6b37e 100644 --- a/src/api.ts +++ b/src/api.ts @@ -40,7 +40,6 @@ export = { TimeoutError: require('./Errors').TimeoutError, Touchscreen: require('./chromium/Input').Touchscreen, Tracing: require('./chromium/Tracing').Tracing, - Worker: require('./chromium/Worker').Worker, }, Firefox: { Accessibility: require('./firefox/Accessibility').Accessibility, diff --git a/src/chromium/Page.ts b/src/chromium/Page.ts index ae6a1ae7e5..ec793b151c 100644 --- a/src/chromium/Page.ts +++ b/src/chromium/Page.ts @@ -35,7 +35,6 @@ import { Response, NetworkManagerEvents } from './NetworkManager'; import { TaskQueue } from './TaskQueue'; import { TimeoutSettings } from '../TimeoutSettings'; import { Tracing } from './Tracing'; -import { Worker } from './Worker'; import { Target } from './Target'; import { Browser } from './Browser'; import { BrowserContext } from './BrowserContext'; @@ -69,7 +68,6 @@ export class Page extends EventEmitter { _javascriptEnabled = true; private _viewport: Viewport | null = null; private _screenshotTaskQueue: TaskQueue; - private _workers = new Map(); private _fileChooserInterceptionIsDisabled = false; private _fileChooserInterceptors = new Set<(chooser: FileChooser) => void>(); private _disconnectPromise: Promise | undefined; @@ -98,27 +96,6 @@ export class Page extends EventEmitter { this._screenshotTaskQueue = screenshotTaskQueue; - client.on('Target.attachedToTarget', event => { - if (event.targetInfo.type !== 'worker') { - // If we don't detach from service workers, they will never die. - client.send('Target.detachFromTarget', { - sessionId: event.sessionId - }).catch(debugError); - return; - } - const session = Connection.fromSession(client).session(event.sessionId); - const worker = new Worker(session, event.targetInfo.url, this._addConsoleMessage.bind(this), this._handleException.bind(this)); - this._workers.set(event.sessionId, worker); - this.emit(Events.Page.WorkerCreated, worker); - }); - client.on('Target.detachedFromTarget', event => { - const worker = this._workers.get(event.sessionId); - if (!worker) - return; - this.emit(Events.Page.WorkerDestroyed, worker); - this._workers.delete(event.sessionId); - }); - this._frameManager.on(FrameManagerEvents.FrameAttached, event => this.emit(Events.Page.FrameAttached, event)); this._frameManager.on(FrameManagerEvents.FrameDetached, event => this.emit(Events.Page.FrameDetached, event)); this._frameManager.on(FrameManagerEvents.FrameNavigated, event => this.emit(Events.Page.FrameNavigated, event)); @@ -215,8 +192,7 @@ export class Page extends EventEmitter { const {level, text, args, source, url, lineNumber} = event.entry; if (args) args.map(arg => releaseObject(this._client, arg)); - if (source !== 'worker') - this.emit(Events.Page.Console, new ConsoleMessage(level, text, [], {url, lineNumber})); + this.emit(Events.Page.Console, new ConsoleMessage(level, text, [], {url, lineNumber})); } mainFrame(): Frame { @@ -247,10 +223,6 @@ export class Page extends EventEmitter { return this._frameManager.frames(); } - workers(): Worker[] { - return Array.from(this._workers.values()); - } - async setRequestInterception(value: boolean) { return this._frameManager.networkManager().setRequestInterception(value); } diff --git a/src/chromium/Target.ts b/src/chromium/Target.ts index d3810651cb..3687a97c10 100644 --- a/src/chromium/Target.ts +++ b/src/chromium/Target.ts @@ -21,7 +21,6 @@ import { BrowserContext } from './BrowserContext'; import { CDPSession } from './Connection'; import { Page, Viewport } from './Page'; import { TaskQueue } from './TaskQueue'; -import { Worker } from './Worker'; import { Protocol } from './protocol'; export class Target { @@ -33,7 +32,7 @@ export class Target { private _defaultViewport: Viewport; private _screenshotTaskQueue: TaskQueue; private _pagePromise: Promise | null = null; - private _workerPromise: Promise | null = null; + _initializedPromise: Promise; _initializedCallback: (value?: unknown) => void; _isClosedPromise: Promise; @@ -85,17 +84,6 @@ export class Target { return this._pagePromise; } - async worker(): Promise { - if (this._targetInfo.type !== 'service_worker' && this._targetInfo.type !== 'shared_worker') - return null; - if (!this._workerPromise) { - // TODO(einbinder): Make workers send their console logs. - this._workerPromise = this._sessionFactory() - .then(client => new Worker(client, this._targetInfo.url, () => {} /* consoleAPICalled */, () => {} /* exceptionThrown */)); - } - return this._workerPromise; - } - url(): string { return this._targetInfo.url; } diff --git a/src/chromium/Worker.ts b/src/chromium/Worker.ts deleted file mode 100644 index 4030a1180e..0000000000 --- a/src/chromium/Worker.ts +++ /dev/null @@ -1,63 +0,0 @@ -/** - * Copyright 2018 Google Inc. All rights reserved. - * Modifications copyright (c) Microsoft Corporation. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -import { EventEmitter } from 'events'; -import { CDPSession } from './Connection'; -import { ExecutionContext } from './ExecutionContext'; -import { debugError } from '../helper'; -import { JSHandle } from './JSHandle'; -import { Protocol } from './protocol'; - -export class Worker extends EventEmitter { - private _client: CDPSession; - private _url: string; - private _executionContextPromise: Promise; - private _executionContextCallback: (value?: ExecutionContext) => void; - - constructor(client: CDPSession, url: string, consoleAPICalled: (arg0: string, arg1: JSHandle[], arg2: Protocol.Runtime.StackTrace | undefined) => void, exceptionThrown: (arg0: Protocol.Runtime.ExceptionDetails) => void) { - super(); - this._client = client; - this._url = url; - this._executionContextPromise = new Promise(x => this._executionContextCallback = x); - let jsHandleFactory: (o: Protocol.Runtime.RemoteObject) => JSHandle; - this._client.once('Runtime.executionContextCreated', async event => { - jsHandleFactory = remoteObject => new JSHandle(executionContext, client, remoteObject); - const executionContext = new ExecutionContext(client, event.context, null); - this._executionContextCallback(executionContext); - }); - // This might fail if the target is closed before we recieve all execution contexts. - this._client.send('Runtime.enable', {}).catch(debugError); - - this._client.on('Runtime.consoleAPICalled', event => consoleAPICalled(event.type, event.args.map(jsHandleFactory), event.stackTrace)); - this._client.on('Runtime.exceptionThrown', exception => exceptionThrown(exception.exceptionDetails)); - } - - url(): string { - return this._url; - } - - async executionContext(): Promise { - return this._executionContextPromise; - } - - async evaluate(pageFunction: Function | string, ...args: any[]): Promise { - return (await this._executionContextPromise).evaluate(pageFunction, ...args); - } - - async evaluateHandle(pageFunction: Function | string, ...args: any[]): Promise { - return (await this._executionContextPromise).evaluateHandle(pageFunction, ...args); - } -} diff --git a/src/webkit/Page.ts b/src/webkit/Page.ts index 76cfe18d63..d0080a1320 100644 --- a/src/webkit/Page.ts +++ b/src/webkit/Page.ts @@ -50,7 +50,6 @@ export class Page extends EventEmitter { _javascriptEnabled = true; private _viewport: Viewport | null = null; private _screenshotTaskQueue: TaskQueue; - private _workers = new Map(); private _disconnectPromise: Promise | undefined; private _sessionListeners: RegisteredListener[] = []; @@ -179,11 +178,6 @@ export class Page extends EventEmitter { return this._frameManager.frames(); } - workers(): Worker[] { - return Array.from(this._workers.values()); - } - - setDefaultNavigationTimeout(timeout: number) { this._timeoutSettings.setDefaultNavigationTimeout(timeout); } diff --git a/test/assets/worker/worker.html b/test/assets/worker/worker.html deleted file mode 100644 index 7de2d9fd9e..0000000000 --- a/test/assets/worker/worker.html +++ /dev/null @@ -1,14 +0,0 @@ - - - - Worker test - - - - - \ No newline at end of file diff --git a/test/assets/worker/worker.js b/test/assets/worker/worker.js deleted file mode 100644 index d0d229a192..0000000000 --- a/test/assets/worker/worker.js +++ /dev/null @@ -1,16 +0,0 @@ -console.log('hello from the worker'); - -function workerFunction() { - return 'worker function result'; -} - -self.addEventListener('message', event => { - console.log('got this data: ' + event.data); -}); - -(async function() { - while (true) { - self.postMessage(workerFunction.toString()); - await new Promise(x => setTimeout(x, 100)); - } -})(); \ No newline at end of file diff --git a/test/headful.spec.js b/test/headful.spec.js index 61ab37c602..6c2279a078 100644 --- a/test/headful.spec.js +++ b/test/headful.spec.js @@ -55,14 +55,6 @@ module.exports.addTests = function({testRunner, expect, playwright, defaultBrows 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); - await browserWithExtension.close(); - }); it('should have default url when launching browser', async function() { const browser = await playwright.launch(extensionOptions); const pages = (await browser.pages()).map(page => page.url()); diff --git a/test/playwright.spec.js b/test/playwright.spec.js index 4d89f84fbf..e992008958 100644 --- a/test/playwright.spec.js +++ b/test/playwright.spec.js @@ -152,7 +152,6 @@ module.exports.addTests = ({testRunner, product, playwrightPath}) => { require('./target.spec.js').addTests(testOptions); require('./touchscreen.spec.js').addTests(testOptions); require('./waittask.spec.js').addTests(testOptions); - require('./worker.spec.js').addTests(testOptions); if (CHROME) { require('./CDPSession.spec.js').addTests(testOptions); require('./coverage.spec.js').addTests(testOptions); diff --git a/test/target.spec.js b/test/target.spec.js index a287ed4dc6..e154d41c2d 100644 --- a/test/target.spec.js +++ b/test/target.spec.js @@ -72,35 +72,6 @@ module.exports.addTests = function({testRunner, expect, playwright, FFOX, CHROME expect(allPages).toContain(page); expect(allPages).not.toContain(otherPage); }); - it.skip(FFOX || WEBKIT)('should report when a service worker is created and destroyed', async({page, server, context}) => { - await page.goto(server.EMPTY_PAGE); - const createdTarget = new Promise(fulfill => 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 => context.once('targetdestroyed', target => fulfill(target))); - await page.evaluate(() => window.registrationPromise.then(registration => registration.unregister())); - expect(await destroyedTarget).toBe(await createdTarget); - }); - it.skip(FFOX || WEBKIT)('should create a worker from a service worker', async({page, server, context}) => { - await page.goto(server.PREFIX + '/serviceworkers/empty/sw.html'); - - const target = await context.waitForTarget(target => target.type() === 'service_worker'); - const worker = await target.worker(); - expect(await worker.evaluate(() => self.toString())).toBe('[object ServiceWorkerGlobalScope]'); - }); - it.skip(FFOX || WEBKIT)('should create a worker from a shared worker', async({page, server, context}) => { - await page.goto(server.EMPTY_PAGE); - await page.evaluate(() => { - new SharedWorker('data:text/javascript,console.log("hi")'); - }); - const target = await context.waitForTarget(target => target.type() === 'shared_worker'); - const worker = await target.worker(); - expect(await worker.evaluate(() => self.toString())).toBe('[object SharedWorkerGlobalScope]'); - }); it.skip(WEBKIT)('should report when a target url changes', async({page, server, context}) => { await page.goto(server.EMPTY_PAGE); let changedTarget = new Promise(fulfill => context.once('targetchanged', target => fulfill(target))); diff --git a/test/worker.spec.js b/test/worker.spec.js deleted file mode 100644 index f44796dd90..0000000000 --- a/test/worker.spec.js +++ /dev/null @@ -1,66 +0,0 @@ -const utils = require('./utils'); -const {waitEvent} = utils; - -module.exports.addTests = function({testRunner, expect, FFOX, CHROME, WEBKIT}) { - const {describe, xdescribe, fdescribe} = testRunner; - const {it, fit, xit} = testRunner; - const {beforeAll, beforeEach, afterAll, afterEach} = testRunner; - - describe.skip(FFOX || WEBKIT)('Workers', function() { - it('Page.workers', async function({page, server}) { - await Promise.all([ - new Promise(x => page.once('workercreated', x)), - page.goto(server.PREFIX + '/worker/worker.html')]); - const worker = page.workers()[0]; - expect(worker.url()).toContain('worker.js'); - - expect(await worker.evaluate(() => self.workerFunction())).toBe('worker function result'); - - await page.goto(server.EMPTY_PAGE); - expect(page.workers().length).toBe(0); - }); - it('should emit created and destroyed events', async function({page}) { - const workerCreatedPromise = new Promise(x => page.once('workercreated', x)); - const workerObj = await page.evaluateHandle(() => new Worker('data:text/javascript,1')); - const worker = await workerCreatedPromise; - const workerThisObj = await worker.evaluateHandle(() => this); - const workerDestroyedPromise = new Promise(x => page.once('workerdestroyed', x)); - await page.evaluate(workerObj => workerObj.terminate(), workerObj); - expect(await workerDestroyedPromise).toBe(worker); - const error = await workerThisObj.getProperty('self').catch(error => error); - expect(error.message).toContain('Most likely the worker has been closed.'); - }); - it('should report console logs', async function({page}) { - const [message] = await Promise.all([ - waitEvent(page, 'console'), - page.evaluate(() => new Worker(`data:text/javascript,console.log(1)`)), - ]); - expect(message.text()).toBe('1'); - expect(message.location()).toEqual({ - url: 'data:text/javascript,console.log(1)', - lineNumber: 0, - columnNumber: 8, - }); - }); - it('should have JSHandles for console logs', async function({page}) { - const logPromise = new Promise(x => page.on('console', x)); - await page.evaluate(() => new Worker(`data:text/javascript,console.log(1,2,3,this)`)); - const log = await logPromise; - expect(log.text()).toBe('1 2 3 JSHandle@object'); - expect(log.args().length).toBe(4); - expect(await (await log.args()[3].getProperty('origin')).jsonValue()).toBe('null'); - }); - it('should have an execution context', async function({page}) { - const workerCreatedPromise = new Promise(x => page.once('workercreated', x)); - await page.evaluate(() => new Worker(`data:text/javascript,console.log(1)`)); - const worker = await workerCreatedPromise; - expect(await (await worker.executionContext()).evaluate('1+1')).toBe(2); - }); - it('should report errors', async function({page}) { - const errorPromise = new Promise(x => page.on('pageerror', x)); - await page.evaluate(() => new Worker(`data:text/javascript, throw new Error('this is my error');`)); - const errorLog = await errorPromise; - expect(errorLog.message).toContain('this is my error'); - }); - }); -};