mirror of
https://github.com/puppeteer/puppeteer
synced 2024-06-14 14:02:48 +00:00
feat: support closing workers (#11870)
This commit is contained in:
parent
928d14ac84
commit
1bdae40ec8
17
docs/api/puppeteer.webworker.close.md
Normal file
17
docs/api/puppeteer.webworker.close.md
Normal file
@ -0,0 +1,17 @@
|
||||
---
|
||||
sidebar_label: WebWorker.close
|
||||
---
|
||||
|
||||
# WebWorker.close() method
|
||||
|
||||
#### Signature:
|
||||
|
||||
```typescript
|
||||
class WebWorker {
|
||||
close(): Promise<void>;
|
||||
}
|
||||
```
|
||||
|
||||
**Returns:**
|
||||
|
||||
Promise<void>
|
@ -46,6 +46,7 @@ for (const worker of page.workers()) {
|
||||
|
||||
| Method | Modifiers | Description |
|
||||
| --------------------------------------------------------------------- | --------- | --------------------------------------------------------------------- |
|
||||
| [close()](./puppeteer.webworker.close.md) | | |
|
||||
| [evaluate(func, args)](./puppeteer.webworker.evaluate.md) | | Evaluates a given function in the [worker](./puppeteer.webworker.md). |
|
||||
| [evaluateHandle(func, args)](./puppeteer.webworker.evaluatehandle.md) | | Evaluates a given function in the [worker](./puppeteer.webworker.md). |
|
||||
| [url()](./puppeteer.webworker.url.md) | | The URL of this web worker. |
|
||||
|
821
package-lock.json
generated
821
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@ -4,6 +4,7 @@
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
import {UnsupportedOperation} from '../common/Errors.js';
|
||||
import {EventEmitter, type EventType} from '../common/EventEmitter.js';
|
||||
import {TimeoutSettings} from '../common/TimeoutSettings.js';
|
||||
import type {EvaluateFunc, HandleFor} from '../common/types.js';
|
||||
@ -131,4 +132,8 @@ export abstract class WebWorker extends EventEmitter<
|
||||
func = withSourcePuppeteerURLIfNone(this.evaluateHandle.name, func);
|
||||
return await this.mainRealm().evaluateHandle(func, ...args);
|
||||
}
|
||||
|
||||
async close(): Promise<void> {
|
||||
throw new UnsupportedOperation('WebWorker.close() is not supported');
|
||||
}
|
||||
}
|
||||
|
@ -358,6 +358,8 @@ export class CdpPage extends Page {
|
||||
const worker = new CdpWebWorker(
|
||||
session,
|
||||
session._target().url(),
|
||||
session._target()._targetId,
|
||||
session._target().type(),
|
||||
this.#addConsoleMessage.bind(this),
|
||||
this.#handleException.bind(this)
|
||||
);
|
||||
|
@ -290,6 +290,8 @@ export class WorkerTarget extends CdpTarget {
|
||||
return new CdpWebWorker(
|
||||
client,
|
||||
this._getTargetInfo().url,
|
||||
this._targetId,
|
||||
this.type(),
|
||||
() => {} /* consoleAPICalled */,
|
||||
() => {} /* exceptionThrown */
|
||||
);
|
||||
|
@ -7,6 +7,7 @@ import type {Protocol} from 'devtools-protocol';
|
||||
|
||||
import type {CDPSession} from '../api/CDPSession.js';
|
||||
import type {Realm} from '../api/Realm.js';
|
||||
import {TargetType} from '../api/Target.js';
|
||||
import {WebWorker} from '../api/WebWorker.js';
|
||||
import {TimeoutSettings} from '../common/TimeoutSettings.js';
|
||||
import {debugError} from '../common/util.js';
|
||||
@ -37,15 +38,21 @@ export type ExceptionThrownCallback = (
|
||||
export class CdpWebWorker extends WebWorker {
|
||||
#world: IsolatedWorld;
|
||||
#client: CDPSession;
|
||||
readonly #id: string;
|
||||
readonly #targetType: TargetType;
|
||||
|
||||
constructor(
|
||||
client: CDPSession,
|
||||
url: string,
|
||||
targetId: string,
|
||||
targetType: TargetType,
|
||||
consoleAPICalled: ConsoleAPICalledCallback,
|
||||
exceptionThrown: ExceptionThrownCallback
|
||||
) {
|
||||
super(url);
|
||||
this.#id = targetId;
|
||||
this.#client = client;
|
||||
this.#targetType = targetType;
|
||||
this.#world = new IsolatedWorld(this, new TimeoutSettings());
|
||||
|
||||
this.#client.once('Runtime.executionContextCreated', async event => {
|
||||
@ -79,4 +86,25 @@ export class CdpWebWorker extends WebWorker {
|
||||
get client(): CDPSession {
|
||||
return this.#client;
|
||||
}
|
||||
|
||||
override async close(): Promise<void> {
|
||||
switch (this.#targetType) {
|
||||
case TargetType.SERVICE_WORKER:
|
||||
case TargetType.SHARED_WORKER: {
|
||||
// For service and shared workers we need to close the target and detach to allow
|
||||
// the worker to stop.
|
||||
await this.client.connection()?.send('Target.closeTarget', {
|
||||
targetId: this.#id,
|
||||
});
|
||||
await this.client.connection()?.send('Target.detachFromTarget', {
|
||||
sessionId: this.client.id(),
|
||||
});
|
||||
break;
|
||||
}
|
||||
default:
|
||||
await this.evaluate(() => {
|
||||
self.close();
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1234,6 +1234,20 @@
|
||||
"parameters": ["webDriverBiDi"],
|
||||
"expectations": ["PASS"]
|
||||
},
|
||||
{
|
||||
"testIdPattern": "[target.spec] Target should close a service worker",
|
||||
"platforms": ["darwin", "linux", "win32"],
|
||||
"parameters": ["webDriverBiDi"],
|
||||
"expectations": ["SKIP"],
|
||||
"comment": "not supported"
|
||||
},
|
||||
{
|
||||
"testIdPattern": "[target.spec] Target should close a shared worker",
|
||||
"platforms": ["darwin", "linux", "win32"],
|
||||
"parameters": ["webDriverBiDi"],
|
||||
"expectations": ["SKIP"],
|
||||
"comment": "not supported"
|
||||
},
|
||||
{
|
||||
"testIdPattern": "[target.spec] Target should contain browser target",
|
||||
"platforms": ["darwin", "linux", "win32"],
|
||||
@ -4290,6 +4304,20 @@
|
||||
"parameters": ["firefox", "webDriverBiDi"],
|
||||
"expectations": ["PASS"]
|
||||
},
|
||||
{
|
||||
"testIdPattern": "[target.spec] Target should close a service worker",
|
||||
"platforms": ["darwin", "linux", "win32"],
|
||||
"parameters": ["cdp", "firefox"],
|
||||
"expectations": ["SKIP"],
|
||||
"comment": "not supported"
|
||||
},
|
||||
{
|
||||
"testIdPattern": "[target.spec] Target should close a shared worker",
|
||||
"platforms": ["darwin", "linux", "win32"],
|
||||
"parameters": ["cdp", "firefox"],
|
||||
"expectations": ["SKIP"],
|
||||
"comment": "not supported"
|
||||
},
|
||||
{
|
||||
"testIdPattern": "[target.spec] Target should contain browser target",
|
||||
"platforms": ["darwin", "linux", "win32"],
|
||||
@ -4735,6 +4763,13 @@
|
||||
"parameters": ["cdp", "firefox", "headless"],
|
||||
"expectations": ["FAIL"]
|
||||
},
|
||||
{
|
||||
"testIdPattern": "[target.spec] Target should close a service worker",
|
||||
"platforms": ["darwin", "linux", "win32"],
|
||||
"parameters": ["cdp", "chrome", "chrome-headless-shell"],
|
||||
"expectations": ["SKIP"],
|
||||
"comment": "For some reason service_workers do not close in chrome-headless-shell"
|
||||
},
|
||||
{
|
||||
"testIdPattern": "[worker.spec] Workers Page.workers",
|
||||
"platforms": ["darwin", "linux", "win32"],
|
||||
|
@ -179,6 +179,29 @@ describe('Target', function () {
|
||||
})
|
||||
).toBe('[object ServiceWorkerGlobalScope]');
|
||||
});
|
||||
|
||||
it('should close a service worker', async () => {
|
||||
const {page, server, context} = await getTestState();
|
||||
|
||||
await page.goto(server.PREFIX + '/serviceworkers/empty/sw.html');
|
||||
|
||||
const target = await context.waitForTarget(
|
||||
target => {
|
||||
return target.type() === 'service_worker';
|
||||
},
|
||||
{timeout: 3000}
|
||||
);
|
||||
const worker = (await target.worker())!;
|
||||
|
||||
const onceDestroyed = new Promise(resolve => {
|
||||
context.once('targetdestroyed', event => {
|
||||
resolve(event);
|
||||
});
|
||||
});
|
||||
await worker.close();
|
||||
expect(await onceDestroyed).toBe(target);
|
||||
});
|
||||
|
||||
it('should create a worker from a shared worker', async () => {
|
||||
const {page, server, context} = await getTestState();
|
||||
|
||||
@ -199,6 +222,31 @@ describe('Target', function () {
|
||||
})
|
||||
).toBe('[object SharedWorkerGlobalScope]');
|
||||
});
|
||||
|
||||
it('should close a shared worker', async () => {
|
||||
const {page, server, context} = await getTestState();
|
||||
|
||||
await page.goto(server.EMPTY_PAGE);
|
||||
await page.evaluate(() => {
|
||||
new SharedWorker('data:text/javascript,console.log("hi2")');
|
||||
});
|
||||
const target = await context.waitForTarget(
|
||||
target => {
|
||||
return target.type() === 'shared_worker';
|
||||
},
|
||||
{timeout: 3000}
|
||||
);
|
||||
const worker = (await target.worker())!;
|
||||
|
||||
const onceDestroyed = new Promise(resolve => {
|
||||
context.once('targetdestroyed', event => {
|
||||
resolve(event);
|
||||
});
|
||||
});
|
||||
await worker.close();
|
||||
expect(await onceDestroyed).toBe(target);
|
||||
});
|
||||
|
||||
it('should report when a target url changes', async () => {
|
||||
const {page, server, context} = await getTestState();
|
||||
|
||||
|
@ -106,4 +106,17 @@ describe('Workers', function () {
|
||||
const errorLog = await errorPromise;
|
||||
expect(errorLog.message).toContain('this is my error');
|
||||
});
|
||||
|
||||
it('can be closed', async () => {
|
||||
const {page, server} = await getTestState();
|
||||
|
||||
await Promise.all([
|
||||
waitEvent(page, 'workercreated'),
|
||||
page.goto(server.PREFIX + '/worker/worker.html'),
|
||||
]);
|
||||
const worker = page.workers()[0]!;
|
||||
expect(worker?.url()).toContain('worker.js');
|
||||
|
||||
await Promise.all([waitEvent(page, 'workerdestroyed'), worker?.close()]);
|
||||
});
|
||||
});
|
||||
|
Loading…
Reference in New Issue
Block a user