Implement page.$$ method (#463)
This patch implements page.$$ which runs document.querySelectorAll in page and returns results as an array of ElementHandle instances. Fixes #384.
This commit is contained in:
parent
7e1f2f0609
commit
151d512ae2
19
docs/api.md
19
docs/api.md
@ -27,6 +27,7 @@
|
||||
+ [event: 'requestfinished'](#event-requestfinished)
|
||||
+ [event: 'response'](#event-response)
|
||||
+ [page.$(selector)](#pageselector)
|
||||
+ [page.$$(selector)](#pageselector)
|
||||
+ [page.addScriptTag(url)](#pageaddscripttagurl)
|
||||
+ [page.click(selector[, options])](#pageclickselector-options)
|
||||
+ [page.close()](#pageclose)
|
||||
@ -85,6 +86,7 @@
|
||||
+ [dialog.type](#dialogtype)
|
||||
* [class: Frame](#class-frame)
|
||||
+ [frame.$(selector)](#frameselector)
|
||||
+ [frame.$$(selector)](#frameselector)
|
||||
+ [frame.addScriptTag(url)](#frameaddscripttagurl)
|
||||
+ [frame.childFrames()](#framechildframes)
|
||||
+ [frame.evaluate(pageFunction, ...args)](#frameevaluatepagefunction-args)
|
||||
@ -297,6 +299,14 @@ The method runs `document.querySelector` within the page. If no element matches
|
||||
|
||||
Shortcut for [page.mainFrame().$(selector)](#frameselector).
|
||||
|
||||
#### page.$$(selector)
|
||||
- `selector` <[string]> Selector to query page for
|
||||
- returns: <[Promise]<[Array]<[ElementHandle]>>>
|
||||
|
||||
The method runs `document.querySelectorAll` within the page. If no elements match the selector, the return value resolve to `[]`.
|
||||
|
||||
Shortcut for [page.mainFrame().$$(selector)](#frameselector-1).
|
||||
|
||||
#### page.addScriptTag(url)
|
||||
- `url` <[string]> Url of the `<script>` tag
|
||||
- returns: <[Promise]> which resolves when the script's onload fires.
|
||||
@ -976,10 +986,15 @@ puppeteer.launch().then(async browser => {
|
||||
|
||||
#### frame.$(selector)
|
||||
- `selector` <[string]> Selector to query page for
|
||||
- returns: <[Promise]<[ElementHandle]>> Promise which resolves to ElementHandle pointing to the page element.
|
||||
- returns: <[Promise]<[ElementHandle]>> Promise which resolves to ElementHandle pointing to the frame element.
|
||||
|
||||
The method queries page for the selector. If there's no such element within the page, the method will resolve to `null`.
|
||||
The method queries frame for the selector. If there's no such element within the frame, the method will resolve to `null`.
|
||||
|
||||
#### frame.$$(selector)
|
||||
- `selector` <[string]> Selector to query page for
|
||||
- returns: <[Promise]<[Array]<[ElementHandle]>>> Promise which resolves to ElementHandles pointing to the frame elements.
|
||||
|
||||
The method runs `document.querySelectorAll` within the frame. If no elements match the selector, the return value resolve to `[]`.
|
||||
|
||||
#### frame.addScriptTag(url)
|
||||
- `url` <[string]> Url of a script to be added
|
||||
|
@ -191,10 +191,33 @@ class Frame {
|
||||
const remoteObject = await this._rawEvaluate(selector => document.querySelector(selector), selector);
|
||||
if (remoteObject.subtype === 'node')
|
||||
return new ElementHandle(this._client, remoteObject, this._mouse);
|
||||
helper.releaseObject(this._client, remoteObject);
|
||||
await helper.releaseObject(this._client, remoteObject);
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} selector
|
||||
* @return {!Promise<!Array<!ElementHandle>>}
|
||||
*/
|
||||
async $$(selector) {
|
||||
const remoteObject = await this._rawEvaluate(selector => Array.from(document.querySelectorAll(selector)), selector);
|
||||
const response = await this._client.send('Runtime.getProperties', {
|
||||
objectId: remoteObject.objectId,
|
||||
ownProperties: true
|
||||
});
|
||||
const properties = response.result;
|
||||
const result = [];
|
||||
const releasePromises = [helper.releaseObject(this._client, remoteObject)];
|
||||
for (const property of properties) {
|
||||
if (property.enumerable && property.value.subtype === 'node')
|
||||
result.push(new ElementHandle(this._client, property.value, this._mouse));
|
||||
else
|
||||
releasePromises.push(helper.releaseObject(this._client, property.value));
|
||||
}
|
||||
await Promise.all(releasePromises);
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {function()|string} pageFunction
|
||||
* @param {!Array<*>} args
|
||||
|
@ -146,6 +146,14 @@ class Page extends EventEmitter {
|
||||
return this.mainFrame().$(selector);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} selector
|
||||
* @return {!Promise<!Array<!ElementHandle>>}
|
||||
*/
|
||||
async $$(selector) {
|
||||
return this.mainFrame().$$(selector);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} url
|
||||
* @return {!Promise}
|
||||
|
14
test/test.js
14
test/test.js
@ -1074,6 +1074,20 @@ describe('Page', function() {
|
||||
expect(element).toBe(null);
|
||||
}));
|
||||
});
|
||||
describe('Page.$$', function() {
|
||||
it('should query existing elements', SX(async function() {
|
||||
await page.setContent('<div>A</div><br/><div>B</div>');
|
||||
const elements = await page.$$('div');
|
||||
expect(elements.length).toBe(2);
|
||||
const promises = elements.map(element => element.evaluate(e => e.textContent));
|
||||
expect(await Promise.all(promises)).toEqual(['A', 'B']);
|
||||
}));
|
||||
it('should return ampty array if nothing is found', SX(async function() {
|
||||
await page.goto(EMPTY_PAGE);
|
||||
const elements = await page.$$('div');
|
||||
expect(elements.length).toBe(0);
|
||||
}));
|
||||
});
|
||||
|
||||
describe('ElementHandle.evaluate', function() {
|
||||
it('should work', SX(async function() {
|
||||
|
Loading…
Reference in New Issue
Block a user