Merge Page.evaluate and Page.evaluateAsync together

This patch makes Page.evaluate await promise if one is
returned by the evaluated code.

This makes the Page.evaluateAsync unneeded, so the patch
removes it.

Fixes #11.
This commit is contained in:
Andrey Lushnikov 2017-06-15 14:56:40 -07:00
parent 50976c7f29
commit 14a75a83ea
4 changed files with 47 additions and 36 deletions

View File

@ -21,7 +21,6 @@
- [page.setViewportSize(size)](#pagesetsizesize) - [page.setViewportSize(size)](#pagesetsizesize)
- [page.viewportSize()](#pagesize) - [page.viewportSize()](#pagesize)
- [page.evaluate(fun, args)](#pageevaluatefun-args) - [page.evaluate(fun, args)](#pageevaluatefun-args)
- [page.evaluateAsync(fun, args)](#pageevaluateasyncfun-args)
- [page.evaluateOnInitialized(fun, args)](#pageevaluateoninitializedfun-args) - [page.evaluateOnInitialized(fun, args)](#pageevaluateoninitializedfun-args)
- [page.screenshot(type[, clipRect])](#pagescreenshottype-cliprect) - [page.screenshot(type[, clipRect])](#pagescreenshottype-cliprect)
- [page.saveScreenshot(filePath[, clipRect])](#pagesavescreenshotfilepath-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` - `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 - 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) #### 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 - `fun` [<Function>](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function) Function to be evaluated in browser context

View File

@ -89,7 +89,7 @@ class Page extends EventEmitter {
* @return {!Promise} * @return {!Promise}
*/ */
async addScriptTag(url) { async addScriptTag(url) {
return this.evaluateAsync(addScriptTag, url); return this.evaluate(addScriptTag, url);
/** /**
* @param {string} url * @param {string} url
@ -125,7 +125,7 @@ class Page extends EventEmitter {
var sourceURL = '__in_page_callback__' + name; var sourceURL = '__in_page_callback__' + name;
this._sourceURLToPageCallback.set(sourceURL, new InPageCallback(name, callback)); 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([ await Promise.all([
this._client.send('Debugger.enable', {}), this._client.send('Debugger.enable', {}),
this._client.send('Page.addScriptToEvaluateOnLoad', { scriptSource: text }), this._client.send('Page.addScriptToEvaluateOnLoad', { scriptSource: text }),
@ -326,25 +326,32 @@ class Page extends EventEmitter {
* @return {!Promise<(!Object|undefined)>} * @return {!Promise<(!Object|undefined)>}
*/ */
async evaluate(fun, ...args) { 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) { if (response.exceptionDetails) {
this._handleException(response.exceptionDetails); this._handleException(response.exceptionDetails);
return; return;
} }
return response.result.value; 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;
} }
/**
* @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; return response.result.value;
} }
@ -354,7 +361,7 @@ class Page extends EventEmitter {
* @return {!Promise} * @return {!Promise}
*/ */
async evaluateOnInitialized(fun, ...args) { 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', { await this._client.send('Page.addScriptToEvaluateOnLoad', {
scriptSource: code scriptSource: code
}); });

View File

@ -74,14 +74,14 @@ var helpers = module.exports = {
/** /**
* @param {function()} fun * @param {function()} fun
* @param {!Array<*>} args * @param {!Array<*>} args
* @param {boolean} awaitPromise * @param {boolean} wrapInPromise
* @param {string=} sourceURL * @param {string=} sourceURL
* @return {string} * @return {string}
*/ */
evaluationString: function(fun, args, awaitPromise, sourceURL) { evaluationString: function(fun, args, wrapInPromise, sourceURL) {
var argsString = args.map(x => JSON.stringify(x)).join(','); var argsString = args.map(x => JSON.stringify(x)).join(',');
var code = `(${fun.toString()})(${argsString})`; var code = `(${fun.toString()})(${argsString})`;
if (awaitPromise) if (wrapInPromise)
code = `Promise.resolve(${code})`; code = `Promise.resolve(${code})`;
if (sourceURL) if (sourceURL)
code += `\n//# sourceURL=${sourceURL}`; code += `\n//# sourceURL=${sourceURL}`;

View File

@ -45,15 +45,26 @@ describe('Puppeteer', function() {
page.close(); page.close();
}); });
it('Page.evaluate', SX(async function() { describe('Page.evaluate', function() {
it('should work', SX(async function() {
var result = await page.evaluate(() => 7 * 3); var result = await page.evaluate(() => 7 * 3);
expect(result).toBe(21); expect(result).toBe(21);
})); }));
it('should await promise', SX(async function() {
it('Page.evaluateAsync', SX(async function() { var result = await page.evaluate(() => Promise.resolve(8 * 7));
var result = await page.evaluateAsync(() => Promise.resolve(8 * 7));
expect(result).toBe(56); 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() { it('Page Events: ConsoleMessage', SX(async function() {
var msgs = []; var msgs = [];