feat(Console): Introduce ConsoleMessage type (#909)
This patch introduces ConsoleMessage type and starts dispatching it for the 'console' event. BREAKING CHANGE: this breaks the api of the 'console' event. Fixes #744.
This commit is contained in:
parent
cfece3451d
commit
f6255029bd
@ -153,7 +153,7 @@ Explore the [API documentation](docs/api.md) and [examples](https://github.com/G
|
|||||||
This is also handy when debugging code in `page.evaluate()`:
|
This is also handy when debugging code in `page.evaluate()`:
|
||||||
|
|
||||||
```js
|
```js
|
||||||
page.on('console', (...args) => console.log('PAGE LOG:', ...args));
|
page.on('console', msg => console.log('PAGE LOG:', ...msg.args));
|
||||||
|
|
||||||
await page.evaluate(() => console.log(`url is ${location.href}`));
|
await page.evaluate(() => console.log(`url is ${location.href}`));
|
||||||
```
|
```
|
||||||
|
32
docs/api.md
32
docs/api.md
@ -99,6 +99,10 @@
|
|||||||
+ [dialog.dismiss()](#dialogdismiss)
|
+ [dialog.dismiss()](#dialogdismiss)
|
||||||
+ [dialog.message()](#dialogmessage)
|
+ [dialog.message()](#dialogmessage)
|
||||||
+ [dialog.type](#dialogtype)
|
+ [dialog.type](#dialogtype)
|
||||||
|
* [class: ConsoleMessage](#class-consolemessage)
|
||||||
|
+ [consoleMessage.args](#consolemessageargs)
|
||||||
|
+ [consoleMessage.text](#consolemessagetext)
|
||||||
|
+ [consoleMessage.type](#consolemessagetype)
|
||||||
* [class: Frame](#class-frame)
|
* [class: Frame](#class-frame)
|
||||||
+ [frame.$(selector)](#frameselector)
|
+ [frame.$(selector)](#frameselector)
|
||||||
+ [frame.$$(selector)](#frameselector)
|
+ [frame.$$(selector)](#frameselector)
|
||||||
@ -249,7 +253,7 @@ puppeteer.launch().then(async browser => {
|
|||||||
```
|
```
|
||||||
|
|
||||||
#### event: 'console'
|
#### event: 'console'
|
||||||
- <[string]>
|
- <[ConsoleMessage]>
|
||||||
|
|
||||||
Emitted when JavaScript within the page calls one of console API methods, e.g. `console.log` or `console.dir`. Also emitted if the page throws an error or a warning.
|
Emitted when JavaScript within the page calls one of console API methods, e.g. `console.log` or `console.dir`. Also emitted if the page throws an error or a warning.
|
||||||
|
|
||||||
@ -257,11 +261,11 @@ The arguments passed into `console.log` appear as arguments on the event handler
|
|||||||
|
|
||||||
An example of handling `console` event:
|
An example of handling `console` event:
|
||||||
```js
|
```js
|
||||||
page.on('console', (...args) => {
|
page.on('console', msg => {
|
||||||
for (let i = 0; i < args.length; ++i)
|
for (let i = 0; i < msg.args.length; ++i)
|
||||||
console.log(`${i}: ${args[i]}`);
|
console.log(`${i}: ${args[i]}`);
|
||||||
});
|
});
|
||||||
page.evaluate(() => console.log(5, 'hello', {foo: 'bar'}));
|
page.evaluate(() => console.log('hello', 5, {foo: 'bar'}));
|
||||||
```
|
```
|
||||||
|
|
||||||
#### event: 'dialog'
|
#### event: 'dialog'
|
||||||
@ -514,7 +518,7 @@ const crypto = require('crypto');
|
|||||||
|
|
||||||
puppeteer.launch().then(async browser => {
|
puppeteer.launch().then(async browser => {
|
||||||
const page = await browser.newPage();
|
const page = await browser.newPage();
|
||||||
page.on('console', console.log);
|
page.on('console', msg => console.log(msg.text));
|
||||||
await page.exposeFunction('md5', text =>
|
await page.exposeFunction('md5', text =>
|
||||||
crypto.createHash('md5').update(text).digest('hex')
|
crypto.createHash('md5').update(text).digest('hex')
|
||||||
);
|
);
|
||||||
@ -536,7 +540,7 @@ const fs = require('fs');
|
|||||||
|
|
||||||
puppeteer.launch().then(async browser => {
|
puppeteer.launch().then(async browser => {
|
||||||
const page = await browser.newPage();
|
const page = await browser.newPage();
|
||||||
page.on('console', console.log);
|
page.on('console', msg => console.log(msg.text));
|
||||||
await page.exposeFunction('readfile', async filePath => {
|
await page.exposeFunction('readfile', async filePath => {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
fs.readFile(filePath, 'utf8', (err, text) => {
|
fs.readFile(filePath, 'utf8', (err, text) => {
|
||||||
@ -1093,6 +1097,21 @@ puppeteer.launch().then(async browser => {
|
|||||||
|
|
||||||
Dialog's type, could be one of the `alert`, `beforeunload`, `confirm` and `prompt`.
|
Dialog's type, could be one of the `alert`, `beforeunload`, `confirm` and `prompt`.
|
||||||
|
|
||||||
|
### class: ConsoleMessage
|
||||||
|
|
||||||
|
[ConsoleMessage] objects are dispatched by page via the ['console'](#event-console) event.
|
||||||
|
|
||||||
|
#### consoleMessage.args
|
||||||
|
- <[Array]<[string]>>
|
||||||
|
|
||||||
|
#### consoleMessage.text
|
||||||
|
- <[string]>
|
||||||
|
|
||||||
|
#### consoleMessage.type
|
||||||
|
- <[string]>
|
||||||
|
|
||||||
|
One of the following values: `'log'`, `'debug'`, `'info'`, `'error'`, `'warning'`, `'dir'`, `'dirxml'`, `'table'`, `'trace'`, `'clear'`, `'startGroup'`, `'startGroupCollapsed'`, `'endGroup'`, `'assert'`, `'profile'`, `'profileEnd'`, `'count'`, `'timeEnd'`.
|
||||||
|
|
||||||
### class: Frame
|
### class: Frame
|
||||||
|
|
||||||
At every point of time, page exposes its current frame tree via the [page.mainFrame()](#pagemainframe) and [frame.childFrames()](#framechildframes) methods.
|
At every point of time, page exposes its current frame tree via the [page.mainFrame()](#pagemainframe) and [frame.childFrames()](#framechildframes) methods.
|
||||||
@ -1432,6 +1451,7 @@ Contains the URL of the response.
|
|||||||
[stream.Readable]: https://nodejs.org/api/stream.html#stream_class_stream_readable "stream.Readable"
|
[stream.Readable]: https://nodejs.org/api/stream.html#stream_class_stream_readable "stream.Readable"
|
||||||
[Error]: https://nodejs.org/api/errors.html#errors_class_error "Error"
|
[Error]: https://nodejs.org/api/errors.html#errors_class_error "Error"
|
||||||
[Frame]: #class-frame "Frame"
|
[Frame]: #class-frame "Frame"
|
||||||
|
[ConsoleMessage]: #class-consolemessage "ConsoleMessage"
|
||||||
[iterator]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Iteration_protocols "Iterator"
|
[iterator]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Iteration_protocols "Iterator"
|
||||||
[Response]: #class-response "Response"
|
[Response]: #class-response "Response"
|
||||||
[Request]: #class-request "Request"
|
[Request]: #class-request "Request"
|
||||||
|
17
lib/Page.js
17
lib/Page.js
@ -313,7 +313,9 @@ class Page extends EventEmitter {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const values = await Promise.all(event.args.map(arg => helper.serializeRemoteObject(this._client, arg)));
|
const values = await Promise.all(event.args.map(arg => helper.serializeRemoteObject(this._client, arg)));
|
||||||
this.emit(Page.Events.Console, ...values);
|
const text = values.join(' ');
|
||||||
|
const message = new ConsoleMessage(event.type, text, values);
|
||||||
|
this.emit(Page.Events.Console, message);
|
||||||
}
|
}
|
||||||
|
|
||||||
_onDialog(event) {
|
_onDialog(event) {
|
||||||
@ -875,6 +877,19 @@ Page.Viewport;
|
|||||||
* @property {("Strict"|"Lax")=} sameSite
|
* @property {("Strict"|"Lax")=} sameSite
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
class ConsoleMessage {
|
||||||
|
/**
|
||||||
|
* @param {string} type
|
||||||
|
* @param {string} text
|
||||||
|
* @param {!Array<*>} args
|
||||||
|
*/
|
||||||
|
constructor(type, text, args) {
|
||||||
|
this.type = type;
|
||||||
|
this.text = text;
|
||||||
|
this.args = args;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
module.exports = Page;
|
module.exports = Page;
|
||||||
helper.tracePublicAPI(Page);
|
helper.tracePublicAPI(Page);
|
||||||
|
25
test/test.js
25
test/test.js
@ -537,13 +537,15 @@ describe('Page', function() {
|
|||||||
|
|
||||||
describe('Page.Events.Console', function() {
|
describe('Page.Events.Console', function() {
|
||||||
it('should work', SX(async function() {
|
it('should work', SX(async function() {
|
||||||
let commandArgs = [];
|
let message = null;
|
||||||
page.once('console', (...args) => commandArgs = args);
|
page.once('console', m => message = m);
|
||||||
await Promise.all([
|
await Promise.all([
|
||||||
page.evaluate(() => console.log(5, 'hello', {foo: 'bar'})),
|
page.evaluate(() => console.log('hello', 5, {foo: 'bar'})),
|
||||||
waitForEvents(page, 'console')
|
waitForEvents(page, 'console')
|
||||||
]);
|
]);
|
||||||
expect(commandArgs).toEqual([5, 'hello', {foo: 'bar'}]);
|
expect(message.text).toEqual('hello 5 [object Object]');
|
||||||
|
expect(message.type).toEqual('log');
|
||||||
|
expect(message.args).toEqual(['hello', 5, {foo: 'bar'}]);
|
||||||
}));
|
}));
|
||||||
it('should work for different console API calls', SX(async function() {
|
it('should work for different console API calls', SX(async function() {
|
||||||
const messages = [];
|
const messages = [];
|
||||||
@ -559,11 +561,14 @@ describe('Page', function() {
|
|||||||
console.error('calling console.error');
|
console.error('calling console.error');
|
||||||
console.log(Promise.resolve('should not wait until resolved!'));
|
console.log(Promise.resolve('should not wait until resolved!'));
|
||||||
}),
|
}),
|
||||||
// Wait for 5 events to hit.
|
// Wait for 5 events to hit - console.time is not reported
|
||||||
waitForEvents(page, 'console', 5)
|
waitForEvents(page, 'console', 5)
|
||||||
]);
|
]);
|
||||||
expect(messages[0]).toContain('calling console.time');
|
expect(messages.map(msg => msg.type)).toEqual([
|
||||||
expect(messages.slice(1)).toEqual([
|
'timeEnd', 'trace', 'dir', 'warning', 'error', 'log'
|
||||||
|
]);
|
||||||
|
expect(messages[0].text).toContain('calling console.time');
|
||||||
|
expect(messages.slice(1).map(msg => msg.text)).toEqual([
|
||||||
'calling console.trace',
|
'calling console.trace',
|
||||||
'calling console.dir',
|
'calling console.dir',
|
||||||
'calling console.warn',
|
'calling console.warn',
|
||||||
@ -572,13 +577,13 @@ describe('Page', function() {
|
|||||||
]);
|
]);
|
||||||
}));
|
}));
|
||||||
it('should not fail for window object', SX(async function() {
|
it('should not fail for window object', SX(async function() {
|
||||||
let windowObj = null;
|
let message = null;
|
||||||
page.once('console', arg => windowObj = arg);
|
page.once('console', msg => message = msg);
|
||||||
await Promise.all([
|
await Promise.all([
|
||||||
page.evaluate(() => console.error(window)),
|
page.evaluate(() => console.error(window)),
|
||||||
waitForEvents(page, 'console')
|
waitForEvents(page, 'console')
|
||||||
]);
|
]);
|
||||||
expect(windowObj).toBe('Window');
|
expect(message.text).toBe('Window');
|
||||||
}));
|
}));
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -37,6 +37,7 @@ const EXCLUDE_CLASSES = new Set([
|
|||||||
const EXCLUDE_METHODS = new Set([
|
const EXCLUDE_METHODS = new Set([
|
||||||
'Body.constructor',
|
'Body.constructor',
|
||||||
'Browser.constructor',
|
'Browser.constructor',
|
||||||
|
'ConsoleMessage.constructor',
|
||||||
'Dialog.constructor',
|
'Dialog.constructor',
|
||||||
'ElementHandle.constructor',
|
'ElementHandle.constructor',
|
||||||
'Frame.constructor',
|
'Frame.constructor',
|
||||||
|
Loading…
Reference in New Issue
Block a user