I have a React/Redux app that I am testing using Puppeteer. Based on the documentation, I am using the following code to show the console outputs:
page.on('console', msg => {
for(let i = 0; i < msg.args().length; ++i) {
let text = msg.args()[i];
console.log(`${i}: ${text}`);
}
});
However, when the redux-logger logs an object to console (prevState, nextState), Puppeeter shows JSHandle@object
in my console outputs instead. How do I see the keys and properties inside this object?
If you place the consoleMessage.args()
directly inside console.log()
without enclosing them in template literals, you can print the keys and values of the JSHandles that represent each argument passed to console.log()
in the page context:
page.on('console', msg => {
for (let i = 0; i < msg.args().length; i++) {
console.log(msg.args()[i]);
}
});
The beginning of the result will look something like this:
JSHandle {
_context:
ExecutionContext {
_client:
CDPSession {
domain: null,
_events: [Object],
...
You can get args
from JSHandle
with await
for it.
The best way for me was next to describe errors from the browser and catch needed types of console
notifications:
import { ConsoleMessage, Page, JSHandle } from 'puppeteer';
const chalk = require('chalk');
export const listenPageErrors = async (page: Page) => {
// make args accessible
const describe = (jsHandle) => {
return jsHandle.executionContext().evaluate((obj) => {
// serialize |obj| however you want
return `OBJ: ${typeof obj}, ${obj}`;
}, jsHandle);
}
const colors: any = {
LOG: chalk.grey, // (text: any) => text,
ERR: chalk.red,
WAR: chalk.yellow,
INF: chalk.cyan,
};
// listen to browser console there
page.on('console', async (message: ConsoleMessage) => {
const args = await Promise.all(message.args().map(arg => describe(arg)));
// make ability to paint different console[types]
const type = message.type().substr(0, 3).toUpperCase();
const color = colors[type] || chalk.blue;
let text = '';
for (let i = 0; i < args.length; ++i) {
text += `[${i}] ${args[i]} `;
}
console.log(color(`CONSOLE.${type}: ${message.text()}\n${text} `));
});
}
Put it between const page = await browser.newPage();
and page.goto(URL)
, and it will work as should
const page = await browser.newPage();
await listenPageErrors(page); // <- like there
page.goto(URL)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With