mirror of
https://github.com/puppeteer/puppeteer
synced 2024-06-14 14:02:48 +00:00
feat(Page): introduce Page.$$eval method (#1006)
This patch adds a `Page.$$eval` method that runs `document.querySelectorAll` and passes resulting array to the page function. Fixes #625.
This commit is contained in:
parent
464b6a9616
commit
7a8aa73466
33
docs/api.md
33
docs/api.md
@ -33,6 +33,7 @@
|
||||
+ [event: 'response'](#event-response)
|
||||
+ [page.$(selector)](#pageselector)
|
||||
+ [page.$$(selector)](#pageselector)
|
||||
+ [page.$$eval(selector, pageFunction[, ...args])](#pageevalselector-pagefunction-args)
|
||||
+ [page.$eval(selector, pageFunction[, ...args])](#pageevalselector-pagefunction-args)
|
||||
+ [page.addScriptTag(url)](#pageaddscripttagurl)
|
||||
+ [page.addStyleTag(url)](#pageaddstyletagurl)
|
||||
@ -110,6 +111,7 @@
|
||||
* [class: Frame](#class-frame)
|
||||
+ [frame.$(selector)](#frameselector)
|
||||
+ [frame.$$(selector)](#frameselector)
|
||||
+ [frame.$$eval(selector, pageFunction[, ...args])](#frameevalselector-pagefunction-args)
|
||||
+ [frame.$eval(selector, pageFunction[, ...args])](#frameevalselector-pagefunction-args)
|
||||
+ [frame.addScriptTag(url)](#frameaddscripttagurl)
|
||||
+ [frame.addStyleTag(url)](#frameaddstyletagurl)
|
||||
@ -379,6 +381,22 @@ The method runs `document.querySelectorAll` within the page. If no elements matc
|
||||
|
||||
Shortcut for [page.mainFrame().$$(selector)](#frameselector-1).
|
||||
|
||||
|
||||
#### page.$$eval(selector, pageFunction[, ...args])
|
||||
- `selector` <[string]> A [selector] to query frame for
|
||||
- `pageFunction` <[function]> Function to be evaluated in browser context
|
||||
- `...args` <...[Serializable]|[ElementHandle]> Arguments to pass to `pageFunction`
|
||||
- returns: <[Promise]<[Serializable]>> Promise which resolves to the return value of `pageFunction`
|
||||
|
||||
This method runs `document.querySelectorAll` within the page and passes it as the first argument to `pageFunction`.
|
||||
|
||||
If `pageFunction` returns a [Promise], then `page.$$eval` would wait for the promise to resolve and return its value.
|
||||
|
||||
Examples:
|
||||
```js
|
||||
const divsCounts = await page.$$eval('div', divs => divs.length);
|
||||
```
|
||||
|
||||
#### page.$eval(selector, pageFunction[, ...args])
|
||||
- `selector` <[string]> A [selector] to query page for
|
||||
- `pageFunction` <[function]> Function to be evaluated in browser context
|
||||
@ -1260,6 +1278,21 @@ The method queries frame for the selector. If there's no such element within the
|
||||
|
||||
The method runs `document.querySelectorAll` within the frame. If no elements match the selector, the return value resolve to `[]`.
|
||||
|
||||
#### frame.$$eval(selector, pageFunction[, ...args])
|
||||
- `selector` <[string]> A [selector] to query frame for
|
||||
- `pageFunction` <[function]> Function to be evaluated in browser context
|
||||
- `...args` <...[Serializable]|[ElementHandle]> Arguments to pass to `pageFunction`
|
||||
- returns: <[Promise]<[Serializable]>> Promise which resolves to the return value of `pageFunction`
|
||||
|
||||
This method runs `document.querySelectorAll` within the frame and passes it as the first argument to `pageFunction`.
|
||||
|
||||
If `pageFunction` returns a [Promise], then `frame.$$eval` would wait for the promise to resolve and return its value.
|
||||
|
||||
Examples:
|
||||
```js
|
||||
const divsCounts = await frame.$$eval('div', divs => divs.length);
|
||||
```
|
||||
|
||||
#### frame.$eval(selector, pageFunction[, ...args])
|
||||
- `selector` <[string]> A [selector] to query frame for
|
||||
- `pageFunction` <[function]> Function to be evaluated in browser context
|
||||
|
@ -232,12 +232,24 @@ class Frame {
|
||||
const elementHandle = await this.$(selector);
|
||||
if (!elementHandle)
|
||||
throw new Error(`Error: failed to find element matching selector "${selector}"`);
|
||||
args = [elementHandle].concat(args);
|
||||
const result = await this.evaluate(pageFunction, ...args);
|
||||
const result = await this.evaluate(pageFunction, elementHandle, ...args);
|
||||
await elementHandle.dispose();
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} selector
|
||||
* @param {Function|string} pageFunction
|
||||
* @param {!Array<*>} args
|
||||
* @return {!Promise<(!Object|undefined)>}
|
||||
*/
|
||||
async $$eval(selector, pageFunction, ...args) {
|
||||
const arrayHandle = await this._context.evaluateHandle(selector => Array.from(document.querySelectorAll(selector)), selector);
|
||||
const result = await this.evaluate(pageFunction, arrayHandle, ...args);
|
||||
await arrayHandle.dispose();
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} selector
|
||||
* @return {!Promise<!Array<!ElementHandle>>}
|
||||
|
10
lib/Page.js
10
lib/Page.js
@ -186,6 +186,16 @@ class Page extends EventEmitter {
|
||||
return this.mainFrame().$eval(selector, pageFunction, ...args);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} selector
|
||||
* @param {Function|string} pageFunction
|
||||
* @param {!Array<*>} args
|
||||
* @return {!Promise<(!Object|undefined)>}
|
||||
*/
|
||||
async $$eval(selector, pageFunction, ...args) {
|
||||
return this.mainFrame().$$eval(selector, pageFunction, ...args);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} selector
|
||||
* @return {!Promise<!Array<!Puppeteer.ElementHandle>>}
|
||||
|
@ -1392,6 +1392,14 @@ describe('Page', function() {
|
||||
}));
|
||||
});
|
||||
|
||||
describe('Page.$$eval', function() {
|
||||
it('should work', SX(async function() {
|
||||
await page.setContent('<div>hello</div><div>beautiful</div><div>world!</div>');
|
||||
const divsCount = await page.$$eval('div', divs => divs.length);
|
||||
expect(divsCount).toBe(3);
|
||||
}));
|
||||
});
|
||||
|
||||
describe('Page.$', function() {
|
||||
it('should query existing element', SX(async function() {
|
||||
await page.setContent('<section>test</section>');
|
||||
|
Loading…
Reference in New Issue
Block a user