diff --git a/src/server/webkit/wkExecutionContext.ts b/src/server/webkit/wkExecutionContext.ts index 645378f397..f0c99869ba 100644 --- a/src/server/webkit/wkExecutionContext.ts +++ b/src/server/webkit/wkExecutionContext.ts @@ -80,54 +80,26 @@ export class WKExecutionContext implements js.ExecutionContextDelegate { async evaluateWithArguments(expression: string, returnByValue: boolean, utilityScript: js.JSHandle, values: any[], objectIds: string[]): Promise { try { - let response = await this._session.send('Runtime.callFunctionOn', { - functionDeclaration: expression, - objectId: utilityScript._objectId!, - arguments: [ - { objectId: utilityScript._objectId }, - ...values.map(value => ({ value })), - ...objectIds.map(objectId => ({ objectId })), - ], - returnByValue: false, // We need to return real Promise if that is a promise. - emulateUserGesture: true - }); - if (response.result.objectId && response.result.className === 'Promise') { - response = await Promise.race([ - this._executionContextDestroyedPromise.then(() => contextDestroyedResult), - this._session.send('Runtime.awaitPromise', { - promiseObjectId: response.result.objectId, - returnByValue: false - }) - ]); - } + const response = await Promise.race([ + this._executionContextDestroyedPromise.then(() => contextDestroyedResult), + this._session.send('Runtime.callFunctionOn', { + functionDeclaration: expression, + objectId: utilityScript._objectId!, + arguments: [ + { objectId: utilityScript._objectId }, + ...values.map(value => ({ value })), + ...objectIds.map(objectId => ({ objectId })), + ], + returnByValue, + emulateUserGesture: true, + awaitPromise: true + }) + ]); if (response.wasThrown) throw new Error('Evaluation failed: ' + response.result.description); - if (!returnByValue) - return utilityScript._context.createHandle(response.result); - if (response.result.objectId) { - // 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, objectId: Protocol.Runtime.RemoteObjectId): Promise { - 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); + if (returnByValue) + return parseEvaluationResultValue(response.result.value); + return utilityScript._context.createHandle(response.result); } catch (error) { throw rewriteError(error); } diff --git a/tests/page/page-evaluate.spec.ts b/tests/page/page-evaluate.spec.ts index cd73ce0587..c5e41cfae7 100644 --- a/tests/page/page-evaluate.spec.ts +++ b/tests/page/page-evaluate.spec.ts @@ -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.fixme(browserName === 'webkit'); - // It is imporant to be on about:blank for sync reload. const result = await page.evaluate(() => { window.location.reload();