From 189deb84c0ecf43f405961814aad840c1107ee85 Mon Sep 17 00:00:00 2001 From: Yaniv Efraim Date: Thu, 25 Jan 2018 07:16:01 +0200 Subject: [PATCH] feat(Frame): add Frame.evaluateHandle (#1885) This patch adds Frame.evaluateHandle method. The method is a shortcut for frame.executionContext().evaluateHandle. Fixes #1051 --- docs/api.md | 28 ++++++++++++++++++++++++++++ lib/FrameManager.js | 10 ++++++++++ test/test.js | 9 +++++++++ 3 files changed, 47 insertions(+) diff --git a/docs/api.md b/docs/api.md index 89d24bf0..295d0c2c 100644 --- a/docs/api.md +++ b/docs/api.md @@ -137,6 +137,7 @@ * [frame.childFrames()](#framechildframes) * [frame.content()](#framecontent) * [frame.evaluate(pageFunction, ...args)](#frameevaluatepagefunction-args) + * [frame.evaluateHandle(pageFunction, ...args)](#frameevaluatehandlepagefunction-args) * [frame.executionContext()](#frameexecutioncontext) * [frame.isDetached()](#frameisdetached) * [frame.name()](#framename) @@ -1658,6 +1659,33 @@ const html = await frame.evaluate(body => body.innerHTML, bodyHandle); await bodyHandle.dispose(); ``` +#### frame.evaluateHandle(pageFunction, ...args) +- `pageFunction` <[function]|[string]> Function to be evaluated in the page context +- `...args` <...[Serializable]|[JSHandle]> Arguments to pass to `pageFunction` +- returns: <[Promise]<[JSHandle]>> Resolves to the return value of `pageFunction` + +If the function, passed to the `frame.evaluateHandle`, returns a [Promise], then `frame.evaluateHandle` would wait for the promise to resolve and return its value. + +```js +const aWindowHandle = await frame.evaluateHandle(() => Promise.resolve(window)); +aWindowHandle; // Handle for the window object. +``` + +A string can also be passed in instead of a function. + +```js +const aHandle = await frame.evaluateHandle('document'); // Handle for the 'document'. +``` + +[JSHandle] instances can be passed as arguments to the `frame.evaluateHandle`: +```js +const aHandle = await frame.evaluateHandle(() => document.body); +const resultHandle = await frame.evaluateHandle(body => body.innerHTML, aHandle); +console.log(await resultHandle.jsonValue()); +await resultHandle.dispose(); +``` + + #### frame.executionContext() - returns: <[Promise]<[ExecutionContext]>> Execution context associated with this frame. diff --git a/lib/FrameManager.js b/lib/FrameManager.js index b2bb6b2c..b18968d3 100644 --- a/lib/FrameManager.js +++ b/lib/FrameManager.js @@ -280,6 +280,16 @@ class Frame { return this._contextPromise; } + /** + * @param {function()|string} pageFunction + * @param {!Array<*>} args + * @return {!Promise} + */ + async evaluateHandle(pageFunction, ...args) { + const context = await this._contextPromise; + return context.evaluateHandle(pageFunction, ...args); + } + /** * @param {Function|string} pageFunction * @param {!Array<*>} args diff --git a/test/test.js b/test/test.js index 0e3301e2..dfb53fbe 100644 --- a/test/test.js +++ b/test/test.js @@ -624,6 +624,15 @@ describe('Page', function() { }); }); + describe('Frame.evaluateHandle', function() { + it('should work', async({page, server}) => { + await page.goto(server.EMPTY_PAGE); + const mainFrame = page.mainFrame(); + const windowHandle = await mainFrame.evaluateHandle(() => window); + expect(windowHandle).toBeTruthy(); + }); + }); + describe('Frame.evaluate', function() { it('should have different execution contexts', async({page, server}) => { await page.goto(server.EMPTY_PAGE);