mirror of
https://github.com/puppeteer/puppeteer
synced 2024-06-14 14:02:48 +00:00
feat(ElementHandle): introduce elementHandle.$eval (#2407)
This patch introduces `elementHandle.$eval` method. References #2401.
This commit is contained in:
parent
1d225cfa17
commit
88b996877f
18
docs/api.md
18
docs/api.md
@ -189,6 +189,7 @@
|
||||
- [class: ElementHandle](#class-elementhandle)
|
||||
* [elementHandle.$(selector)](#elementhandleselector)
|
||||
* [elementHandle.$$(selector)](#elementhandleselector)
|
||||
* [elementHandle.$eval(selector, pageFunction, ...args)](#elementhandleevalselector-pagefunction-args)
|
||||
* [elementHandle.$x(expression)](#elementhandlexexpression)
|
||||
* [elementHandle.asElement()](#elementhandleaselement)
|
||||
* [elementHandle.boundingBox()](#elementhandleboundingbox)
|
||||
@ -2230,6 +2231,23 @@ The method runs `element.querySelector` within the page. If no element matches t
|
||||
|
||||
The method runs `element.querySelectorAll` within the page. If no elements match the selector, the return value resolve to `[]`.
|
||||
|
||||
#### elementHandle.$eval(selector, pageFunction, ...args)
|
||||
- `selector` <[string]> A [selector] to query page for
|
||||
- `pageFunction` <[function]> Function to be evaluated in browser context
|
||||
- `...args` <...[Serializable]|[JSHandle]> Arguments to pass to `pageFunction`
|
||||
- returns: <[Promise]<[Serializable]>> Promise which resolves to the return value of `pageFunction`
|
||||
|
||||
This method runs `document.querySelector` within the element and passes it as the first argument to `pageFunction`. If there's no element matching `selector`, the method throws an error.
|
||||
|
||||
If `pageFunction` returns a [Promise], then `frame.$eval` would wait for the promise to resolve and return its value.
|
||||
|
||||
Examples:
|
||||
```js
|
||||
const tweetHandle = await page.$('.tweet');
|
||||
expect(await tweetHandle.$eval('.like', node => node.innerText)).toBe('100');
|
||||
expect(await tweetHandle.$eval('.retweets', node => node.innerText)).toBe('10');
|
||||
```
|
||||
|
||||
#### elementHandle.$x(expression)
|
||||
- `expression` <[string]> Expression to [evaluate](https://developer.mozilla.org/en-US/docs/Web/API/Document/evaluate).
|
||||
- returns: <[Promise]<?[ElementHandle]>> Promise which resolves to ElementHandle pointing to the frame element.
|
||||
|
@ -280,6 +280,21 @@ class ElementHandle extends JSHandle {
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} selector
|
||||
* @param {Function|String} pageFunction
|
||||
* @param {!Array<*>} args
|
||||
* @return {!Promise<(!Object|undefined)>}
|
||||
*/
|
||||
async $eval(selector, pageFunction, ...args) {
|
||||
const elementHandle = await this.$(selector);
|
||||
if (!elementHandle)
|
||||
throw new Error(`Error: failed to find element matching selector "${selector}"`);
|
||||
const result = await this.executionContext().evaluate(pageFunction, elementHandle, ...args);
|
||||
await elementHandle.dispose();
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} expression
|
||||
* @return {!Promise<!Array<!ElementHandle>>}
|
||||
|
@ -366,12 +366,9 @@ class Frame {
|
||||
* @return {!Promise<(!Object|undefined)>}
|
||||
*/
|
||||
async $eval(selector, pageFunction, ...args) {
|
||||
const elementHandle = await this.$(selector);
|
||||
if (!elementHandle)
|
||||
throw new Error(`Error: failed to find element matching selector "${selector}"`);
|
||||
const result = await this.evaluate(pageFunction, elementHandle, ...args);
|
||||
await elementHandle.dispose();
|
||||
return result;
|
||||
const document = await this._document();
|
||||
const value = await document.$eval(selector, pageFunction, ...args);
|
||||
return value;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -294,6 +294,22 @@ module.exports.addTests = function({testRunner, expect}) {
|
||||
expect(second).toBe(null);
|
||||
});
|
||||
});
|
||||
describe('ElementHandle.$eval', function() {
|
||||
it('should work', async({page, server}) => {
|
||||
await page.setContent('<html><body><div class="tweet"><div class="like">100</div><div class="retweets">10</div></div></body></html>');
|
||||
const tweet = await page.$('.tweet');
|
||||
const content = await tweet.$eval('.like', node => node.innerText);
|
||||
expect(content).toBe('100');
|
||||
});
|
||||
|
||||
it('should retrieve content from subtree', async({page, server}) => {
|
||||
const htmlContent = '<div class="a">not-a-child-div</div><div id="myId"><div class="a">a-child-div</div></div>';
|
||||
await page.setContent(htmlContent);
|
||||
const elementHandle = await page.$('#myId');
|
||||
const content = await elementHandle.$eval('.a', node => node.innerText);
|
||||
expect(content).toBe('a-child-div');
|
||||
});
|
||||
});
|
||||
|
||||
describe('ElementHandle.$$', function() {
|
||||
it('should query existing elements', async({page, server}) => {
|
||||
|
Loading…
Reference in New Issue
Block a user