Skip to content

Commit

Permalink
api(press): bump .press to the page/frame level (#1262)
Browse files Browse the repository at this point in the history
  • Loading branch information
pavelfeldman authored Mar 6, 2020
1 parent 2724157 commit 49c1161
Show file tree
Hide file tree
Showing 4 changed files with 87 additions and 7 deletions.
58 changes: 56 additions & 2 deletions docs/api.md
Original file line number Diff line number Diff line change
Expand Up @@ -650,6 +650,7 @@ page.removeListener('request', logRequest);
- [page.mouse](#pagemouse)
- [page.opener()](#pageopener)
- [page.pdf([options])](#pagepdfoptions)
- [page.press(selector, key[, options])](#pagepressselector-key-options)
- [page.reload([options])](#pagereloadoptions)
- [page.route(url, handler)](#pagerouteurl-handler)
- [page.screenshot([options])](#pagescreenshotoptions)
Expand Down Expand Up @@ -1193,11 +1194,19 @@ If there's no element matching `selector`, the method throws an error.
Shortcut for [page.mainFrame().focus(selector)](#framefocusselector).

#### page.frame(options)
- `options` <[Object]>
- `options` <[string]|[Object]> Frame name or other frame lookup options.
- `name` <[string]> frame name specified in the `iframe`'s `name` attribute
- `url` <[string]|[RegExp]|[Function]> A glob pattern, regex pattern or predicate receiving frame's `url` as a [URL] object.
- returns: <[Frame]> frame matching the criteria.

```js
const frame = page.frame('frame-name');
```

```js
const frame = page.frame({ url: /.*domain.*/ });
```

Returns frame matching the specified criteria. Either `name` or `url` must be specified.

#### page.frames()
Expand Down Expand Up @@ -1366,6 +1375,28 @@ The `format` options are:
> 1. Script tags inside templates are not evaluated.
> 2. Page styles are not visible inside templates.
#### page.press(selector, key[, options])
- `selector` <[string]> A selector of an element to type into. If there are multiple elements satisfying the selector, the first will be used.
- `key` <[string]> Name of key to press, such as `ArrowLeft`. See [USKeyboardLayout] for a list of all key names.
- `options` <[Object]>
- `text` <[string]> If specified, generates an input event with this text.
- `delay` <[number]> Time to wait between `keydown` and `keyup` in milliseconds. Defaults to 0.
- `waitFor` <[boolean]> Whether to wait for the element to be present in the dom. Defaults to `true`.
- `waitUntil` <"commit"|"load"|"domcontentloaded"|"networkidle0"|"networkidle2"> When to consider navigation succeeded, defaults to `commit`. Events can be either:
- `'commit'` - navigation is committed, new url is displayed in the browser address bar.
- `'load'` - consider navigation to be finished when the `load` event is fired.
- `'domcontentloaded'` - consider navigation to be finished when the `DOMContentLoaded` event is fired.
- `'networkidle0'` - consider navigation to be finished when there are no more than 0 network connections for at least `500` ms.
- `'networkidle2'` - consider navigation to be finished when there are no more than 2 network connections for at least `500` ms.
- `timeout` <[number]> Maximum time in milliseconds, defaults to 30 seconds, pass `0` to disable timeout. The default value can be changed by using the [browserContext.setDefaultTimeout(timeout)](#browsercontextsetdefaulttimeouttimeout) or [page.setDefaultTimeout(timeout)](#pagesetdefaulttimeouttimeout) methods.
- returns: <[Promise]>

Focuses the element, and then uses [`keyboard.down`](#keyboarddownkey-options) and [`keyboard.up`](#keyboardupkey).

If `key` is a single character and no modifier keys besides `Shift` are being held down, a `keypress`/`input` event will also be generated. The `text` option can be specified to force an input event to be generated.

> **NOTE** Modifier keys DO affect `page.press`. Holding down `Shift` will type the text in upper case.
#### page.reload([options])
- `options` <[Object]> Navigation parameters which might have the following properties:
- `timeout` <[number]> Maximum navigation time in milliseconds, defaults to 30 seconds, pass `0` to disable timeout. The default value can be changed by using the [browserContext.setDefaultNavigationTimeout(timeout)](#browsercontextsetdefaultnavigationtimeouttimeout), [browserContext.setDefaultTimeout(timeout)](#browsercontextsetdefaulttimeouttimeout), [page.setDefaultNavigationTimeout(timeout)](#pagesetdefaultnavigationtimeouttimeout) or [page.setDefaultTimeout(timeout)](#pagesetdefaulttimeouttimeout) methods.
Expand Down Expand Up @@ -1860,6 +1891,7 @@ An example of getting text from an iframe element:
- [frame.isDetached()](#frameisdetached)
- [frame.name()](#framename)
- [frame.parentFrame()](#frameparentframe)
- [frame.press(selector, key[, options])](#framepressselector-key-options)
- [frame.select(selector, values[, options])](#frameselectselector-values-options)
- [frame.setContent(html[, options])](#framesetcontenthtml-options)
- [frame.title()](#frametitle)
Expand Down Expand Up @@ -2165,6 +2197,28 @@ If the name is empty, returns the id attribute instead.
#### frame.parentFrame()
- returns: <?[Frame]> Parent frame, if any. Detached frames and main frames return `null`.

#### frame.press(selector, key[, options])
- `selector` <[string]> A selector of an element to type into. If there are multiple elements satisfying the selector, the first will be used.
- `key` <[string]> Name of key to press, such as `ArrowLeft`. See [USKeyboardLayout] for a list of all key names.
- `options` <[Object]>
- `text` <[string]> If specified, generates an input event with this text.
- `delay` <[number]> Time to wait between `keydown` and `keyup` in milliseconds. Defaults to 0.
- `waitFor` <[boolean]> Whether to wait for the element to be present in the dom. Defaults to `true`.
- `waitUntil` <"commit"|"load"|"domcontentloaded"|"networkidle0"|"networkidle2"> When to consider navigation succeeded, defaults to `commit`. Events can be either:
- `'commit'` - navigation is committed, new url is displayed in the browser address bar.
- `'load'` - consider navigation to be finished when the `load` event is fired.
- `'domcontentloaded'` - consider navigation to be finished when the `DOMContentLoaded` event is fired.
- `'networkidle0'` - consider navigation to be finished when there are no more than 0 network connections for at least `500` ms.
- `'networkidle2'` - consider navigation to be finished when there are no more than 2 network connections for at least `500` ms.
- `timeout` <[number]> Maximum time in milliseconds, defaults to 30 seconds, pass `0` to disable timeout. The default value can be changed by using the [browserContext.setDefaultTimeout(timeout)](#browsercontextsetdefaulttimeouttimeout) or [page.setDefaultTimeout(timeout)](#pagesetdefaulttimeouttimeout) methods.
- returns: <[Promise]>

Focuses the element, and then uses [`keyboard.down`](#keyboarddownkey-options) and [`keyboard.up`](#keyboardupkey).

If `key` is a single character and no modifier keys besides `Shift` are being held down, a `keypress`/`input` event will also be generated. The `text` option can be specified to force an input event to be generated.

> **NOTE** Modifier keys DO affect `frame.press`. Holding down `Shift` will type the text in upper case.
#### frame.select(selector, values[, options])
- `selector` <[string]> A selector to query frame for.
- `values` <[string]|[ElementHandle]|[Object]|[Array]<[string]>|[Array]<[ElementHandle]>|[Array]<[Object]>> Options to select. If the `<select>` has the `multiple` attribute, all matching options are selected, otherwise only the first option matching one of the passed options is selected. String values are equivalent to `{value:'string'}`. Option is considered matching if all specified properties match.
Expand Down Expand Up @@ -2654,7 +2708,7 @@ Focuses the element, and then uses [`keyboard.down`](#keyboarddownkey-options) a

If `key` is a single character and no modifier keys besides `Shift` are being held down, a `keypress`/`input` event will also be generated. The `text` option can be specified to force an input event to be generated.

> **NOTE** Modifier keys DO effect `elementHandle.press`. Holding down `Shift` will type the text in upper case.
> **NOTE** Modifier keys DO affect `elementHandle.press`. Holding down `Shift` will type the text in upper case.
#### elementHandle.screenshot([options])
- `options` <[Object]> Screenshot options.
Expand Down
6 changes: 6 additions & 0 deletions src/frames.ts
Original file line number Diff line number Diff line change
Expand Up @@ -848,6 +848,12 @@ export class Frame {
handle.dispose();
}

async press(selector: string, key: string, options?: { delay?: number, text?: string } & types.NavigateOptions & types.WaitForOptions & types.NavigateOptions) {
const handle = await this._optionallyWaitForSelectorInUtilityContext(selector, options);
await handle.press(key, options);
handle.dispose();
}

async check(selector: string, options?: types.WaitForOptions & types.NavigateOptions) {
const handle = await this._optionallyWaitForSelectorInUtilityContext(selector, options);
await handle.check(options);
Expand Down
16 changes: 11 additions & 5 deletions src/page.ts
Original file line number Diff line number Diff line change
Expand Up @@ -206,12 +206,14 @@ export class Page extends platform.EventEmitter {
return this._frameManager.mainFrame();
}

frame(options: { name?: string, url?: types.URLMatch }): frames.Frame | null {
assert(options.name || options.url, 'Either name or url matcher should be specified');
frame(options: string | { name?: string, url?: types.URLMatch }): frames.Frame | null {
const name = helper.isString(options) ? options : options.name;
const url = helper.isObject(options) ? options.url : undefined;
assert(name || url, 'Either name or url matcher should be specified');
return this.frames().find(f => {
if (options.name)
return f.name() === options.name;
return platform.urlMatches(f.url(), options.url);
if (name)
return f.name() === name;
return platform.urlMatches(f.url(), url);
}) || null;
}

Expand Down Expand Up @@ -471,6 +473,10 @@ export class Page extends platform.EventEmitter {
return this.mainFrame().type(selector, text, options);
}

async press(selector: string, key: string, options?: { delay?: number, text?: string } & types.NavigateOptions & types.WaitForOptions & types.NavigateOptions) {
return this.mainFrame().press(selector, key, options);
}

async check(selector: string, options?: types.WaitForOptions & types.NavigateOptions) {
return this.mainFrame().check(selector, options);
}
Expand Down
14 changes: 14 additions & 0 deletions test/page.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -1112,4 +1112,18 @@ module.exports.describe = function({testRunner, expect, headless, playwright, FF
expect(page.frame({ url: /empty/ }).url()).toBe(server.EMPTY_PAGE);
});
});

fdescribe('Page api coverage', function() {
it('Page.press should work', async({page, server}) => {
await page.goto(server.PREFIX + '/input/textarea.html');
await page.press('textarea', 'a');
expect(await page.evaluate(() => document.querySelector('textarea').value)).toBe('a');
});
it('Frame.press should work', async({page, server}) => {
await page.setContent(`<iframe name=inner src="${server.PREFIX}/input/textarea.html"></iframe>`);
const frame = page.frame('inner');
await frame.press('textarea', 'a');
expect(await frame.evaluate(() => document.querySelector('textarea').value)).toBe('a');
});
});
};

0 comments on commit 49c1161

Please sign in to comment.