fix(page): fix race condition in WaitTask (#2739)

This patch eliminates a common race condition with WaitTask, that
happens when predicate function gets resolved right before the execution
context gets destroyed.
This situation results in a "Cannot find context with specified id undefined"
exception.

Credits go to @jakub300 for his wonderful [investigation](https://github.com/GoogleChrome/puppeteer/issues/1325#issuecomment-395472092).

Fixes #1325.
This commit is contained in:
Andrey Lushnikov 2018-06-14 11:39:51 -07:00 committed by GitHub
parent ed7a26cc95
commit ddfdaf97c5
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 11 additions and 1 deletions

View File

@ -869,7 +869,9 @@ class WaitTask {
} }
// Ignore timeouts in pageScript - we track timeouts ourselves. // Ignore timeouts in pageScript - we track timeouts ourselves.
if (!error && await this._frame.evaluate(s => !s, success)) { // If the frame's execution context has already changed, `frame.evaluate` will
// throw an error - ignore this predicate run altogether.
if (!error && await this._frame.evaluate(s => !s, success).catch(e => true)) {
await success.dispose(); await success.dispose();
return; return;
} }

View File

@ -84,6 +84,14 @@ module.exports.addTests = function({testRunner, expect}) {
await page.evaluate(() => window.__FOO = 1); await page.evaluate(() => window.__FOO = 1);
await watchdog; await watchdog;
}); });
it('should work when resolved right before execution context disposal', async({page, server}) => {
await page.evaluateOnNewDocument(() => window.__RELOADED = true);
await page.waitForFunction(() => {
if (!window.__RELOADED)
window.location.reload();
return true;
});
});
it('should poll on interval', async({page, server}) => { it('should poll on interval', async({page, server}) => {
let success = false; let success = false;
const startTime = Date.now(); const startTime = Date.now();