I am following this issue post here:
https://github.com/cyrus-and/chrome-remote-interface/issues/105
But I cannot seem to get console.log
output
I've been doing some research on this; below are some of my findings:
When evaluating:
const result = await Runtime.evaluate({ expression: 'console.log("aaa")' });
Result is always:
{ result: { type: 'undefined' } }
However, the following expression:
const result = await Runtime.evaluate({expression: 'window.location.toString()'});
Returns:
{ result: { type: 'string', value: 'https://www.chromestatus.com/features' } }
Now if I evaluate the function without invoking it:
const result = await Runtime.evaluate({ expression: 'console.log' });
Result is set to:
{ result: { type: 'function', className: 'Function', description: 'function log() { [native code] }', objectId: '{"injectedScriptId":2,"id":1}' } }
So I did some more digging, and found that every time console.log
is invoked when evaluated, the messageAdded event on the Console object is always fired.
So I went ahead and enabled the Console object and added a listener to the messageAdded event, and now I can successfully capture the console entry as expected.
This is what I did:
const chromeLauncher = require('chrome-launcher');
const CDP = require('chrome-remote-interface');
const file = require('fs');
(async function() {
async function launchChrome() {
return await chromeLauncher.launch({
chromeFlags: [
'--headless',
'--disable-gpu'
]
});
}
const chrome = await launchChrome();
const protocol = await CDP({
port: chrome.port
});
const {
DOM,
Network,
Page,
Emulation,
Runtime,
Console
} = protocol;
await Promise.all([Network.enable(), Page.enable(), DOM.enable(), Runtime.enable(), Console.enable()]);
await Page.navigate({url: 'https://www.chromestatus.com/'});
// REMARKS: messageAdded is fired every time a new console message is added
Console.messageAdded((result) => {
console.log(result);
});
Page.loadEventFired(async () => {
const result = await Runtime.evaluate({ expression: 'console.log("aaa")' });
// REMARKS: When evaluating console.log, result.result.value is undefined.
console.log(result);
protocol.close();
chrome.kill();
});
})();
/* Output from listening on messageAdded:
{ message:
{ source: 'console-api',
level: 'log',
text: 'aaa',
url: '',
line: 1,
column: 9 } }
*/
I got the details from Chrome DevTools Protocol Viewer - Console
From the documentation:
Console.messageAdded
Issued when new console message is added.
Hope this helps!
For those who want a less complicated way to get data from a page I'd recommend puppeteer. It has a much clearer higher-level API than chrome-remote-interface. The best feature in my opinion is its ability to accept javascript functions instead of strings for evaluation.
Let's say we want to fetch some data from API in context of a given page.
const puppeteer = require('puppeteer');
(async () => {
const browser = await puppeteer.launch();
const page = await browser.newPage();
await page.goto('https://example.com/');
let result = await page.evaluate(async () => {
// here comes the code which gets executed in browser
return await fetch('index.html').then(response => response.text());
});
console.log(result);
await browser.close();
})();