From 9d6aa967f39151f77236ff3d68623b43e68f688c Mon Sep 17 00:00:00 2001 From: Yury Semikhatsky Date: Thu, 27 Feb 2020 14:02:48 -0800 Subject: [PATCH] chore(workers): align worker lifecycle evens with other APIs (#1147) --- docs/api.md | 27 +++++++++++++++------------ src/events.ts | 7 +++++-- src/page.ts | 9 +++++---- test/workers.spec.js | 24 ++++++++++++------------ 4 files changed, 37 insertions(+), 30 deletions(-) diff --git a/docs/api.md b/docs/api.md index 150c142e2d..bd4a242f99 100644 --- a/docs/api.md +++ b/docs/api.md @@ -481,8 +481,7 @@ page.removeListener('request', logRequest); - [event: 'requestfailed'](#event-requestfailed) - [event: 'requestfinished'](#event-requestfinished) - [event: 'response'](#event-response) -- [event: 'workercreated'](#event-workercreated) -- [event: 'workerdestroyed'](#event-workerdestroyed) +- [event: 'worker'](#event-worker) - [page.$(selector)](#pageselector) - [page.$$(selector)](#pageselector-1) - [page.$$eval(selector, pageFunction[, ...args])](#pageevalselector-pagefunction-args) @@ -653,16 +652,11 @@ Emitted when a request finishes successfully. Emitted when a [response] is received. -#### event: 'workercreated' +#### event: 'worker' - <[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]> @@ -3272,11 +3266,14 @@ function findFocusedNode(node) { ### 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. +`worker` event is emitted on the page object to signal a worker creation. +`close` event is emitted on the worker object when the worker is gone. ```js -page.on('workercreated', worker => console.log('Worker created: ' + worker.url())); -page.on('workerdestroyed', worker => console.log('Worker destroyed: ' + worker.url())); +page.on('worker', worker => { + console.log('Worker created: ' + worker.url()); + worker.on('close', worker => console.log('Worker destroyed: ' + worker.url())); +}); console.log('Current workers:'); for (const worker of page.workers()) @@ -3284,11 +3281,17 @@ for (const worker of page.workers()) ``` +- [event: 'close'](#event-close-2) - [worker.evaluate(pageFunction[, ...args])](#workerevaluatepagefunction-args) - [worker.evaluateHandle(pageFunction[, ...args])](#workerevaluatehandlepagefunction-args) - [worker.url()](#workerurl) +#### event: 'close' +- <[Worker]> + +Emitted when this dedicated [WebWorker](https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API) is terminated. + #### worker.evaluate(pageFunction[, ...args]) - `pageFunction` <[function]|[string]> Function to be evaluated in the worker context - `...args` <...[Serializable]|[JSHandle]> Arguments to pass to `pageFunction` @@ -3314,7 +3317,7 @@ If the function passed to the `worker.evaluateHandle` returns a [Promise], then ### class: BrowserServer -- [event: 'close'](#event-close-2) +- [event: 'close'](#event-close-3) - [browserServer.close()](#browserserverclose) - [browserServer.kill()](#browserserverkill) - [browserServer.process()](#browserserverprocess) diff --git a/src/events.ts b/src/events.ts index c3b2d353cd..4eb800175f 100644 --- a/src/events.ts +++ b/src/events.ts @@ -46,7 +46,10 @@ export const Events = { FrameNavigated: 'framenavigated', Load: 'load', Popup: 'popup', - WorkerCreated: 'workercreated', - WorkerDestroyed: 'workerdestroyed', + Worker: 'worker', + }, + + Worker: { + Close: 'close', }, }; diff --git a/src/page.ts b/src/page.ts index 64fe314a0f..bb20a38276 100644 --- a/src/page.ts +++ b/src/page.ts @@ -534,20 +534,20 @@ export class Page extends platform.EventEmitter { _addWorker(workerId: string, worker: Worker) { this._workers.set(workerId, worker); - this.emit(Events.Page.WorkerCreated, worker); + this.emit(Events.Page.Worker, worker); } _removeWorker(workerId: string) { const worker = this._workers.get(workerId); if (!worker) return; - this.emit(Events.Page.WorkerDestroyed, worker); + worker.emit(Events.Worker.Close, worker); this._workers.delete(workerId); } _clearWorkers() { for (const [workerId, worker] of this._workers) { - this.emit(Events.Page.WorkerDestroyed, worker); + worker.emit(Events.Worker.Close, worker); this._workers.delete(workerId); } } @@ -569,13 +569,14 @@ export class Page extends platform.EventEmitter { } } -export class Worker { +export class Worker extends platform.EventEmitter { private _url: string; private _executionContextPromise: Promise; private _executionContextCallback: (value?: js.ExecutionContext) => void; _existingExecutionContext: js.ExecutionContext | null = null; constructor(url: string) { + super(); this._url = url; this._executionContextCallback = () => {}; this._executionContextPromise = new Promise(x => this._executionContextCallback = x); diff --git a/test/workers.spec.js b/test/workers.spec.js index e9ee090374..4303f2305b 100644 --- a/test/workers.spec.js +++ b/test/workers.spec.js @@ -29,7 +29,7 @@ module.exports.describe = function({testRunner, expect, FFOX, CHROMIUM, WEBKIT}) describe('Workers', function() { it('Page.workers', async function({page, server}) { await Promise.all([ - page.waitForEvent('workercreated'), + page.waitForEvent('worker'), page.goto(server.PREFIX + '/worker/worker.html')]); const worker = page.workers()[0]; expect(worker.url()).toContain('worker.js'); @@ -40,11 +40,11 @@ module.exports.describe = function({testRunner, expect, FFOX, CHROMIUM, WEBKIT}) expect(page.workers().length).toBe(0); }); it('should emit created and destroyed events', async function({page}) { - const workerCreatedPromise = page.waitForEvent('workercreated'); + const workerCreatedPromise = page.waitForEvent('worker'); const workerObj = await page.evaluateHandle(() => new Worker(URL.createObjectURL(new Blob(['1'], {type: 'application/javascript'})))); const worker = await workerCreatedPromise; const workerThisObj = await worker.evaluateHandle(() => this); - const workerDestroyedPromise = new Promise(x => page.once('workerdestroyed', x)); + const workerDestroyedPromise = new Promise(x => worker.once('close', x)); await page.evaluate(workerObj => workerObj.terminate(), workerObj); expect(await workerDestroyedPromise).toBe(worker); const error = await workerThisObj.getProperty('self').catch(error => error); @@ -66,7 +66,7 @@ module.exports.describe = function({testRunner, expect, FFOX, CHROMIUM, WEBKIT}) expect(await (await log.args()[3].getProperty('origin')).jsonValue()).toBe('null'); }); it('should evaluate', async function({page}) { - const workerCreatedPromise = page.waitForEvent('workercreated'); + const workerCreatedPromise = page.waitForEvent('worker'); page.evaluate(() => new Worker(URL.createObjectURL(new Blob(['console.log(1)'], {type: 'application/javascript'})))); const worker = await workerCreatedPromise; expect(await worker.evaluate('1+1')).toBe(2); @@ -79,31 +79,31 @@ module.exports.describe = function({testRunner, expect, FFOX, CHROMIUM, WEBKIT}) }); it('should clear upon navigation', async function({server, page}) { await page.goto(server.EMPTY_PAGE); - const workerCreatedPromise = page.waitForEvent('workercreated'); + const workerCreatedPromise = page.waitForEvent('worker'); page.evaluate(() => new Worker(URL.createObjectURL(new Blob(['console.log(1)'], {type: 'application/javascript'})))); - await workerCreatedPromise; + const worker = await workerCreatedPromise; expect(page.workers().length).toBe(1); let destroyed = false; - page.once('workerdestroyed', () => destroyed = true); + worker.once('close', () => destroyed = true); await page.goto(server.PREFIX + '/one-style.html'); expect(destroyed).toBe(true); expect(page.workers().length).toBe(0); }); it('should clear upon cross-process navigation', async function({server, page}) { await page.goto(server.EMPTY_PAGE); - const workerCreatedPromise = page.waitForEvent('workercreated'); + const workerCreatedPromise = page.waitForEvent('worker'); page.evaluate(() => new Worker(URL.createObjectURL(new Blob(['console.log(1)'], {type: 'application/javascript'})))); - await workerCreatedPromise; + const worker = await workerCreatedPromise; expect(page.workers().length).toBe(1); let destroyed = false; - page.once('workerdestroyed', () => destroyed = true); + worker.once('close', () => destroyed = true); await page.goto(server.CROSS_PROCESS_PREFIX + '/empty.html'); expect(destroyed).toBe(true); expect(page.workers().length).toBe(0); }); it('should report network activity', async function({page, server}) { const [worker] = await Promise.all([ - page.waitForEvent('workercreated'), + page.waitForEvent('worker'), page.goto(server.PREFIX + '/worker/worker.html'), ]); const url = server.PREFIX + '/one-style.css'; @@ -133,7 +133,7 @@ module.exports.describe = function({testRunner, expect, FFOX, CHROMIUM, WEBKIT}) }); false && it.skip(FFOX)('should report web socket activity', async function({page, server}) { const [worker] = await Promise.all([ - page.waitForEvent('workercreated'), + page.waitForEvent('worker'), page.goto(server.PREFIX + '/worker/worker.html'), ]); const log = [];