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()`:
|
||||
|
||||
```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}`));
|
||||
```
|
||||
|
32
docs/api.md
32
docs/api.md
@ -99,6 +99,10 @@
|
||||
+ [dialog.dismiss()](#dialogdismiss)
|
||||
+ [dialog.message()](#dialogmessage)
|
||||
+ [dialog.type](#dialogtype)
|
||||
* [class: ConsoleMessage](#class-consolemessage)
|
||||
+ [consoleMessage.args](#consolemessageargs)
|
||||
+ [consoleMessage.text](#consolemessagetext)
|
||||
+ [consoleMessage.type](#consolemessagetype)
|
||||
* [class: Frame](#class-frame)
|
||||
+ [frame.$(selector)](#frameselector)
|
||||
+ [frame.$$(selector)](#frameselector)
|
||||
@ -249,7 +253,7 @@ puppeteer.launch().then(async browser => {
|
||||
```
|
||||
|
||||
#### 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.
|
||||
|
||||
@ -257,11 +261,11 @@ The arguments passed into `console.log` appear as arguments on the event handler
|
||||
|
||||
An example of handling `console` event:
|
||||
```js
|
||||
page.on('console', (...args) => {
|
||||
for (let i = 0; i < args.length; ++i)
|
||||
page.on('console', msg => {
|
||||
for (let i = 0; i < msg.args.length; ++i)
|
||||
console.log(`${i}: ${args[i]}`);
|
||||
});
|
||||
page.evaluate(() => console.log(5, 'hello', {foo: 'bar'}));
|
||||
page.evaluate(() => console.log('hello', 5, {foo: 'bar'}));
|
||||
```
|
||||
|
||||
#### event: 'dialog'
|
||||
@ -514,7 +518,7 @@ const crypto = require('crypto');
|
||||
|
||||
puppeteer.launch().then(async browser => {
|
||||
const page = await browser.newPage();
|
||||
page.on('console', console.log);
|
||||
page.on('console', msg => console.log(msg.text));
|
||||
await page.exposeFunction('md5', text =>
|
||||
crypto.createHash('md5').update(text).digest('hex')
|
||||
);
|
||||
@ -536,7 +540,7 @@ const fs = require('fs');
|
||||
|
||||
puppeteer.launch().then(async browser => {
|
||||
const page = await browser.newPage();
|
||||
page.on('console', console.log);
|
||||
page.on('console', msg => console.log(msg.text));
|
||||
await page.exposeFunction('readfile', async filePath => {
|
||||
return new Promise((resolve, reject) => {
|
||||
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`.
|
||||
|
||||
### 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
|
||||
|
||||
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"
|
||||
[Error]: https://nodejs.org/api/errors.html#errors_class_error "Error"
|
||||
[Frame]: #class-frame "Frame"
|
||||
[ConsoleMessage]: #class-consolemessage "ConsoleMessage"
|
||||
[iterator]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Iteration_protocols "Iterator"
|
||||
[Response]: #class-response "Response"
|
||||
[Request]: #class-request "Request"
|
||||
|
17
lib/Page.js
17
lib/Page.js
@ -313,7 +313,9 @@ class Page extends EventEmitter {
|
||||
return;
|
||||
}
|
||||
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) {
|
||||
@ -875,6 +877,19 @@ Page.Viewport;
|
||||
* @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;
|
||||
helper.tracePublicAPI(Page);
|
||||
|
25
test/test.js
25
test/test.js
@ -537,13 +537,15 @@ describe('Page', function() {
|
||||
|
||||
describe('Page.Events.Console', function() {
|
||||
it('should work', SX(async function() {
|
||||
let commandArgs = [];
|
||||
page.once('console', (...args) => commandArgs = args);
|
||||
let message = null;
|
||||
page.once('console', m => message = m);
|
||||
await Promise.all([
|
||||
page.evaluate(() => console.log(5, 'hello', {foo: 'bar'})),
|
||||
page.evaluate(() => console.log('hello', 5, {foo: 'bar'})),
|
||||
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() {
|
||||
const messages = [];
|
||||
@ -559,11 +561,14 @@ describe('Page', function() {
|
||||
console.error('calling console.error');
|
||||
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)
|
||||
]);
|
||||
expect(messages[0]).toContain('calling console.time');
|
||||
expect(messages.slice(1)).toEqual([
|
||||
expect(messages.map(msg => msg.type)).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.dir',
|
||||
'calling console.warn',
|
||||
@ -572,13 +577,13 @@ describe('Page', function() {
|
||||
]);
|
||||
}));
|
||||
it('should not fail for window object', SX(async function() {
|
||||
let windowObj = null;
|
||||
page.once('console', arg => windowObj = arg);
|
||||
let message = null;
|
||||
page.once('console', msg => message = msg);
|
||||
await Promise.all([
|
||||
page.evaluate(() => console.error(window)),
|
||||
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([
|
||||
'Body.constructor',
|
||||
'Browser.constructor',
|
||||
'ConsoleMessage.constructor',
|
||||
'Dialog.constructor',
|
||||
'ElementHandle.constructor',
|
||||
'Frame.constructor',
|
||||
|
Loading…
Reference in New Issue
Block a user