diff --git a/docs/api.md b/docs/api.md index 84fca31f527..403956bc8cb 100644 --- a/docs/api.md +++ b/docs/api.md @@ -21,7 +21,6 @@ - [page.setViewportSize(size)](#pagesetsizesize) - [page.viewportSize()](#pagesize) - [page.evaluate(fun, args)](#pageevaluatefun-args) - - [page.evaluateAsync(fun, args)](#pageevaluateasyncfun-args) - [page.evaluateOnInitialized(fun, args)](#pageevaluateoninitializedfun-args) - [page.screenshot(type[, clipRect])](#pagescreenshottype-cliprect) - [page.saveScreenshot(filePath[, clipRect])](#pagesavescreenshotfilepath-cliprect) @@ -149,12 +148,6 @@ Pages could be closed by `page.close()` method. - `args` [<Array>](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array) Arguments to pass to `fun` - returns: [<Promise<Object>>](https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Promise) Promise which resolves to function return value -#### page.evaluateAsync(fun, args) - -- `fun` [<Function>](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function) Function to be evaluated in browser context -- `args` [<Array>](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array) Arguments to pass to `fun` -- returns: [<Promise<Object>>](https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Promise) Promise which resolves to function - #### page.evaluateOnInitialized(fun, args) - `fun` [<Function>](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function) Function to be evaluated in browser context diff --git a/lib/Page.js b/lib/Page.js index 7403428436b..20fa9e46eb2 100644 --- a/lib/Page.js +++ b/lib/Page.js @@ -89,7 +89,7 @@ class Page extends EventEmitter { * @return {!Promise} */ async addScriptTag(url) { - return this.evaluateAsync(addScriptTag, url); + return this.evaluate(addScriptTag, url); /** * @param {string} url @@ -125,7 +125,7 @@ class Page extends EventEmitter { var sourceURL = '__in_page_callback__' + name; this._sourceURLToPageCallback.set(sourceURL, new InPageCallback(name, callback)); - var text = helpers.evaluationString(inPageCallback, [name], false /* awaitPromise */, sourceURL); + var text = helpers.evaluationString(inPageCallback, [name], false /* wrapInPromise */, sourceURL); await Promise.all([ this._client.send('Debugger.enable', {}), this._client.send('Page.addScriptToEvaluateOnLoad', { scriptSource: text }), @@ -326,25 +326,32 @@ class Page extends EventEmitter { * @return {!Promise<(!Object|undefined)>} */ async evaluate(fun, ...args) { - var response = await helpers.evaluate(this._client, fun, args, false /* awaitPromise */); + var code = helpers.evaluationString(fun, args, false /* wrapInPromise */); + var response = await this._client.send('Runtime.evaluate', { + expression: code + }); + if (response.exceptionDetails) { + this._handleException(response.exceptionDetails); + return; + } + var remoteObject = response.result; + if (remoteObject.type !== 'object') + return remoteObject.value; + var isPromise = remoteObject.type === 'object' && remoteObject.subtype === 'promise'; + var response = await this._client.send('Runtime.callFunctionOn', { + objectId: remoteObject.objectId, + functionDeclaration: 'function() { return this; }', + returnByValue: true, + awaitPromise: isPromise + }); + await this._client.send('Runtime.releaseObject', { + objectId: remoteObject.objectId + }); if (response.exceptionDetails) { this._handleException(response.exceptionDetails); return; } - return response.result.value; - } - /** - * @param {function()} fun - * @param {!Array<*>} args - * @return {!Promise<(!Object|undefined)>} - */ - async evaluateAsync(fun, ...args) { - var response = await helpers.evaluate(this._client, fun, args, true /* awaitPromise */); - if (response.exceptionDetails) { - this._handleException(response.exceptionDetails); - return; - } return response.result.value; } @@ -354,7 +361,7 @@ class Page extends EventEmitter { * @return {!Promise} */ async evaluateOnInitialized(fun, ...args) { - var code = helpers.evaluationString(fun, args, false); + var code = helpers.evaluationString(fun, args, false /* wrapInPromise */); await this._client.send('Page.addScriptToEvaluateOnLoad', { scriptSource: code }); diff --git a/lib/helpers.js b/lib/helpers.js index 0a9ce14ecce..b3419ab668c 100644 --- a/lib/helpers.js +++ b/lib/helpers.js @@ -74,14 +74,14 @@ var helpers = module.exports = { /** * @param {function()} fun * @param {!Array<*>} args - * @param {boolean} awaitPromise + * @param {boolean} wrapInPromise * @param {string=} sourceURL * @return {string} */ - evaluationString: function(fun, args, awaitPromise, sourceURL) { + evaluationString: function(fun, args, wrapInPromise, sourceURL) { var argsString = args.map(x => JSON.stringify(x)).join(','); var code = `(${fun.toString()})(${argsString})`; - if (awaitPromise) + if (wrapInPromise) code = `Promise.resolve(${code})`; if (sourceURL) code += `\n//# sourceURL=${sourceURL}`; diff --git a/test/test.js b/test/test.js index 85cf84bc3e1..575c5a7a520 100644 --- a/test/test.js +++ b/test/test.js @@ -45,15 +45,26 @@ describe('Puppeteer', function() { page.close(); }); - it('Page.evaluate', SX(async function() { - var result = await page.evaluate(() => 7 * 3); - expect(result).toBe(21); - })); - - it('Page.evaluateAsync', SX(async function() { - var result = await page.evaluateAsync(() => Promise.resolve(8 * 7)); - expect(result).toBe(56); - })); + describe('Page.evaluate', function() { + it('should work', SX(async function() { + var result = await page.evaluate(() => 7 * 3); + expect(result).toBe(21); + })); + it('should await promise', SX(async function() { + var result = await page.evaluate(() => Promise.resolve(8 * 7)); + expect(result).toBe(56); + })); + it('should work from-inside inPageCallback', SX(async function() { + // Setup inpage callback, which calls Page.evaluate + await page.setInPageCallback('callController', async function(a, b) { + return await page.evaluate((a, b) => a * b, a, b); + }); + var result = await page.evaluate(function() { + return callController(9, 3); + }); + expect(result).toBe(27); + })); + }); it('Page Events: ConsoleMessage', SX(async function() { var msgs = [];