mirror of
https://github.com/puppeteer/puppeteer
synced 2024-06-14 14:02:48 +00:00
feat(workers): create workers from service workers and shared workers (#4397)
This allows users to easily evaluate javascript inside service workers and shared workers by creating a Worker object for them.
This commit is contained in:
parent
ef24c69c62
commit
1516e0df21
10
docs/api.md
10
docs/api.md
@ -304,6 +304,7 @@
|
||||
* [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)
|
||||
@ -3479,13 +3480,18 @@ Get the target that opened this target. Top-level targets return `null`.
|
||||
If the target is not of type `"page"` or `"background_page"`, returns `null`.
|
||||
|
||||
#### target.type()
|
||||
- returns: <"page"|"background_page"|"service_worker"|"other"|"browser">
|
||||
- returns: <"page"|"background_page"|"service_worker"|"shared_worker"|"other"|"browser">
|
||||
|
||||
Identifies what kind of target this is. Can be `"page"`, [`"background_page"`](https://developer.chrome.com/extensions/background_pages), `"service_worker"`, `"browser"` or `"other"`.
|
||||
Identifies what kind of target this is. Can be `"page"`, [`"background_page"`](https://developer.chrome.com/extensions/background_pages), `"service_worker"`, `"shared_worker"`, `"browser"` or `"other"`.
|
||||
|
||||
#### target.url()
|
||||
- returns: <[string]>
|
||||
|
||||
#### target.worker()
|
||||
- returns: <[Promise]<?[Worker]>>
|
||||
|
||||
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)
|
||||
|
@ -16,6 +16,8 @@
|
||||
|
||||
const {Events} = require('./Events');
|
||||
const {Page} = require('./Page');
|
||||
const {Worker} = require('./Worker');
|
||||
const {Connection} = require('./Connection');
|
||||
|
||||
class Target {
|
||||
/**
|
||||
@ -36,6 +38,8 @@ class Target {
|
||||
this._screenshotTaskQueue = screenshotTaskQueue;
|
||||
/** @type {?Promise<!Puppeteer.Page>} */
|
||||
this._pagePromise = null;
|
||||
/** @type {?Promise<!Worker>} */
|
||||
this._workerPromise = null;
|
||||
this._initializedPromise = new Promise(fulfill => this._initializedCallback = fulfill).then(async success => {
|
||||
if (!success)
|
||||
return false;
|
||||
@ -73,6 +77,27 @@ class Target {
|
||||
return this._pagePromise;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return {!Promise<?Worker>}
|
||||
*/
|
||||
async worker() {
|
||||
if (this._targetInfo.type !== 'service_worker' && this._targetInfo.type !== 'shared_worker')
|
||||
return null;
|
||||
if (!this._workerPromise) {
|
||||
this._workerPromise = this._sessionFactory().then(async client => {
|
||||
// Top level workers have a fake page wrapping the actual worker.
|
||||
const [targetAttached] = await Promise.all([
|
||||
new Promise(x => client.once('Target.attachedToTarget', x)),
|
||||
client.send('Target.setAutoAttach', {autoAttach: true, waitForDebuggerOnStart: false, flatten: true}),
|
||||
]);
|
||||
const session = Connection.fromSession(client).session(targetAttached.sessionId);
|
||||
// TODO(einbinder): Make workers send their console logs.
|
||||
return new Worker(session, this._targetInfo.url, () => {} /* consoleAPICalled */, () => {} /* exceptionThrown */);
|
||||
});
|
||||
}
|
||||
return this._workerPromise;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return {string}
|
||||
*/
|
||||
@ -81,11 +106,11 @@ class Target {
|
||||
}
|
||||
|
||||
/**
|
||||
* @return {"page"|"background_page"|"service_worker"|"other"|"browser"}
|
||||
* @return {"page"|"background_page"|"service_worker"|"shared_worker"|"other"|"browser"}
|
||||
*/
|
||||
type() {
|
||||
const type = this._targetInfo.type;
|
||||
if (type === 'page' || type === 'background_page' || type === 'service_worker' || type === 'browser')
|
||||
if (type === 'page' || type === 'background_page' || type === 'service_worker' || type === 'shared_worker' || type === 'browser')
|
||||
return type;
|
||||
return 'other';
|
||||
}
|
||||
|
@ -83,6 +83,22 @@ module.exports.addTests = function({testRunner, expect, puppeteer}) {
|
||||
await page.evaluate(() => window.registrationPromise.then(registration => registration.unregister()));
|
||||
expect(await destroyedTarget).toBe(await createdTarget);
|
||||
});
|
||||
it_fails_ffox('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_fails_ffox('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('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)));
|
||||
|
Loading…
Reference in New Issue
Block a user