mirror of
https://github.com/puppeteer/puppeteer
synced 2024-06-14 14:02:48 +00:00
feat(Frame): add click(), focus(), hover(), tap() and type() (#1970)
This patch adds frame shortcuts to drive input: - `Frame.click()` - `Frame.focus()` - `Frame.hover()` - `Frame.tap()` - `Frame.type()`
This commit is contained in:
parent
48218fae8a
commit
660b65780f
72
docs/api.md
72
docs/api.md
@ -135,16 +135,21 @@
|
|||||||
* [frame.addScriptTag(options)](#frameaddscripttagoptions)
|
* [frame.addScriptTag(options)](#frameaddscripttagoptions)
|
||||||
* [frame.addStyleTag(options)](#frameaddstyletagoptions)
|
* [frame.addStyleTag(options)](#frameaddstyletagoptions)
|
||||||
* [frame.childFrames()](#framechildframes)
|
* [frame.childFrames()](#framechildframes)
|
||||||
|
* [frame.click(selector[, options])](#frameclickselector-options)
|
||||||
* [frame.content()](#framecontent)
|
* [frame.content()](#framecontent)
|
||||||
* [frame.evaluate(pageFunction, ...args)](#frameevaluatepagefunction-args)
|
* [frame.evaluate(pageFunction, ...args)](#frameevaluatepagefunction-args)
|
||||||
* [frame.evaluateHandle(pageFunction, ...args)](#frameevaluatehandlepagefunction-args)
|
* [frame.evaluateHandle(pageFunction, ...args)](#frameevaluatehandlepagefunction-args)
|
||||||
* [frame.executionContext()](#frameexecutioncontext)
|
* [frame.executionContext()](#frameexecutioncontext)
|
||||||
|
* [frame.focus(selector)](#framefocusselector)
|
||||||
|
* [frame.hover(selector)](#framehoverselector)
|
||||||
* [frame.isDetached()](#frameisdetached)
|
* [frame.isDetached()](#frameisdetached)
|
||||||
* [frame.name()](#framename)
|
* [frame.name()](#framename)
|
||||||
* [frame.parentFrame()](#frameparentframe)
|
* [frame.parentFrame()](#frameparentframe)
|
||||||
* [frame.select(selector, ...values)](#frameselectselector-values)
|
* [frame.select(selector, ...values)](#frameselectselector-values)
|
||||||
* [frame.setContent(html)](#framesetcontenthtml)
|
* [frame.setContent(html)](#framesetcontenthtml)
|
||||||
|
* [frame.tap(selector)](#frametapselector)
|
||||||
* [frame.title()](#frametitle)
|
* [frame.title()](#frametitle)
|
||||||
|
* [frame.type(selector, text[, options])](#frametypeselector-text-options)
|
||||||
* [frame.url()](#frameurl)
|
* [frame.url()](#frameurl)
|
||||||
* [frame.waitFor(selectorOrFunctionOrTimeout[, options[, ...args]])](#framewaitforselectororfunctionortimeout-options-args)
|
* [frame.waitFor(selectorOrFunctionOrTimeout[, options[, ...args]])](#framewaitforselectororfunctionortimeout-options-args)
|
||||||
* [frame.waitForFunction(pageFunction[, options[, ...args]])](#framewaitforfunctionpagefunction-options-args)
|
* [frame.waitForFunction(pageFunction[, options[, ...args]])](#framewaitforfunctionpagefunction-options-args)
|
||||||
@ -621,6 +626,8 @@ const [response] = await Promise.all([
|
|||||||
]);
|
]);
|
||||||
```
|
```
|
||||||
|
|
||||||
|
Shortcut for [page.mainFrame().click(selector[, options])](#frameclickselector-options).
|
||||||
|
|
||||||
#### page.close()
|
#### page.close()
|
||||||
- returns: <[Promise]>
|
- returns: <[Promise]>
|
||||||
|
|
||||||
@ -856,6 +863,8 @@ puppeteer.launch().then(async browser => {
|
|||||||
This method fetches an element with `selector` and focuses it.
|
This method fetches an element with `selector` and focuses it.
|
||||||
If there's no element matching `selector`, the method throws an error.
|
If there's no element matching `selector`, the method throws an error.
|
||||||
|
|
||||||
|
Shortcut for [page.mainFrame().focus(selector)](#framefocusselector).
|
||||||
|
|
||||||
#### page.frames()
|
#### page.frames()
|
||||||
- returns: <[Array]<[Frame]>> An array of all frames attached to the page.
|
- returns: <[Array]<[Frame]>> An array of all frames attached to the page.
|
||||||
|
|
||||||
@ -913,6 +922,8 @@ The `page.goto` will throw an error if:
|
|||||||
This method fetches an element with `selector`, scrolls it into view if needed, and then uses [page.mouse](#pagemouse) to hover over the center of the element.
|
This method fetches an element with `selector`, scrolls it into view if needed, and then uses [page.mouse](#pagemouse) to hover over the center of the element.
|
||||||
If there's no element matching `selector`, the method throws an error.
|
If there's no element matching `selector`, the method throws an error.
|
||||||
|
|
||||||
|
Shortcut for [page.mainFrame().hover(selector)](#framehoverselector).
|
||||||
|
|
||||||
#### page.keyboard
|
#### page.keyboard
|
||||||
|
|
||||||
- returns: <[Keyboard]>
|
- returns: <[Keyboard]>
|
||||||
@ -1162,6 +1173,8 @@ In the case of multiple pages in a single browser, each page can have its own vi
|
|||||||
This method fetches an element with `selector`, scrolls it into view if needed, and then uses [page.touchscreen](#pagetouchscreen) to tap in the center of the element.
|
This method fetches an element with `selector`, scrolls it into view if needed, and then uses [page.touchscreen](#pagetouchscreen) to tap in the center of the element.
|
||||||
If there's no element matching `selector`, the method throws an error.
|
If there's no element matching `selector`, the method throws an error.
|
||||||
|
|
||||||
|
Shortcut for [page.mainFrame().tap(selector)](#frametapselector).
|
||||||
|
|
||||||
#### page.target()
|
#### page.target()
|
||||||
- returns: <[Target]> a target this page was created from.
|
- returns: <[Target]> a target this page was created from.
|
||||||
|
|
||||||
@ -1192,6 +1205,8 @@ page.type('#mytextarea', 'Hello'); // Types instantly
|
|||||||
page.type('#mytextarea', 'World', {delay: 100}); // Types slower, like a user
|
page.type('#mytextarea', 'World', {delay: 100}); // Types slower, like a user
|
||||||
```
|
```
|
||||||
|
|
||||||
|
Shortcut for [page.mainFrame().type(selector, text[, options])](#frametypeselector-text-options).
|
||||||
|
|
||||||
#### page.url()
|
#### page.url()
|
||||||
- returns: <[string]>
|
- returns: <[string]>
|
||||||
|
|
||||||
@ -1625,6 +1640,26 @@ Adds a `<link rel="stylesheet">` tag into the page with the desired url or a `<s
|
|||||||
#### frame.childFrames()
|
#### frame.childFrames()
|
||||||
- returns: <[Array]<[Frame]>>
|
- returns: <[Array]<[Frame]>>
|
||||||
|
|
||||||
|
#### frame.click(selector[, options])
|
||||||
|
- `selector` <[string]> A [selector] to search for element to click. If there are multiple elements satisfying the selector, the first will be clicked.
|
||||||
|
- `options` <[Object]>
|
||||||
|
- `button` <[string]> `left`, `right`, or `middle`, defaults to `left`.
|
||||||
|
- `clickCount` <[number]> defaults to 1. See [UIEvent.detail].
|
||||||
|
- `delay` <[number]> Time to wait between `mousedown` and `mouseup` in milliseconds. Defaults to 0.
|
||||||
|
- returns: <[Promise]> Promise which resolves when the element matching `selector` is successfully clicked. The Promise will be rejected if there is no element matching `selector`.
|
||||||
|
|
||||||
|
This method fetches an element with `selector`, scrolls it into view if needed, and then uses [page.mouse](#pagemouse) to click in the center of the element.
|
||||||
|
If there's no element matching `selector`, the method throws an error.
|
||||||
|
|
||||||
|
Bare in mind that if `click()` triggers a navigation event and there's a separate `page.waitForNavigation()` promise to be resolved, you may end up with a race condition that yields unexpected results. The correct pattern for click and wait for navigation is the following:
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
const [response] = await Promise.all([
|
||||||
|
page.waitForNavigation(waitOptions),
|
||||||
|
frame.click(selector, clickOptions),
|
||||||
|
]);
|
||||||
|
```
|
||||||
|
|
||||||
#### frame.content()
|
#### frame.content()
|
||||||
- returns: <[Promise]<[String]>>
|
- returns: <[Promise]<[String]>>
|
||||||
|
|
||||||
@ -1689,6 +1724,20 @@ await resultHandle.dispose();
|
|||||||
#### frame.executionContext()
|
#### frame.executionContext()
|
||||||
- returns: <[Promise]<[ExecutionContext]>> Execution context associated with this frame.
|
- returns: <[Promise]<[ExecutionContext]>> Execution context associated with this frame.
|
||||||
|
|
||||||
|
#### frame.focus(selector)
|
||||||
|
- `selector` <[string]> A [selector] of an element to focus. If there are multiple elements satisfying the selector, the first will be focused.
|
||||||
|
- returns: <[Promise]> Promise which resolves when the element matching `selector` is successfully focused. The promise will be rejected if there is no element matching `selector`.
|
||||||
|
|
||||||
|
This method fetches an element with `selector` and focuses it.
|
||||||
|
If there's no element matching `selector`, the method throws an error.
|
||||||
|
|
||||||
|
#### frame.hover(selector)
|
||||||
|
- `selector` <[string]> A [selector] to search for element to hover. If there are multiple elements satisfying the selector, the first will be hovered.
|
||||||
|
- returns: <[Promise]> Promise which resolves when the element matching `selector` is successfully hovered. Promise gets rejected if there's no element matching `selector`.
|
||||||
|
|
||||||
|
This method fetches an element with `selector`, scrolls it into view if needed, and then uses [page.mouse](#pagemouse) to hover over the center of the element.
|
||||||
|
If there's no element matching `selector`, the method throws an error.
|
||||||
|
|
||||||
#### frame.isDetached()
|
#### frame.isDetached()
|
||||||
- returns: <[boolean]>
|
- returns: <[boolean]>
|
||||||
|
|
||||||
@ -1723,9 +1772,32 @@ frame.select('select#colors', 'red', 'green', 'blue'); // multiple selections
|
|||||||
- `html` <[string]> HTML markup to assign to the page.
|
- `html` <[string]> HTML markup to assign to the page.
|
||||||
- returns: <[Promise]>
|
- returns: <[Promise]>
|
||||||
|
|
||||||
|
#### frame.tap(selector)
|
||||||
|
- `selector` <[string]> A [selector] to search for element to tap. If there are multiple elements satisfying the selector, the first will be tapped.
|
||||||
|
- returns: <[Promise]>
|
||||||
|
|
||||||
|
This method fetches an element with `selector`, scrolls it into view if needed, and then uses [page.touchscreen](#pagetouchscreen) to tap in the center of the element.
|
||||||
|
If there's no element matching `selector`, the method throws an error.
|
||||||
|
|
||||||
#### frame.title()
|
#### frame.title()
|
||||||
- returns: <[Promise]<[string]>> Returns page's title.
|
- returns: <[Promise]<[string]>> Returns page's title.
|
||||||
|
|
||||||
|
#### frame.type(selector, text[, options])
|
||||||
|
- `selector` <[string]> A [selector] of an element to type into. If there are multiple elements satisfying the selector, the first will be used.
|
||||||
|
- `text` <[string]> A text to type into a focused element.
|
||||||
|
- `options` <[Object]>
|
||||||
|
- `delay` <[number]> Time to wait between key presses in milliseconds. Defaults to 0.
|
||||||
|
- returns: <[Promise]>
|
||||||
|
|
||||||
|
Sends a `keydown`, `keypress`/`input`, and `keyup` event for each character in the text.
|
||||||
|
|
||||||
|
To press a special key, like `Control` or `ArrowDown`, use [`keyboard.press`](#keyboardpresskey-options).
|
||||||
|
|
||||||
|
```js
|
||||||
|
frame.type('#mytextarea', 'Hello'); // Types instantly
|
||||||
|
frame.type('#mytextarea', 'World', {delay: 100}); // Types slower, like a user
|
||||||
|
```
|
||||||
|
|
||||||
#### frame.url()
|
#### frame.url()
|
||||||
- returns: <[string]>
|
- returns: <[string]>
|
||||||
|
|
||||||
|
@ -547,6 +547,37 @@ class Frame {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {string} selector
|
||||||
|
* @param {!Object=} options
|
||||||
|
*/
|
||||||
|
async click(selector, options = {}) {
|
||||||
|
const handle = await this.$(selector);
|
||||||
|
console.assert(handle, 'No node found for selector: ' + selector);
|
||||||
|
await handle.click(options);
|
||||||
|
await handle.dispose();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {string} selector
|
||||||
|
*/
|
||||||
|
async focus(selector) {
|
||||||
|
const handle = await this.$(selector);
|
||||||
|
console.assert(handle, 'No node found for selector: ' + selector);
|
||||||
|
await handle.focus();
|
||||||
|
await handle.dispose();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {string} selector
|
||||||
|
*/
|
||||||
|
async hover(selector) {
|
||||||
|
const handle = await this.$(selector);
|
||||||
|
console.assert(handle, 'No node found for selector: ' + selector);
|
||||||
|
await handle.hover();
|
||||||
|
await handle.dispose();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param {string} selector
|
* @param {string} selector
|
||||||
* @param {!Array<string>} values
|
* @param {!Array<string>} values
|
||||||
@ -572,6 +603,28 @@ class Frame {
|
|||||||
}, values);
|
}, values);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {string} selector
|
||||||
|
*/
|
||||||
|
async tap(selector) {
|
||||||
|
const handle = await this.$(selector);
|
||||||
|
console.assert(handle, 'No node found for selector: ' + selector);
|
||||||
|
await handle.tap();
|
||||||
|
await handle.dispose();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {string} selector
|
||||||
|
* @param {string} text
|
||||||
|
* @param {{delay: (number|undefined)}=} options
|
||||||
|
*/
|
||||||
|
async type(selector, text, options) {
|
||||||
|
const handle = await this.$(selector);
|
||||||
|
console.assert(handle, 'No node found for selector: ' + selector);
|
||||||
|
await handle.type(text, options);
|
||||||
|
await handle.dispose();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param {(string|number|Function)} selectorOrFunctionOrTimeout
|
* @param {(string|number|Function)} selectorOrFunctionOrTimeout
|
||||||
* @param {!Object=} options
|
* @param {!Object=} options
|
||||||
|
47
lib/Page.js
47
lib/Page.js
@ -144,16 +144,6 @@ class Page extends EventEmitter {
|
|||||||
return this._coverage;
|
return this._coverage;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @param {string} selector
|
|
||||||
*/
|
|
||||||
async tap(selector) {
|
|
||||||
const handle = await this.$(selector);
|
|
||||||
console.assert(handle, 'No node found for selector: ' + selector);
|
|
||||||
await handle.tap();
|
|
||||||
await handle.dispose();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return {!Tracing}
|
* @return {!Tracing}
|
||||||
*/
|
*/
|
||||||
@ -814,31 +804,22 @@ class Page extends EventEmitter {
|
|||||||
* @param {string} selector
|
* @param {string} selector
|
||||||
* @param {!Object=} options
|
* @param {!Object=} options
|
||||||
*/
|
*/
|
||||||
async click(selector, options = {}) {
|
click(selector, options = {}) {
|
||||||
const handle = await this.$(selector);
|
return this.mainFrame().click(selector, options);
|
||||||
console.assert(handle, 'No node found for selector: ' + selector);
|
|
||||||
await handle.click(options);
|
|
||||||
await handle.dispose();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param {string} selector
|
* @param {string} selector
|
||||||
*/
|
*/
|
||||||
async hover(selector) {
|
focus(selector) {
|
||||||
const handle = await this.$(selector);
|
return this.mainFrame().focus(selector);
|
||||||
console.assert(handle, 'No node found for selector: ' + selector);
|
|
||||||
await handle.hover();
|
|
||||||
await handle.dispose();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param {string} selector
|
* @param {string} selector
|
||||||
*/
|
*/
|
||||||
async focus(selector) {
|
hover(selector) {
|
||||||
const handle = await this.$(selector);
|
return this.mainFrame().hover(selector);
|
||||||
console.assert(handle, 'No node found for selector: ' + selector);
|
|
||||||
await handle.focus();
|
|
||||||
await handle.dispose();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -846,20 +827,24 @@ class Page extends EventEmitter {
|
|||||||
* @param {!Array<string>} values
|
* @param {!Array<string>} values
|
||||||
* @return {!Promise<!Array<string>>}
|
* @return {!Promise<!Array<string>>}
|
||||||
*/
|
*/
|
||||||
async select(selector, ...values) {
|
select(selector, ...values) {
|
||||||
return this.mainFrame().select(selector, ...values);
|
return this.mainFrame().select(selector, ...values);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {string} selector
|
||||||
|
*/
|
||||||
|
tap(selector) {
|
||||||
|
return this.mainFrame().tap(selector);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param {string} selector
|
* @param {string} selector
|
||||||
* @param {string} text
|
* @param {string} text
|
||||||
* @param {{delay: (number|undefined)}=} options
|
* @param {{delay: (number|undefined)}=} options
|
||||||
*/
|
*/
|
||||||
async type(selector, text, options) {
|
type(selector, text, options) {
|
||||||
const handle = await this.$(selector);
|
return this.mainFrame().type(selector, text, options);
|
||||||
console.assert(handle, 'No node found for selector: ' + selector);
|
|
||||||
await handle.type(text, options);
|
|
||||||
await handle.dispose();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
Loading…
Reference in New Issue
Block a user