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 |
|
| 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). |
|
| [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). |
|
| [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. |
|
| [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
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
import {UnsupportedOperation} from '../common/Errors.js';
|
||||||
import {EventEmitter, type EventType} from '../common/EventEmitter.js';
|
import {EventEmitter, type EventType} from '../common/EventEmitter.js';
|
||||||
import {TimeoutSettings} from '../common/TimeoutSettings.js';
|
import {TimeoutSettings} from '../common/TimeoutSettings.js';
|
||||||
import type {EvaluateFunc, HandleFor} from '../common/types.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);
|
func = withSourcePuppeteerURLIfNone(this.evaluateHandle.name, func);
|
||||||
return await this.mainRealm().evaluateHandle(func, ...args);
|
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(
|
const worker = new CdpWebWorker(
|
||||||
session,
|
session,
|
||||||
session._target().url(),
|
session._target().url(),
|
||||||
|
session._target()._targetId,
|
||||||
|
session._target().type(),
|
||||||
this.#addConsoleMessage.bind(this),
|
this.#addConsoleMessage.bind(this),
|
||||||
this.#handleException.bind(this)
|
this.#handleException.bind(this)
|
||||||
);
|
);
|
||||||
|
@ -290,6 +290,8 @@ export class WorkerTarget extends CdpTarget {
|
|||||||
return new CdpWebWorker(
|
return new CdpWebWorker(
|
||||||
client,
|
client,
|
||||||
this._getTargetInfo().url,
|
this._getTargetInfo().url,
|
||||||
|
this._targetId,
|
||||||
|
this.type(),
|
||||||
() => {} /* consoleAPICalled */,
|
() => {} /* consoleAPICalled */,
|
||||||
() => {} /* exceptionThrown */
|
() => {} /* exceptionThrown */
|
||||||
);
|
);
|
||||||
|
@ -7,6 +7,7 @@ import type {Protocol} from 'devtools-protocol';
|
|||||||
|
|
||||||
import type {CDPSession} from '../api/CDPSession.js';
|
import type {CDPSession} from '../api/CDPSession.js';
|
||||||
import type {Realm} from '../api/Realm.js';
|
import type {Realm} from '../api/Realm.js';
|
||||||
|
import {TargetType} from '../api/Target.js';
|
||||||
import {WebWorker} from '../api/WebWorker.js';
|
import {WebWorker} from '../api/WebWorker.js';
|
||||||
import {TimeoutSettings} from '../common/TimeoutSettings.js';
|
import {TimeoutSettings} from '../common/TimeoutSettings.js';
|
||||||
import {debugError} from '../common/util.js';
|
import {debugError} from '../common/util.js';
|
||||||
@ -37,15 +38,21 @@ export type ExceptionThrownCallback = (
|
|||||||
export class CdpWebWorker extends WebWorker {
|
export class CdpWebWorker extends WebWorker {
|
||||||
#world: IsolatedWorld;
|
#world: IsolatedWorld;
|
||||||
#client: CDPSession;
|
#client: CDPSession;
|
||||||
|
readonly #id: string;
|
||||||
|
readonly #targetType: TargetType;
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
client: CDPSession,
|
client: CDPSession,
|
||||||
url: string,
|
url: string,
|
||||||
|
targetId: string,
|
||||||
|
targetType: TargetType,
|
||||||
consoleAPICalled: ConsoleAPICalledCallback,
|
consoleAPICalled: ConsoleAPICalledCallback,
|
||||||
exceptionThrown: ExceptionThrownCallback
|
exceptionThrown: ExceptionThrownCallback
|
||||||
) {
|
) {
|
||||||
super(url);
|
super(url);
|
||||||
|
this.#id = targetId;
|
||||||
this.#client = client;
|
this.#client = client;
|
||||||
|
this.#targetType = targetType;
|
||||||
this.#world = new IsolatedWorld(this, new TimeoutSettings());
|
this.#world = new IsolatedWorld(this, new TimeoutSettings());
|
||||||
|
|
||||||
this.#client.once('Runtime.executionContextCreated', async event => {
|
this.#client.once('Runtime.executionContextCreated', async event => {
|
||||||
@ -79,4 +86,25 @@ export class CdpWebWorker extends WebWorker {
|
|||||||
get client(): CDPSession {
|
get client(): CDPSession {
|
||||||
return this.#client;
|
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"],
|
"parameters": ["webDriverBiDi"],
|
||||||
"expectations": ["PASS"]
|
"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",
|
"testIdPattern": "[target.spec] Target should contain browser target",
|
||||||
"platforms": ["darwin", "linux", "win32"],
|
"platforms": ["darwin", "linux", "win32"],
|
||||||
@ -4290,6 +4304,20 @@
|
|||||||
"parameters": ["firefox", "webDriverBiDi"],
|
"parameters": ["firefox", "webDriverBiDi"],
|
||||||
"expectations": ["PASS"]
|
"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",
|
"testIdPattern": "[target.spec] Target should contain browser target",
|
||||||
"platforms": ["darwin", "linux", "win32"],
|
"platforms": ["darwin", "linux", "win32"],
|
||||||
@ -4735,6 +4763,13 @@
|
|||||||
"parameters": ["cdp", "firefox", "headless"],
|
"parameters": ["cdp", "firefox", "headless"],
|
||||||
"expectations": ["FAIL"]
|
"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",
|
"testIdPattern": "[worker.spec] Workers Page.workers",
|
||||||
"platforms": ["darwin", "linux", "win32"],
|
"platforms": ["darwin", "linux", "win32"],
|
||||||
|
@ -179,6 +179,29 @@ describe('Target', function () {
|
|||||||
})
|
})
|
||||||
).toBe('[object ServiceWorkerGlobalScope]');
|
).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 () => {
|
it('should create a worker from a shared worker', async () => {
|
||||||
const {page, server, context} = await getTestState();
|
const {page, server, context} = await getTestState();
|
||||||
|
|
||||||
@ -199,6 +222,31 @@ describe('Target', function () {
|
|||||||
})
|
})
|
||||||
).toBe('[object SharedWorkerGlobalScope]');
|
).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 () => {
|
it('should report when a target url changes', async () => {
|
||||||
const {page, server, context} = await getTestState();
|
const {page, server, context} = await getTestState();
|
||||||
|
|
||||||
|
@ -106,4 +106,17 @@ describe('Workers', function () {
|
|||||||
const errorLog = await errorPromise;
|
const errorLog = await errorPromise;
|
||||||
expect(errorLog.message).toContain('this is my error');
|
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