Kill page.$ and page.$$ functions (#197)
page.$ and page.$$ conflicts with our ideas about element handles. This patch removes functions in favor of future implementation. References #111
This commit is contained in:
parent
211c372a3a
commit
31224392bb
50
docs/api.md
50
docs/api.md
@ -25,8 +25,6 @@
|
|||||||
+ [event: 'requestfailed'](#event-requestfailed)
|
+ [event: 'requestfailed'](#event-requestfailed)
|
||||||
+ [event: 'requestfinished'](#event-requestfinished)
|
+ [event: 'requestfinished'](#event-requestfinished)
|
||||||
+ [event: 'response'](#event-response)
|
+ [event: 'response'](#event-response)
|
||||||
+ [page.$(selector, pageFunction, ...args)](#pageselector-pagefunction-args)
|
|
||||||
+ [page.$$(selector, pageFunction, ...args)](#pageselector-pagefunction-args)
|
|
||||||
+ [page.addScriptTag(url)](#pageaddscripttagurl)
|
+ [page.addScriptTag(url)](#pageaddscripttagurl)
|
||||||
+ [page.click(selector[, options])](#pageclickselector-options)
|
+ [page.click(selector[, options])](#pageclickselector-options)
|
||||||
+ [page.close()](#pageclose)
|
+ [page.close()](#pageclose)
|
||||||
@ -81,8 +79,6 @@
|
|||||||
+ [dialog.message()](#dialogmessage)
|
+ [dialog.message()](#dialogmessage)
|
||||||
+ [dialog.type](#dialogtype)
|
+ [dialog.type](#dialogtype)
|
||||||
* [class: Frame](#class-frame)
|
* [class: Frame](#class-frame)
|
||||||
+ [frame.$(selector, pageFunction, ...args)](#frameselector-pagefunction-args)
|
|
||||||
+ [frame.$$(selector, pageFunction, ...args)](#frameselector-pagefunction-args)
|
|
||||||
+ [frame.addScriptTag(url)](#frameaddscripttagurl)
|
+ [frame.addScriptTag(url)](#frameaddscripttagurl)
|
||||||
+ [frame.childFrames()](#framechildframes)
|
+ [frame.childFrames()](#framechildframes)
|
||||||
+ [frame.click(selector[, options])](#frameclickselector-options)
|
+ [frame.click(selector[, options])](#frameclickselector-options)
|
||||||
@ -316,30 +312,6 @@ Emitted when a request is successfully finished.
|
|||||||
|
|
||||||
Emitted when a [response] is received.
|
Emitted when a [response] is received.
|
||||||
|
|
||||||
#### page.$(selector, pageFunction, ...args)
|
|
||||||
- `selector` <[string]> A [selector] to be matched in the page
|
|
||||||
- `pageFunction` <[function]\([Element]\)> Function to be evaluated with first element matching `selector`
|
|
||||||
- `...args` <...[string]> Arguments to pass to `pageFunction`
|
|
||||||
- returns: <[Promise]<[Object]>> Promise which resolves to function return value.
|
|
||||||
Example:
|
|
||||||
```js
|
|
||||||
const outerhtml = await page.$('#box', e => e.outerHTML);
|
|
||||||
```
|
|
||||||
Shortcut for [page.mainFrame().$(selector, pageFunction, ...args)](#frameselector-pagefunction-args).
|
|
||||||
|
|
||||||
#### page.$$(selector, pageFunction, ...args)
|
|
||||||
- `selector` <[string]> A [selector] to be matched in the page
|
|
||||||
- `pageFunction` <[function]\([Element]\)> Function to be evaluted for every element matching `selector`.
|
|
||||||
- `...args` <...[string]> Arguments to pass to `pageFunction`
|
|
||||||
- returns: <[Promise]<[Array]<[Object]>>> Promise which resolves to array of function return values.
|
|
||||||
Example:
|
|
||||||
```js
|
|
||||||
const headings = await page.$$('h1,h2,h3,h4', el => el.textContent);
|
|
||||||
for (const heading of headings) console.log(heading);
|
|
||||||
```
|
|
||||||
|
|
||||||
Shortcut for [page.mainFrame().$$(selector, pageFunction, ...args)](#frameselector-pagefunction-args-1).
|
|
||||||
|
|
||||||
#### page.addScriptTag(url)
|
#### page.addScriptTag(url)
|
||||||
- `url` <[string]> Url of a script to be added
|
- `url` <[string]> Url of a script to be added
|
||||||
- returns: <[Promise]> Promise which resolves as the script gets added and loads.
|
- returns: <[Promise]> Promise which resolves as the script gets added and loads.
|
||||||
@ -916,28 +888,6 @@ browser.newPage().then(async page => {
|
|||||||
});
|
});
|
||||||
```
|
```
|
||||||
|
|
||||||
#### frame.$(selector, pageFunction, ...args)
|
|
||||||
- `selector` <[string]> A [selector] to be matched in the page
|
|
||||||
- `pageFunction` <[function]\([Element]\)> Function to be evaluated with first element matching `selector`
|
|
||||||
- `...args` <...[string]> Arguments to pass to `pageFunction`
|
|
||||||
- returns: <[Promise]<[Object]>> Promise which resolves to function return value.
|
|
||||||
Example:
|
|
||||||
```js
|
|
||||||
const outerhtml = await page.$('#box', e => e.outerHTML);
|
|
||||||
```
|
|
||||||
|
|
||||||
|
|
||||||
#### frame.$$(selector, pageFunction, ...args)
|
|
||||||
- `selector` <[string]> A [selector] to be matched in the page
|
|
||||||
- `pageFunction` <[function]\([Element]\)> Function to be evaluted for every element matching `selector`.
|
|
||||||
- `...args` <...[string]> Arguments to pass to `pageFunction`
|
|
||||||
- returns: <[Promise]<[Array]<[Object]>>> Promise which resolves to array of function return values.
|
|
||||||
Example:
|
|
||||||
```js
|
|
||||||
const headings = await page.$$('h1,h2,h3,h4', el => el.textContent);
|
|
||||||
for (const heading of headings) console.log(heading);
|
|
||||||
```
|
|
||||||
|
|
||||||
|
|
||||||
#### frame.addScriptTag(url)
|
#### frame.addScriptTag(url)
|
||||||
- `url` <[string]> Url of a script to be added
|
- `url` <[string]> Url of a script to be added
|
||||||
|
@ -317,40 +317,6 @@ class Frame {
|
|||||||
return this._client.send('DOM.setFileInputFiles', { objectId, files: filePaths });
|
return this._client.send('DOM.setFileInputFiles', { objectId, files: filePaths });
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @template T
|
|
||||||
* @param {string} selector
|
|
||||||
* @param {function(!Element):T} pageFunction
|
|
||||||
* @param {!Array<*>} args
|
|
||||||
* @return {!Promise<?T>}
|
|
||||||
*/
|
|
||||||
async $(selector, pageFunction, ...args) {
|
|
||||||
let argsString = ['node'].concat(args.map(x => JSON.stringify(x))).join(',');
|
|
||||||
let expression = `(()=>{
|
|
||||||
let node = document.querySelector(${JSON.stringify(selector)});
|
|
||||||
if (!node)
|
|
||||||
return null;
|
|
||||||
return (${pageFunction})(${argsString});
|
|
||||||
})()`;
|
|
||||||
return this.evaluate(expression);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @template T
|
|
||||||
* @param {string} selector
|
|
||||||
* @param {function(!Element):T} pageFunction
|
|
||||||
* @param {!Array<*>} args
|
|
||||||
* @return {!Promise<!Array<T>>}
|
|
||||||
*/
|
|
||||||
async $$(selector, pageFunction, ...args) {
|
|
||||||
let argsString = ['node, index'].concat(args.map(x => JSON.stringify(x))).join(',');
|
|
||||||
let expression = `(()=>{
|
|
||||||
let nodes = document.querySelectorAll(${JSON.stringify(selector)});
|
|
||||||
return Array.prototype.map.call(nodes, (node, index) => (${pageFunction})(${argsString}));
|
|
||||||
})()`;
|
|
||||||
return this.evaluate(expression);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return {!Promise<string>}
|
* @return {!Promise<string>}
|
||||||
*/
|
*/
|
||||||
|
22
lib/Page.js
22
lib/Page.js
@ -623,28 +623,6 @@ class Page extends EventEmitter {
|
|||||||
async uploadFile(selector, ...filePaths) {
|
async uploadFile(selector, ...filePaths) {
|
||||||
return this.mainFrame().uploadFile(selector, ...filePaths);
|
return this.mainFrame().uploadFile(selector, ...filePaths);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @template T
|
|
||||||
* @param {string} selector
|
|
||||||
* @param {function(!Element):T} pageFunction
|
|
||||||
* @param {!Array<*>} args
|
|
||||||
* @return {!Promise<?T>}
|
|
||||||
*/
|
|
||||||
async $(selector, pageFunction, ...args) {
|
|
||||||
return this.mainFrame().$(selector, pageFunction, ...args);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @template T
|
|
||||||
* @param {string} selector
|
|
||||||
* @param {function(!Element):T} pageFunction
|
|
||||||
* @param {!Array<*>} args
|
|
||||||
* @return {!Promise<!Array<T>>}
|
|
||||||
*/
|
|
||||||
async $$(selector, pageFunction, ...args) {
|
|
||||||
return this.mainFrame().$$(selector, pageFunction, ...args);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @enum {string} */
|
/** @enum {string} */
|
||||||
|
68
test/test.js
68
test/test.js
@ -311,13 +311,10 @@ describe('Page', function() {
|
|||||||
|
|
||||||
it('should work when node is added through innerHTML', SX(async function() {
|
it('should work when node is added through innerHTML', SX(async function() {
|
||||||
await page.navigate(EMPTY_PAGE);
|
await page.navigate(EMPTY_PAGE);
|
||||||
let frame = page.mainFrame();
|
let watchdog = page.waitForSelector('h3 div');
|
||||||
let added = false;
|
await page.evaluate(addElement, 'span');
|
||||||
frame.waitForSelector('h3 div').then(() => added = true);
|
await page.evaluate(() => document.querySelector('span').innerHTML = '<h3><div></div></h3>');
|
||||||
expect(added).toBe(false);
|
await watchdog;
|
||||||
await frame.evaluate(addElement, 'span');
|
|
||||||
await page.$('span', span => span.innerHTML = '<h3><div></div></h3>');
|
|
||||||
expect(added).toBe(true);
|
|
||||||
}));
|
}));
|
||||||
|
|
||||||
it('Page.waitForSelector is shortcut for main frame', SX(async function() {
|
it('Page.waitForSelector is shortcut for main frame', SX(async function() {
|
||||||
@ -956,21 +953,21 @@ describe('Page', function() {
|
|||||||
await page.navigate(PREFIX + '/input/textarea.html');
|
await page.navigate(PREFIX + '/input/textarea.html');
|
||||||
await page.focus('textarea');
|
await page.focus('textarea');
|
||||||
await page.press('a', {text: 'f'});
|
await page.press('a', {text: 'f'});
|
||||||
expect(await page.$('textarea', t => t.value)).toBe('f');
|
expect(await page.evaluate(() => document.querySelector('textarea').value)).toBe('f');
|
||||||
|
|
||||||
await page.evaluate(() => window.addEventListener('keydown', e => e.preventDefault(), true));
|
await page.evaluate(() => window.addEventListener('keydown', e => e.preventDefault(), true));
|
||||||
|
|
||||||
await page.press('a', {text: 'y'});
|
await page.press('a', {text: 'y'});
|
||||||
expect(await page.$('textarea', t => t.value)).toBe('f');
|
expect(await page.evaluate(() => document.querySelector('textarea').value)).toBe('f');
|
||||||
}));
|
}));
|
||||||
it('should send a character with sendCharacter', SX(async function() {
|
it('should send a character with sendCharacter', SX(async function() {
|
||||||
await page.navigate(PREFIX + '/input/textarea.html');
|
await page.navigate(PREFIX + '/input/textarea.html');
|
||||||
await page.focus('textarea');
|
await page.focus('textarea');
|
||||||
await page.keyboard.sendCharacter('嗨');
|
await page.keyboard.sendCharacter('嗨');
|
||||||
expect(await page.$('textarea', t => t.value)).toBe('嗨');
|
expect(await page.evaluate(() => document.querySelector('textarea').value)).toBe('嗨');
|
||||||
await page.evaluate(() => window.addEventListener('keydown', e => e.preventDefault(), true));
|
await page.evaluate(() => window.addEventListener('keydown', e => e.preventDefault(), true));
|
||||||
await page.keyboard.sendCharacter('a');
|
await page.keyboard.sendCharacter('a');
|
||||||
expect(await page.$('textarea', t => t.value)).toBe('嗨a');
|
expect(await page.evaluate(() => document.querySelector('textarea').value)).toBe('嗨a');
|
||||||
}));
|
}));
|
||||||
it('should report shiftKey', SX(async function(){
|
it('should report shiftKey', SX(async function(){
|
||||||
await page.navigate(PREFIX + '/input/keyboard.html');
|
await page.navigate(PREFIX + '/input/keyboard.html');
|
||||||
@ -1070,13 +1067,14 @@ describe('Page', function() {
|
|||||||
it('should scroll and click the button', SX(async function(){
|
it('should scroll and click the button', SX(async function(){
|
||||||
await page.navigate(PREFIX + '/input/scrollable.html');
|
await page.navigate(PREFIX + '/input/scrollable.html');
|
||||||
await page.click('#button-5');
|
await page.click('#button-5');
|
||||||
expect(await page.$('#button-5', button => button.textContent)).toBe('clicked');
|
expect(await page.evaluate(() => document.querySelector('#button-5').textContent)).toBe('clicked');
|
||||||
await page.click('#button-80');
|
await page.click('#button-80');
|
||||||
expect(await page.$('#button-80', button => button.textContent)).toBe('clicked');
|
expect(await page.evaluate(() => document.querySelector('#button-80').textContent)).toBe('clicked');
|
||||||
}));
|
}));
|
||||||
it('should click a partially obscured button', SX(async function() {
|
it('should click a partially obscured button', SX(async function() {
|
||||||
await page.navigate(PREFIX + '/input/button.html');
|
await page.navigate(PREFIX + '/input/button.html');
|
||||||
await page.$('button', button => {
|
await page.evaluate(() => {
|
||||||
|
let button = document.querySelector('button');
|
||||||
button.textContent = 'Some really long text that will go offscreen';
|
button.textContent = 'Some really long text that will go offscreen';
|
||||||
button.style.position = 'absolute';
|
button.style.position = 'absolute';
|
||||||
button.style.left = '368px';
|
button.style.left = '368px';
|
||||||
@ -1089,7 +1087,7 @@ describe('Page', function() {
|
|||||||
await page.focus('textarea');
|
await page.focus('textarea');
|
||||||
let text = 'This is the text that we are going to try to select. Let\'s see how it goes.';
|
let text = 'This is the text that we are going to try to select. Let\'s see how it goes.';
|
||||||
await page.type(text);
|
await page.type(text);
|
||||||
await page.$('textarea', textarea => textarea.scrollTop = 0);
|
await page.evaluate(() => document.querySelector('textarea').scrollTop = 0);
|
||||||
let {x, y} = await page.evaluate(dimensions);
|
let {x, y} = await page.evaluate(dimensions);
|
||||||
await page.mouse.move(x + 2,y + 2);
|
await page.mouse.move(x + 2,y + 2);
|
||||||
await page.mouse.down();
|
await page.mouse.down();
|
||||||
@ -1110,20 +1108,20 @@ describe('Page', function() {
|
|||||||
it('should trigger hover state', SX(async function(){
|
it('should trigger hover state', SX(async function(){
|
||||||
await page.navigate(PREFIX + '/input/scrollable.html');
|
await page.navigate(PREFIX + '/input/scrollable.html');
|
||||||
await page.hover('#button-6');
|
await page.hover('#button-6');
|
||||||
expect(await page.$('button:hover', button => button.id)).toBe('button-6');
|
expect(await page.evaluate(() => document.querySelector('button:hover').id)).toBe('button-6');
|
||||||
await page.hover('#button-2');
|
await page.hover('#button-2');
|
||||||
expect(await page.$('button:hover', button => button.id)).toBe('button-2');
|
expect(await page.evaluate(() => document.querySelector('button:hover').id)).toBe('button-2');
|
||||||
await page.hover('#button-91');
|
await page.hover('#button-91');
|
||||||
expect(await page.$('button:hover', button => button.id)).toBe('button-91');
|
expect(await page.evaluate(() => document.querySelector('button:hover').id)).toBe('button-91');
|
||||||
}));
|
}));
|
||||||
it('should fire contextmenu event on right click', SX(async function(){
|
it('should fire contextmenu event on right click', SX(async function(){
|
||||||
await page.navigate(PREFIX + '/input/scrollable.html');
|
await page.navigate(PREFIX + '/input/scrollable.html');
|
||||||
await page.click('#button-8', {button: 'right'});
|
await page.click('#button-8', {button: 'right'});
|
||||||
expect(await page.$('#button-8', button => button.textContent)).toBe('context menu');
|
expect(await page.evaluate(() => document.querySelector('#button-8').textContent)).toBe('context menu');
|
||||||
}));
|
}));
|
||||||
it('should set modifier keys on click', SX(async function(){
|
it('should set modifier keys on click', SX(async function(){
|
||||||
await page.navigate(PREFIX + '/input/scrollable.html');
|
await page.navigate(PREFIX + '/input/scrollable.html');
|
||||||
await page.$('#button-3', button => button.addEventListener('mousedown', e => window.lastEvent = e, true));
|
await page.evaluate(() => document.querySelector('#button-3').addEventListener('mousedown', e => window.lastEvent = e, true));
|
||||||
let modifiers = {'Shift': 'shiftKey', 'Control': 'ctrlKey', 'Alt': 'altKey', 'Meta': 'metaKey'};
|
let modifiers = {'Shift': 'shiftKey', 'Control': 'ctrlKey', 'Alt': 'altKey', 'Meta': 'metaKey'};
|
||||||
for (let modifier in modifiers) {
|
for (let modifier in modifiers) {
|
||||||
await page.keyboard.down(modifier);
|
await page.keyboard.down(modifier);
|
||||||
@ -1141,7 +1139,7 @@ describe('Page', function() {
|
|||||||
it('should specify repeat property', SX(async function(){
|
it('should specify repeat property', SX(async function(){
|
||||||
await page.navigate(PREFIX + '/input/textarea.html');
|
await page.navigate(PREFIX + '/input/textarea.html');
|
||||||
await page.focus('textarea');
|
await page.focus('textarea');
|
||||||
await page.$('textarea', textarea => textarea.addEventListener('keydown', e => window.lastEvent = e, true));
|
await page.evaluate(() => document.querySelector('textarea').addEventListener('keydown', e => window.lastEvent = e, true));
|
||||||
await page.keyboard.down('a', {text: 'a'});
|
await page.keyboard.down('a', {text: 'a'});
|
||||||
expect(await page.evaluate(() => window.lastEvent.repeat)).toBe(false);
|
expect(await page.evaluate(() => window.lastEvent.repeat)).toBe(false);
|
||||||
await page.press('a');
|
await page.press('a');
|
||||||
@ -1394,34 +1392,6 @@ describe('Page', function() {
|
|||||||
}));
|
}));
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('Query selector', function() {
|
|
||||||
it('Page.$', SX(async function() {
|
|
||||||
await page.navigate(PREFIX + '/playground.html');
|
|
||||||
expect(await page.$('#first', element => element.textContent)).toBe('First div');
|
|
||||||
expect(await page.$('#second span', element => element.textContent)).toBe('Inner span');
|
|
||||||
expect(await page.$('#first', (element, arg1) => arg1, 'value1')).toBe('value1');
|
|
||||||
expect(await page.$('#first', (element, arg1, arg2) => arg2, 'value1', 'value2')).toBe('value2');
|
|
||||||
expect(await page.$('doesnot-exist', element => 5)).toBe(null);
|
|
||||||
expect(await page.$('button', function(element, arg1) {
|
|
||||||
element.textContent = arg1;
|
|
||||||
return true;
|
|
||||||
}, 'new button text')).toBe(true);
|
|
||||||
expect(await page.$('button', function(element) {
|
|
||||||
return element.textContent;
|
|
||||||
})).toBe('new button text');
|
|
||||||
}));
|
|
||||||
|
|
||||||
it('Page.$$', SX(async function() {
|
|
||||||
await page.navigate(PREFIX + '/playground.html');
|
|
||||||
expect((await page.$$('div', element => element.textContent)).length).toBe(2);
|
|
||||||
expect((await page.$$('div', (element, index) => index))[0]).toBe(0);
|
|
||||||
expect((await page.$$('div', (element, index) => index))[1]).toBe(1);
|
|
||||||
expect((await page.$$('doesnotexist', function(){})).length).toBe(0);
|
|
||||||
expect((await page.$$('div', element => element.textContent))[0]).toBe('First div');
|
|
||||||
expect((await page.$$('span', (element, index, arg1) => arg1, 'value1'))[0]).toBe('value1');
|
|
||||||
}));
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('Page.screenshot', function() {
|
describe('Page.screenshot', function() {
|
||||||
it('should work', SX(async function() {
|
it('should work', SX(async function() {
|
||||||
await page.setViewport({width: 500, height: 500});
|
await page.setViewport({width: 500, height: 500});
|
||||||
|
Loading…
Reference in New Issue
Block a user