fix: do not wait for navigations while evaluating injected source (#1347)

This commit is contained in:
Dmitry Gozman 2020-03-11 22:52:03 -07:00 committed by GitHub
parent 11c3c117de
commit 7c59f9ca9a
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 10 additions and 9 deletions

View file

@ -45,7 +45,7 @@ export class FrameExecutionContext extends js.ExecutionContext {
this.frame = frame; this.frame = frame;
} }
async _evaluate(returnByValue: boolean, pageFunction: string | Function, ...args: any[]): Promise<any> { async _evaluate(returnByValue: boolean, waitForNavigations: boolean, pageFunction: string | Function, ...args: any[]): Promise<any> {
const needsAdoption = (value: any): boolean => { const needsAdoption = (value: any): boolean => {
return typeof value === 'object' && value instanceof ElementHandle && value._context !== this; return typeof value === 'object' && value instanceof ElementHandle && value._context !== this;
}; };
@ -54,7 +54,7 @@ export class FrameExecutionContext extends js.ExecutionContext {
// Only go through asynchronous calls if required. // Only go through asynchronous calls if required.
return await this.frame._page._frameManager.waitForNavigationsCreatedBy(async () => { return await this.frame._page._frameManager.waitForNavigationsCreatedBy(async () => {
return this._delegate.evaluate(this, returnByValue, pageFunction, ...args); return this._delegate.evaluate(this, returnByValue, pageFunction, ...args);
}); }, waitForNavigations ? undefined : { waitUntil: 'nowait' });
} }
const toDispose: Promise<ElementHandle>[] = []; const toDispose: Promise<ElementHandle>[] = [];
@ -69,7 +69,7 @@ export class FrameExecutionContext extends js.ExecutionContext {
try { try {
result = await this.frame._page._frameManager.waitForNavigationsCreatedBy(async () => { result = await this.frame._page._frameManager.waitForNavigationsCreatedBy(async () => {
return this._delegate.evaluate(this, returnByValue, pageFunction, ...adopted); return this._delegate.evaluate(this, returnByValue, pageFunction, ...adopted);
}); }, waitForNavigations ? undefined : { waitUntil: 'nowait' });
} finally { } finally {
toDispose.map(handlePromise => handlePromise.then(handle => handle.dispose())); toDispose.map(handlePromise => handlePromise.then(handle => handle.dispose()));
} }
@ -97,7 +97,7 @@ export class FrameExecutionContext extends js.ExecutionContext {
${custom.join(',\n')} ${custom.join(',\n')}
]) ])
`; `;
this._injectedPromise = this.evaluateHandle(source); this._injectedPromise = this._evaluate(false /* returnByValue */, false /* waitForNavigations */, source);
this._injectedGeneration = selectors._generation; this._injectedGeneration = selectors._generation;
} }
return this._injectedPromise; return this._injectedPromise;

View file

@ -32,16 +32,16 @@ export class ExecutionContext {
this._delegate = delegate; this._delegate = delegate;
} }
_evaluate(returnByValue: boolean, pageFunction: string | Function, ...args: any[]): Promise<any> { _evaluate(returnByValue: boolean, waitForNavigations: boolean, pageFunction: string | Function, ...args: any[]): Promise<any> {
return this._delegate.evaluate(this, returnByValue, pageFunction, ...args); return this._delegate.evaluate(this, returnByValue, pageFunction, ...args);
} }
evaluate: types.Evaluate = async (pageFunction, ...args) => { evaluate: types.Evaluate = async (pageFunction, ...args) => {
return this._evaluate(true /* returnByValue */, pageFunction, ...args); return this._evaluate(true /* returnByValue */, true /* waitForNavigations */, pageFunction, ...args);
} }
evaluateHandle: types.EvaluateHandle = async (pageFunction, ...args) => { evaluateHandle: types.EvaluateHandle = async (pageFunction, ...args) => {
return this._evaluate(false /* returnByValue */, pageFunction, ...args); return this._evaluate(false /* returnByValue */, true /* waitForNavigations */, pageFunction, ...args);
} }
_createHandle(remoteObject: any): JSHandle { _createHandle(remoteObject: any): JSHandle {

View file

@ -230,8 +230,9 @@ module.exports.describe = function({testRunner, expect, FFOX, CHROMIUM, WEBKIT,
await page.evaluate(e => e.textContent, element).catch(e => error = e); await page.evaluate(e => e.textContent, element).catch(e => error = e);
expect(error.message).toContain('JSHandle is disposed'); expect(error.message).toContain('JSHandle is disposed');
}); });
// flaky: https://github.com/microsoft/playwright/pull/1277/checks?check_run_id=496501774 it.fail(FFOX)('should simulate a user gesture', async({page, server}) => {
it.fail(FFOX && LINUX)('should simulate a user gesture', async({page, server}) => { // flaky linux: https://github.com/microsoft/playwright/pull/1277/checks?check_run_id=496501774
// flaky win: https://github.com/microsoft/playwright/pull/1323/checks?check_run_id=501701278
const result = await page.evaluate(() => { const result = await page.evaluate(() => {
document.body.appendChild(document.createTextNode('test')); document.body.appendChild(document.createTextNode('test'));
document.execCommand('selectAll'); document.execCommand('selectAll');