fix(webkit): use new awaitPromise parameter instead of separate command (#6852)

This commit is contained in:
Yury Semikhatsky 2021-06-02 17:04:47 +00:00 committed by GitHub
parent d28f45b6ee
commit 2fde9bc13f
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 18 additions and 48 deletions

View file

@ -80,54 +80,26 @@ export class WKExecutionContext implements js.ExecutionContextDelegate {
async evaluateWithArguments(expression: string, returnByValue: boolean, utilityScript: js.JSHandle<any>, values: any[], objectIds: string[]): Promise<any> { async evaluateWithArguments(expression: string, returnByValue: boolean, utilityScript: js.JSHandle<any>, values: any[], objectIds: string[]): Promise<any> {
try { try {
let response = await this._session.send('Runtime.callFunctionOn', { const response = await Promise.race([
functionDeclaration: expression, this._executionContextDestroyedPromise.then(() => contextDestroyedResult),
objectId: utilityScript._objectId!, this._session.send('Runtime.callFunctionOn', {
arguments: [ functionDeclaration: expression,
{ objectId: utilityScript._objectId }, objectId: utilityScript._objectId!,
...values.map(value => ({ value })), arguments: [
...objectIds.map(objectId => ({ objectId })), { objectId: utilityScript._objectId },
], ...values.map(value => ({ value })),
returnByValue: false, // We need to return real Promise if that is a promise. ...objectIds.map(objectId => ({ objectId })),
emulateUserGesture: true ],
}); returnByValue,
if (response.result.objectId && response.result.className === 'Promise') { emulateUserGesture: true,
response = await Promise.race([ awaitPromise: true
this._executionContextDestroyedPromise.then(() => contextDestroyedResult), })
this._session.send('Runtime.awaitPromise', { ]);
promiseObjectId: response.result.objectId,
returnByValue: false
})
]);
}
if (response.wasThrown) if (response.wasThrown)
throw new Error('Evaluation failed: ' + response.result.description); throw new Error('Evaluation failed: ' + response.result.description);
if (!returnByValue) if (returnByValue)
return utilityScript._context.createHandle(response.result); return parseEvaluationResultValue(response.result.value);
if (response.result.objectId) { return utilityScript._context.createHandle(response.result);
// Avoid protocol round trip for evaluates that do not return anything.
// Otherwise, we can fail with 'execution context destroyed' without any reason.
if (response.result.type === 'undefined')
return undefined;
return await this._returnObjectByValue(utilityScript, response.result.objectId);
}
return parseEvaluationResultValue(response.result.value);
} catch (error) {
throw rewriteError(error);
}
}
private async _returnObjectByValue(utilityScript: js.JSHandle<any>, objectId: Protocol.Runtime.RemoteObjectId): Promise<any> {
try {
const serializeResponse = await this._session.send('Runtime.callFunctionOn', {
functionDeclaration: 'object => object',
objectId: utilityScript._objectId!,
arguments: [ { objectId } ],
returnByValue: true
});
if (serializeResponse.wasThrown)
throw new Error('Evaluation failed: ' + serializeResponse.result.description);
return parseEvaluationResultValue(serializeResponse.result.value);
} catch (error) { } catch (error) {
throw rewriteError(error); throw rewriteError(error);
} }

View file

@ -416,8 +416,6 @@ it('should not throw an error when evaluation does a navigation', async ({ page,
}); });
it('should not throw an error when evaluation does a synchronous navigation and returns an object', async ({ page, server, browserName }) => { it('should not throw an error when evaluation does a synchronous navigation and returns an object', async ({ page, server, browserName }) => {
it.fixme(browserName === 'webkit');
// It is imporant to be on about:blank for sync reload. // It is imporant to be on about:blank for sync reload.
const result = await page.evaluate(() => { const result = await page.evaluate(() => {
window.location.reload(); window.location.reload();