diff --git a/README.md b/README.md index a3f44d4..ec62c00 100644 --- a/README.md +++ b/README.md @@ -689,7 +689,8 @@ Emitted when the remote instance sends any notification through the WebSocket. - `method`: a string describing the notification (e.g., `'Network.requestWillBeSent'`); -- `params`: an object containing the payload. +- `params`: an object containing the payload; +- `sessionId`: an optional string representing the session identifier. Refer to the [Chrome Debugging Protocol] specification for more information. @@ -706,7 +707,7 @@ client.on('event', (message) => { #### Event: '``.``' ```js -function (params) {} +function (params, sessionId) {} ``` Emitted when the remote instance sends a notification for `.` @@ -714,6 +715,8 @@ through the WebSocket. `params` is an object containing the payload. +`sessionId` is an optional string representing the session identifier. + This is just a utility event which allows to easily listen for specific notifications (see [`'event'`](#event-event)), for example: @@ -727,6 +730,18 @@ Additionally, the equivalent `.on('', ...)` syntax is available, client.Network.on('requestWillBeSent', console.log); ``` +#### Event: '``.``.``' + +```js +function (params, sessionId) {} +``` + +Equivalent to the following but only for those events belonging to the given `session`: + +```js +client.on('.', callback); +``` + #### Event: 'ready' ```js @@ -819,16 +834,16 @@ For example: client.Page.navigate({url: 'https://github.com'}, console.log); ``` -#### client.``.``([callback]) +#### client.``.``([sessionId], [callback]) Just a shorthand for: ```js -client.on('.', callback); +client.on('.[.]', callback); ``` When `callback` is omitted the event is registered only once and a `Promise` -object is returned. +object is returned. Notice though that in this case the optional `sessionId` usually passed to `callback` is not returned. When `callback` is provided, it returns a function that can be used to unsubscribe `callback` from the event, it can be useful when anonymous functions @@ -837,7 +852,7 @@ are used as callbacks. For example: ```js -const unsubscribe = client.Network.requestWillBeSent((params) => { +const unsubscribe = client.Network.requestWillBeSent((params, sessionId) => { console.log(params.request.url); }); unsubscribe(); diff --git a/lib/api.js b/lib/api.js index b1dd2a2..6e6474e 100644 --- a/lib/api.js +++ b/lib/api.js @@ -37,13 +37,18 @@ function addCommand(chrome, domainName, command) { function addEvent(chrome, domainName, event) { const eventName = `${domainName}.${event.name}`; - const handler = (handler) => { + const handler = (sessionId, handler) => { + if (typeof sessionId === 'function') { + handler = sessionId; + sessionId = undefined; + } + const rawEventName = sessionId ? `${eventName}.${sessionId}` : eventName; if (typeof handler === 'function') { - chrome.on(eventName, handler); - return () => chrome.removeListener(eventName, handler); + chrome.on(rawEventName, handler); + return () => chrome.removeListener(rawEventName, handler); } else { return new Promise((fulfill, reject) => { - chrome.once(eventName, fulfill); + chrome.once(rawEventName, fulfill); }); } }; diff --git a/lib/chrome.js b/lib/chrome.js index 9895a88..ed802aa 100644 --- a/lib/chrome.js +++ b/lib/chrome.js @@ -267,8 +267,10 @@ class Chrome extends EventEmitter { } // event else if (message.method) { + const {method, params, sessionId} = message; this.emit('event', message); - this.emit(message.method, message.params); + this.emit(method, params, sessionId); + this.emit(`${method}.${sessionId}`, params, sessionId); } } diff --git a/test/event.js b/test/event.js index de1752e..241436a 100644 --- a/test/event.js +++ b/test/event.js @@ -92,4 +92,45 @@ describe('registering event', () => { }); }); }); + describe('passing a sessionId', () => { + it('should only listen for those events', async () => { + // fetch and connect to the browser target + const version = await Chrome.Version(); + const chrome = await Chrome({ + target: version.webSocketDebuggerUrl + }); + // create another target + await chrome.Target.createTarget({url: 'about:blank'}); + // fetch the targets (two pages) and attach to each of them + const {targetInfos} = await chrome.Target.getTargets(); + const {sessionId: sessionId0} = await chrome.Target.attachToTarget({ + targetId: targetInfos[0].targetId, + flatten: true + }); + const {sessionId: sessionId1} = await chrome.Target.attachToTarget({ + targetId: targetInfos[1].targetId, + flatten: true + }); + // enable the Page events in both of them + await chrome.Page.enable(sessionId0); + await chrome.Page.enable(sessionId1); + // trigger a reload in both of them + chrome.Page.reload(sessionId0); + chrome.Page.reload(sessionId1); + // awaits individual events + await Promise.all([ + chrome.Page.loadEventFired(sessionId0), + chrome.Page.loadEventFired(sessionId1), + new Promise((fulfill, reject) => { + let counter = 0; + chrome.Page.loadEventFired((params) => { + if (++counter === 2) { + fulfill(); + } + }); + }) + ]); + return chrome.close(); + }); + }); });