最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - How do print the console output of the page in Puppeteer as it would appear in the browser? - Stack Overflow

programmeradmin3浏览0评论

I keep seeing this WRONG CODE

page.on('console', msg => console.log(msg.text()));

That FAILS

console.log('Hello %s', 'World');

produces

Hello World     // browser
Hello %s World  // puppeteer

Ok, So I thought maybe I could do this

page.on('console', msg => console.log(...msg.args()));

NOPE: That dumps out some giant JSHandle thing.

Ok, So maybe

page.on('console', msg => console.log(...msg.args().map(a => a.toString());

NOPE: That prints

JSHandle: Hello %s JSHandle: World

I suppose I can hack it by removing the first 9 characters.

I also tried

page.on('console', msg => console.log(...msg.args().map(a => a.jsonValue())));

NOPE: That prints

Promise { <pending> } Promise { <pending> }

Okay how about

page.on('console', async(msg) => {
  const args = Promise.all(msg.args().map(a => a.jsonValue()));
  console.log(...args);
});

Nope, That prints

UnhandledPromiseRejectionWarning: TypeError: Found non-callable @@iterator
UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). (rejection id: 95)

Another go

page.on('console', async(msg) => {
  const args = Promise.all(msg.args().map(async(a) => {
    return await a.jsonValue();
  }));
  console.log(...args);
});

same as before

UnhandledPromiseRejectionWarning: TypeError: Found non-callable @@iterator
UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a 

I even traced through msg.text() but all it does is return a premade string so it's too late to use that.

How do I get the same output as the browser's console.log in puppeteer?


PS: as mentioned above, this hack works in puppeteer 1.20.0

  page.on('console', (msg) => {
    console.log(...msg.args().map(v => v.toString().substr(9)));
  });

but it's clearly a hack and I expect it will break at some point so looking for the correct solution.

I keep seeing this WRONG CODE

page.on('console', msg => console.log(msg.text()));

That FAILS

console.log('Hello %s', 'World');

produces

Hello World     // browser
Hello %s World  // puppeteer

Ok, So I thought maybe I could do this

page.on('console', msg => console.log(...msg.args()));

NOPE: That dumps out some giant JSHandle thing.

Ok, So maybe

page.on('console', msg => console.log(...msg.args().map(a => a.toString());

NOPE: That prints

JSHandle: Hello %s JSHandle: World

I suppose I can hack it by removing the first 9 characters.

I also tried

page.on('console', msg => console.log(...msg.args().map(a => a.jsonValue())));

NOPE: That prints

Promise { <pending> } Promise { <pending> }

Okay how about

page.on('console', async(msg) => {
  const args = Promise.all(msg.args().map(a => a.jsonValue()));
  console.log(...args);
});

Nope, That prints

UnhandledPromiseRejectionWarning: TypeError: Found non-callable @@iterator
UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). (rejection id: 95)

Another go

page.on('console', async(msg) => {
  const args = Promise.all(msg.args().map(async(a) => {
    return await a.jsonValue();
  }));
  console.log(...args);
});

same as before

UnhandledPromiseRejectionWarning: TypeError: Found non-callable @@iterator
UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a 

I even traced through msg.text() but all it does is return a premade string so it's too late to use that.

How do I get the same output as the browser's console.log in puppeteer?


PS: as mentioned above, this hack works in puppeteer 1.20.0

  page.on('console', (msg) => {
    console.log(...msg.args().map(v => v.toString().substr(9)));
  });

but it's clearly a hack and I expect it will break at some point so looking for the correct solution.

Share Improve this question edited Jan 8, 2024 at 2:40 ggorlen 57.1k8 gold badges110 silver badges150 bronze badges asked Sep 24, 2019 at 23:51 user128511user128511 3
  • Maybe I just need to file a bug...., given that msg.text is wrong the issue is deeper. – user128511 Commented Sep 25, 2019 at 0:18
  • Anything that passes the browser to node or node to browser get's serialized. So %s and anything else would not probably work. – Md. Abu Taher Commented Sep 25, 2019 at 10:22
  • If I can get the original arguments then I can call console.log with them. But as seen above my attempt to get the original arguments fails. They are prefixed by JSHandle:. I can do msg.args().map(v => v.toString().substr(9)) to get them but that seems like a hack so I'm ask what's the correct way to do it. – user128511 Commented Sep 25, 2019 at 11:07
Add a ment  | 

2 Answers 2

Reset to default 11
  page.on('console', async e => {
    const args = await Promise.all(e.args().map(a => a.jsonValue()));
    console.log(...args);
  });

or

  page.on('console', async e => {
    const args = await Promise.all(e.args().map(a => a.jsonValue()));
    console[e.type() === 'warning' ? 'warn' : e.type()](...args);
  });

works

You can use msg.args(), and the workaround will be like this.

page.on('console', async msg => {
  const args = await msg.args()
  args.forEach(async (arg) => {
    const val = await arg.jsonValue()
    // value is serializable
    if (JSON.stringify(val) !== JSON.stringify({})) console.log(val)
    // value is unserializable (or an empty oject)
    else {
      const { type, subtype, description } = arg._remoteObject
      console.log(`type: ${type}, subtype: ${subtype}, description:\n ${description}`)
    }
  })
});

Or something like this, to print only the Error

page.on('console', async msg => {
  // serialize my args the way I want
  const args = await Promise.all(msg.args.map(arg => arg.executionContext().evaluate(arg => {
    // I'm in a page context now. If my arg is an error - get me its message.
    if (arg instanceof Error)
      return arg.message;
    // return arg right away. since we use `executionContext.evaluate`, it'll return JSON value of
    // the argument if possible, or `undefined` if it fails to stringify it.
    return arg;
  }, arg)));
  console.log(...args);
});

与本文相关的文章

发布评论

评论列表(0)

  1. 暂无评论