diff --git a/docs/api.md b/docs/api.md index f6ea2038..4f4c477e 100644 --- a/docs/api.md +++ b/docs/api.md @@ -65,9 +65,7 @@ * [class: Keyboard](#class-keyboard) + [keyboard.down(key[, options])](#keyboarddownkey-options) + [keyboard.modifiers()](#keyboardmodifiers) - + [keyboard.press(key[, options])](#keyboardpresskey-options) + [keyboard.sendCharacter(char)](#keyboardsendcharacterchar) - + [keyboard.type(text)](#keyboardtypetext) + [keyboard.up(key)](#keyboardupkey) * [class: Dialog](#class-dialog) + [dialog.accept([promptText])](#dialogacceptprompttext) @@ -578,6 +576,10 @@ In case of multiple pages in one browser, each page can have its own viewport si - `text` <[string]> A text to type into a focused element. - returns: <[Promise]> Promise which resolves when the text has been successfully typed. +Sends a `keydown`, `keypress`/`input`, and `keyup` event for each character in the text. + +To press a special key, use [`page.press`](#pagepresskey-options). + #### page.uploadFile(selector, ...filePaths) - `selector` <[string]> A query selector to a file input - `...filePaths` <[string]> Sets the value of the file input these paths @@ -614,21 +616,21 @@ Shortcut for [page.mainFrame().waitForSelector()](#framewaitforselectorselectoro ### class: Keyboard -Keyboard provides an api for managing a virtual keyboard. The high level api is [`keyboard.type`](#keyboardtypetext), which takes raw characters and generates proper keydown, keypress/input, and keyup events on your page. +Keyboard provides an api for managing a virtual keyboard. The high level api is [`page.type`](#pageypetext), which takes raw characters and generates proper keydown, keypress/input, and keyup events on your page. For finer control, you can use [`keyboard.down`](#keyboarddownkey-options), [`keyboard.up`](#keyboardupkey), and [`keyboard.sendCharacter`](#keyboardsendcharacterchar) to manually fire events as if they were generated from a real keyboard. An example of holding down `Shift` in order to select and delete some text: ```js -page.keyboard.type('Hello World!'); -page.keyboard.press('ArrowLeft'); +page.type('Hello World!'); +page.press('ArrowLeft'); page.keyboard.down('Shift'); -for (let i = 0; i = 0; i < ' World'.length; i++) - page.keyboard.press('ArrowLeft'); +for (let i = 0; i < ' World'.length; i++) + page.press('ArrowLeft'); page.keyboard.up('Shift'); -page.keyboard.press('Backspace'); +page.press('Backspace'); // Result text will end up saying 'Hello!' ``` @@ -651,15 +653,7 @@ If `key` is a modifier key, `Shift`, `Meta`, `Control`, or `Alt`, subsequent key - `Control` <[boolean]> - `Alt` <[boolean]> - Returns which modifier keys are currently active. Use [`keyboard.down`](#keyboarddownkey) to activate a modifier key. - -#### keyboard.press(key[, options]) -- `key` <[string]> Name of key to press, such as `ArrowLeft`. See [KeyboardEvent.key](https://www.w3.org/TR/uievents-key/) -- `options` <[Object]> - - `text` <[string]> If specified, generates an input event with this text. -- returns: <[Promise]> - -Shortcut for [`keyboard.down`](#keyboarddownkey) and [`keyboard.up`](#keyboardupkey). +Returns which modifier keys are currently active. Use [`keyboard.down`](#keyboarddownkey) to activate a modifier key. #### keyboard.sendCharacter(char) - `char` <[string]> Character to send into the page. @@ -671,17 +665,6 @@ Dispatches a `keypress` and `input` event. This does not send a `keydown` or `ke page.keyboard.sendCharacter('嗨'); ``` -#### keyboard.type(text) -- `text` <[string]> Text to type into the page -- returns: <[Promise]> - -Sends a `keydown`, `keypress`/`input`, and `keyup` event for each character in the text. -This is the suggested way to type printable characters. - -```js -page.keyboard.type('Hello World!'); -``` - #### keyboard.up(key) - `key` <[string]> Name of key to release, such as `ArrowLeft`. See [KeyboardEvent.key](https://www.w3.org/TR/uievents-key/) - returns: <[Promise]> diff --git a/lib/Keyboard.js b/lib/Keyboard.js index aaba917e..534bbdba 100644 --- a/lib/Keyboard.js +++ b/lib/Keyboard.js @@ -70,27 +70,6 @@ class Keyboard { }); } - /** - * @param {string} key - * @param {{text: (string|undefined)}} options - * @return {!Promise} - */ - async press(key, options) { - this.down(key, options); - await this.up(key); - } - - /** - * @param {string} text - * @return {!Promise} - */ - async type(text) { - let last; - for (let char of text) - last = this.press(char, {text: char}); - await last; - } - /** * @param {string} char * @return {!Promise} diff --git a/lib/Page.js b/lib/Page.js index dde60b47..e7485b83 100644 --- a/lib/Page.js +++ b/lib/Page.js @@ -514,7 +514,7 @@ class Page extends EventEmitter { /** * @param {string} selector - * @param {!Promise} + * @return {!Promise} */ async _querySelector(selector) { let {root} = await this._client.send('DOM.getDocument', { depth: 1 }); @@ -529,7 +529,7 @@ class Page extends EventEmitter { /** * @param {string} selector - * @param {!Promise} + * @return {!Promise} */ async click(selector) { let center = await this.evaluate(selector => { @@ -566,7 +566,7 @@ class Page extends EventEmitter { /** * @param {string} selector - * @param {!Promise} + * @return {!Promise} */ async focus(selector) { let success = await this.evaluate(selector => { @@ -582,18 +582,23 @@ class Page extends EventEmitter { /** * @param {string} text - * @param {!Promise} + * @return {!Promise} */ async type(text) { - return this._keyboard.type(text); + let last; + for (let char of text) + last = this.press(char, {text: char}); + await last; } /** * @param {string} text * @param {!Object=} options + * @return {!Promise} */ async press(key, options) { - return this._keyboard.press(key, options); + this._keyboard.down(key, options); + await this._keyboard.up(key); } /** diff --git a/test/test.js b/test/test.js index b2c1d80b..58a40f92 100644 --- a/test/test.js +++ b/test/test.js @@ -759,17 +759,17 @@ describe('Puppeteer', function() { await page.navigate(PREFIX + '/input/textarea.html'); await page.focus('textarea'); let keyboard = page.keyboard; - await keyboard.type('Hello World!'); + await page.type('Hello World!'); expect(await page.evaluate(() => document.querySelector('textarea').value)).toBe('Hello World!'); for (let i = 0; i < 'World!'.length; i++) - keyboard.press('ArrowLeft'); - await keyboard.type('inserted '); + page.press('ArrowLeft'); + await page.type('inserted '); expect(await page.evaluate(() => document.querySelector('textarea').value)).toBe('Hello inserted World!'); keyboard.down('Shift'); for (let i = 0; i < 'inserted '.length; i++) - keyboard.press('ArrowLeft'); + page.press('ArrowLeft'); keyboard.up('Shift'); - await keyboard.press('Backspace'); + await page.press('Backspace'); expect(await page.evaluate(() => document.querySelector('textarea').value)).toBe('Hello World!'); })); it('should send a character with Page.press', SX(async function() { @@ -825,13 +825,12 @@ describe('Puppeteer', function() { })); it('should send proper codes while typing', SX(async function(){ await page.navigate(PREFIX + '/input/keyboard.html'); - let keyboard = page.keyboard; - await keyboard.type('!'); + await page.type('!'); expect(await page.evaluate(() => getResult())).toBe( [ 'Keydown: ! 49 []', 'Keypress: ! 33 33 33 []', 'Keyup: ! 49 []'].join('\n')); - await keyboard.type('^'); + await page.type('^'); expect(await page.evaluate(() => getResult())).toBe( [ 'Keydown: ^ 54 []', 'Keypress: ^ 94 94 94 []', @@ -841,7 +840,7 @@ describe('Puppeteer', function() { await page.navigate(PREFIX + '/input/keyboard.html'); let keyboard = page.keyboard; await keyboard.down('Shift'); - await keyboard.type('~'); + await page.type('~'); expect(await page.evaluate(() => getResult())).toBe( [ 'Keydown: Shift 16 [Shift]', 'Keydown: ~ 192 [Shift]', // 192 is ` keyCode @@ -862,8 +861,7 @@ describe('Puppeteer', function() { Promise.resolve().then(() => event.preventDefault()); }, false); }); - let keyboard = page.keyboard; - await keyboard.type('Hello World!'); + await page.type('Hello World!'); expect(await page.evaluate(() => textarea.value)).toBe('He Wrd!'); })); it('keyboard.modifiers()', SX(async function(){