fix: ignore console messages from destroyed execution contexts (#3866)

Fix #3865
This commit is contained in:
Andrey Lushnikov 2019-01-30 16:19:02 -08:00 committed by GitHub
parent 7001042f79
commit a2f1e2774a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 34 additions and 0 deletions

View File

@ -517,6 +517,22 @@ class Page extends EventEmitter {
* @param {!Protocol.Runtime.consoleAPICalledPayload} event
*/
async _onConsoleAPI(event) {
if (event.executionContextId === 0) {
// DevTools protocol stores the last 1000 console messages. These
// messages are always reported even for removed execution contexts. In
// this case, they are marked with executionContextId = 0 and are
// reported upon enabling Runtime agent.
//
// Ignore these messages since:
// - there's no execution context we can use to operate with message
// arguments
// - these messages are reported before Puppeteer clients can subscribe
// to the 'console'
// page event.
//
// @see https://github.com/GoogleChrome/puppeteer/issues/3865
return;
}
const context = this._frameManager.executionContextById(event.executionContextId);
const values = event.args.map(arg => createJSHandle(context, arg));
this._addConsoleMessage(event.type, values, event.stackTrace);

View File

@ -350,6 +350,24 @@ module.exports.addTests = function({testRunner, expect, headless}) {
columnNumber: 14,
});
});
// @see https://github.com/GoogleChrome/puppeteer/issues/3865
it('should not throw when there are console messages in detached iframes', async({browser, page, server}) => {
await page.goto(server.EMPTY_PAGE);
await page.evaluate(async() => {
// 1. Create a popup that Puppeteer is not connected to.
const win = window.open(window.location.href, 'Title', 'toolbar=no,location=no,directories=no,status=no,menubar=no,scrollbars=yes,resizable=yes,width=780,height=200,top=0,left=0');
await new Promise(x => win.onload = x);
// 2. In this popup, create an iframe that console.logs a message.
win.document.body.innerHTML = `<iframe src='/consolelog.html'></iframe>`;
const frame = win.document.querySelector('iframe');
await new Promise(x => frame.onload = x);
// 3. After that, remove the iframe.
frame.remove();
});
const popupTarget = page.browserContext().targets().find(target => target !== page.target());
// 4. Connect to the popup and make sure it doesn't throw.
await popupTarget.page();
});
});
describe('Page.Events.DOMContentLoaded', function() {