From bf7698e8f87e9f3d5bc4b4a0f7bce06b42b511b7 Mon Sep 17 00:00:00 2001 From: JoelEinbinder Date: Mon, 17 Jul 2017 18:49:52 -0700 Subject: [PATCH] Intorduce Page.keyboard (#74) Introduce page.keyboard to provide low-level access to the keyboard. --- .gitignore | 1 + docs/api.md | 99 +++++++- lib/Keyboard.js | 238 ++++++++++++++++++ lib/Page.js | 28 +-- phantom_shim/WebPage.js | 67 +++++ test/assets/input/keyboard.html | 44 ++++ test/test.js | 105 ++++++++ .../test/module/webpage/keydown-event.js | 5 +- .../test/module/webpage/keypress-event.js | 21 +- .../test/module/webpage/keyup-event.js | 5 +- utils/doclint/lint.js | 1 + 11 files changed, 576 insertions(+), 38 deletions(-) create mode 100644 lib/Keyboard.js create mode 100644 test/assets/input/keyboard.html diff --git a/.gitignore b/.gitignore index 2c7c3259832..0f6a0a0cd4a 100644 --- a/.gitignore +++ b/.gitignore @@ -5,3 +5,4 @@ .DS_Store *.swp *.pyc +.vscode diff --git a/docs/api.md b/docs/api.md index db1f6cc2b20..e97be309e37 100644 --- a/docs/api.md +++ b/docs/api.md @@ -35,6 +35,7 @@ * [page.frames()](#pageframes) * [page.httpHeaders()](#pagehttpheaders) * [page.injectFile(filePath)](#pageinjectfilefilepath) + * [page.keyboard](#pagekeyboard) * [page.mainFrame()](#pagemainframe) * [page.navigate(url, options)](#pagenavigateurl-options) * [page.pdf(options)](#pagepdfoptions) @@ -54,6 +55,13 @@ * [page.userAgent()](#pageuseragent) * [page.viewport()](#pageviewport) * [page.waitFor(selector)](#pagewaitforselector) +- [class: Keyboard](#class-keyboard) + * [keyboard.hold(key[, options])](#keyboardholdkey-options) + * [keyboard.modifiers()](#keyboardmodifiers) + * [keyboard.press(key[, options])](#keyboardpresskey-options) + * [keyboard.release(key)](#keyboardreleasekey) + * [keyboard.sendCharacter(char)](#keyboardsendcharacterchar) + * [keyboard.type(text)](#keyboardtypetext) - [class: Dialog](#class-dialog) * [dialog.accept([promptText])](#dialogacceptprompttext) * [dialog.dismiss()](#dialogdismiss) @@ -186,7 +194,7 @@ An example of creating a page, navigating it to a URL and saving screenshot as ` ```js const {Browser} = require('puppeteer'); const browser = new Browser(); -browser.newPage().then(async page => +browser.newPage().then(async page => await page.navigate('https://example.com'); await page.screenshot({path: 'screenshot.png'}); browser.close(); @@ -299,6 +307,10 @@ This is a shortcut for [page.mainFrame().evaluate()](#frameevaluatefun-args) met - `filePath` <[string]> Path to the javascript file to be injected into page. - returns: <[Promise]> Promise which resolves when file gets successfully evaluated in page. +#### page.keyboard + +- returns: <[Keyboard]> + #### page.mainFrame() - returns: <[Frame]> returns page's main frame. @@ -395,7 +407,7 @@ The `format` options are: - `callback` <[function]> Callback function which will be called in puppeteer's context. - returns: <[Promise]> Promise which resolves when callback is successfully initialized -The in-page callback allows page to asynchronously reach back to the Puppeteer. +The in-page callback allows page to asynchronously reach back to the Puppeteer. An example of a page showing amount of CPU's: ```js const os = require('os'); @@ -481,6 +493,82 @@ This is a shortcut for [page.mainFrame().url()](#frameurl) Shortcut for [page.mainFrame().waitFor(selector)](#framewaitforselector). +### 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. + +For finer control, you can use press, release, and sendCharacter 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.keyboard.hold('Shift'); +for (let i = 0; i = 0; i < ' World'.length; i++) + page.keyboard.press('ArrowLeft'); +page.keyboard.release('Shift'); + +page.keyboard.press('Backspace'); +// Result text will end up saying 'Hello!' +``` + +#### keyboard.hold(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]> + +Dispatches a `keydown` event. + +This will not send input events unless `text` is specified. + +If `key` is a modifier key, `Shift`, `Meta`, `Control`, or `Alt`, subsequent key presses will be sent with that modifier active. To release the modifier key, use [`keyboard.release`](#keyboardreleasekey). + +#### keyboard.modifiers() +- returns: <[Object]> + - `Shift` <[boolean]> + - `Meta` <[boolean]> + - `Control` <[boolean]> + - `Alt` <[boolean]> + + Returns which modifier keys are currently active. Use [`keyboard.hold`](#keyboardholdkey) 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.hold`](#keyboardholdkey) and [`keyboard.release`](#keyboardreleasekey). + +#### keyboard.release(key) +- `key` <[string]> Name of key to release, such as `ArrowLeft`. See [KeyboardEvent.key](https://www.w3.org/TR/uievents-key/) +- returns: <[Promise]> + +Dispatches a `keyup` event. + +#### keyboard.sendCharacter(char) +- `char` <[string]> Character to send into the page. +- returns: <[Promise]> + +Dispatches a `keypress` and `input` event. This does not send a `keydown` or `keyup` event. + +```js +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!'); +``` + ### class: Dialog [Dialog] objects are dispatched by page via the ['dialog'](#event-dialog) event. @@ -558,7 +646,7 @@ If the function, passed to the `page.evaluate`, returns a [Promise], then `page. ```js const {Browser} = require('puppeteer'); const browser = new Browser(); -browser.newPage().then(async page => +browser.newPage().then(async page => const result = await page.evaluate(() => { return Promise.resolve().then(() => 8 * 7); }); @@ -682,7 +770,7 @@ Continues request. #### interceptedRequest.headers - <[Headers]> -Contains the [Headers] object associated with the request. +Contains the [Headers] object associated with the request. Headers could be mutated with the `headers.append`, `headers.set` and other methods. Must not be changed in response to an authChallenge. @@ -693,7 +781,7 @@ methods. Must not be changed in response to an authChallenge. #### interceptedRequest.method - <[string]> -Contains the request's method (GET, POST, etc.) +Contains the request's method (GET, POST, etc.) If set this allows the request method to be overridden. Must not be changed in response to an authChallenge. @@ -780,4 +868,5 @@ If there's already a header with name `name`, the header gets overwritten. [Request]: https://github.com/GoogleChrome/puppeteer/blob/master/docs/api.md#class-request "Request" [Browser]: https://github.com/GoogleChrome/puppeteer/blob/master/docs/api.md#class-browser "Browser" [Body]: https://github.com/GoogleChrome/puppeteer/blob/master/docs/api.md#class-body "Body" +[Keyboard]: https://github.com/GoogleChrome/puppeteer/blob/master/docs/api.md#class-keyboard "Keyboard" [Dialog]: https://github.com/GoogleChrome/puppeteer/blob/master/docs/api.md#class-dialog "Dialog" diff --git a/lib/Keyboard.js b/lib/Keyboard.js new file mode 100644 index 00000000000..8b17b5dd07a --- /dev/null +++ b/lib/Keyboard.js @@ -0,0 +1,238 @@ +/** + * Copyright 2017 Google Inc. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the 'License'); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an 'AS IS' BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +class Keyboard { + /** + * @param {!Connection} client + */ + constructor(client) { + this._client = client; + /** @type {!Set} */ + this._keys = new Set(); + } + + /** + * @param {string} key + * @param {{text: (string|undefined)}} options + * @return {!Promise} + */ + async hold(key, options) { + let {text} = options || {}; + this._keys.add(key); + await this._client.send('Input.dispatchKeyEvent', { + type: text ? 'keyDown' : 'rawKeyDown', + modifiers: this._modifiersMask(), + windowsVirtualKeyCode: codeForKey(key), + key: key, + text: text, + unmodifiedText: text + }); + } + + /** + * @param {{Shift: boolean, Alt: boolean, Meta: boolean, Control: boolean}} + */ + modifiers() { + return { + Shift: this._keys.has('Shift'), + Alt: this._keys.has('Alt'), + Meta: this._keys.has('Meta'), + Control: this._keys.has('Control') + }; + } + + /** + * @param {string} key + * @return {!Promise} + */ + async release(key) { + this._keys.delete(key); + await this._client.send('Input.dispatchKeyEvent', { + type: 'keyUp', + modifiers: this._modifiersMask(), + key, + windowsVirtualKeyCode: codeForKey(key), + }); + } + + /** + * @param {string} key + * @param {{text: (string|undefined)}} options + * @return {!Promise} + */ + async press(key, options) { + this.hold(key, options); + await this.release(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} + */ + async sendCharacter(char) { + await this._client.send('Input.dispatchKeyEvent', { + type: 'char', + modifiers: this._modifiersMask(), + text: char, + key: char, + unmodifiedText: char + }); + } + + /** + * @return {number} + */ + _modifiersMask() { + let modifiers = 0; + if (this._keys.has('Alt')) + modifiers += 1; + if (this._keys.has('Control')) + modifiers += 2; + if (this._keys.has('Meta')) + modifiers += 4; + if (this._keys.has('Shift')) + modifiers += 8; + return modifiers; + } +} + +let keys = { + 'Cancel': 3, + 'Help': 6, + 'Backspace': 8, + 'Tab': 9, + 'Clear': 12, + 'Enter': 13, + 'Shift': 16, + 'Control': 17, + 'Alt': 18, + 'Pause': 19, + 'CapsLock': 20, + 'Escape': 27, + 'Convert': 28, + 'NonConvert': 29, + 'Accept': 30, + 'ModeChange': 31, + 'PageUp': 33, + 'PageDown': 34, + 'End': 35, + 'Home': 36, + 'ArrowLeft': 37, + 'ArrowUp': 38, + 'ArrowRight': 39, + 'ArrowDown': 40, + 'Select': 41, + 'Print': 42, + 'Execute': 43, + 'PrintScreen': 44, + 'Insert': 45, + 'Delete': 46, + ')': 48, + '!': 49, + '@': 50, + '#': 51, + '$': 52, + '%': 53, + '^': 54, + '&': 55, + '*': 56, + '(': 57, + 'Meta': 91, + 'ContextMenu': 93, + 'F1': 112, + 'F2': 113, + 'F3': 114, + 'F4': 115, + 'F5': 116, + 'F6': 117, + 'F7': 118, + 'F8': 119, + 'F9': 120, + 'F10': 121, + 'F11': 122, + 'F12': 123, + 'F13': 124, + 'F14': 125, + 'F15': 126, + 'F16': 127, + 'F17': 128, + 'F18': 129, + 'F19': 130, + 'F20': 131, + 'F21': 132, + 'F22': 133, + 'F23': 134, + 'F24': 135, + 'NumLock': 144, + 'ScrollLock': 145, + 'VolumeMute': 181, + 'VolumeDown': 182, + 'VolumeUp': 183, + ';': 186, + ':': 186, + '=': 187, + '+': 187, + ',': 188, + '<': 188, + '-': 189, + '_': 189, + '.': 190, + '>': 190, + '/': 191, + '?': 191, + '`': 192, + '~': 192, + '[': 219, + '{': 219, + '\\': 220, + '|': 220, + ']': 221, + '}': 221, + '\'': 222, + '"': 222, + 'AltGraph': 225, + 'Attn': 246, + 'CrSel': 247, + 'ExSel': 248, + 'EraseEof': 249, + 'Play': 250, + 'ZoomOut': 251 +}; + +/** + * @param {string} key + * @return {number} + */ +function codeForKey(key) { + if (keys[key]) + return keys[key]; + if (key.length === 1) + return key.toUpperCase().charCodeAt(0); + return 0; +} + +module.exports = Keyboard; diff --git a/lib/Page.js b/lib/Page.js index 5e82cb95f95..83d948984a2 100644 --- a/lib/Page.js +++ b/lib/Page.js @@ -22,6 +22,7 @@ let Navigator = require('./Navigator'); let Dialog = require('./Dialog'); let EmulationManager = require('./EmulationManager'); let FrameManager = require('./FrameManager'); +let Keyboard = require('./Keyboard'); let helper = require('./helper'); class Page extends EventEmitter { @@ -59,6 +60,8 @@ class Page extends EventEmitter { /** @type {!Map} */ this._inPageCallbacks = new Map(); + this._keyboard = new Keyboard(this._client); + this._screenshotTaskChain = Promise.resolve(); this._frameManager.on(FrameManager.Events.FrameAttached, event => this.emit(Page.Events.FrameAttached, event)); @@ -84,6 +87,13 @@ class Page extends EventEmitter { return this._frameManager.mainFrame(); } + /** + * @return {!Keyboard} + */ + get keyboard() { + return this._keyboard; + } + /** * @return {!Array} */ @@ -558,23 +568,7 @@ class Page extends EventEmitter { * @param {!Promise} */ async type(text) { - for (let i = 0; i < text.length; i++) { - let char = text.charAt(i); - this._client.send('Input.dispatchKeyEvent', { - type: 'keyDown', - key: char - }); - this._client.send('Input.dispatchKeyEvent', { - type: 'char', - text: char, - key: char, - unmodifiedText: char - }); - await this._client.send('Input.dispatchKeyEvent', { - type: 'keyUp', - key: char - }); - } + return this._keyboard.type(text); } /** diff --git a/phantom_shim/WebPage.js b/phantom_shim/WebPage.js index bda4fd0a961..4c453aaf358 100644 --- a/phantom_shim/WebPage.js +++ b/phantom_shim/WebPage.js @@ -67,6 +67,18 @@ class WebPage { this._pageEvents.on(PageEvents.Alert, message => this._onAlert(message)); this._pageEvents.on(PageEvents.Dialog, dialog => this._onDialog(dialog)); this._pageEvents.on(PageEvents.PageError, error => (this._onError || noop).call(null, error.message, error.stack)); + this.event = { + key: { + A: 65, + B: 66, + C: 67, + Home: ['Home'], + Delete: ['Delete'], + Backspace: ['Backspace'], + Cut: ['Cut'], + Paste: ['Paste'] + } + }; } /** @@ -343,6 +355,61 @@ class WebPage { await(this._page.uploadFile(selector, ...files)); } + /** + * @param {string} eventType + * @param {!Array<*>} args + */ + sendEvent(eventType, ...args) { + if (eventType.startsWith('key')) + this._sendKeyboardEvent.apply(this, arguments); + } + + /** + * @param {string} eventType + * @param {string} keyOrKeys + * @param {null} nop1 + * @param {null} nop2 + * @param {number} modifier + */ + _sendKeyboardEvent(eventType, keyOrKeys, nop1, nop2, modifier) { + switch (eventType) { + case 'keyup': + if (typeof keyOrKeys === 'number') { + await(this._page.keyboard.release(String.fromCharCode(keyOrKeys))); + break; + } + for (let key of keyOrKeys) + await(this._page.keyboard.release(key)); + break; + case 'keypress': + if (modifier & 0x04000000) + this._page.keyboard.hold('Control'); + if (modifier & 0x02000000) + this._page.keyboard.hold('Shift'); + if (keyOrKeys instanceof Array) { + this._page.keyboard.hold(keyOrKeys[0]); + await(this._page.keyboard.release(keyOrKeys[0])); + } else if (typeof keyOrKeys === 'number') { + await(this._page.type(String.fromCharCode(keyOrKeys))); + } else { + await(this._page.type(keyOrKeys)); + } + if (modifier & 0x02000000) + this._page.keyboard.release('Shift'); + if (modifier & 0x04000000) + this._page.keyboard.release('Control'); + break; + case 'keydown': + if (typeof keyOrKeys === 'number') { + await(this._page.keyboard.hold(String.fromCharCode(keyOrKeys))); + break; + } + for (let key of keyOrKeys) + await(this._page.keyboard.hold(key)); + break; + } + } + /** * @param {string} html * @param {function()=} callback diff --git a/test/assets/input/keyboard.html b/test/assets/input/keyboard.html new file mode 100644 index 00000000000..539c327bcac --- /dev/null +++ b/test/assets/input/keyboard.html @@ -0,0 +1,44 @@ + + + + Keyboard test + + + + + + \ No newline at end of file diff --git a/test/test.js b/test/test.js index 46bcad6e841..c283fd70f65 100644 --- a/test/test.js +++ b/test/test.js @@ -672,6 +672,111 @@ describe('Puppeteer', function() { return promise.then(() => reader.result); })).toBe('contents of the file'); })); + it('should move with the arrow keys', SX(async function(){ + await page.navigate(PREFIX + '/input/textarea.html'); + await page.focus('textarea'); + let keyboard = page.keyboard; + await keyboard.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 '); + expect(await page.evaluate(() => document.querySelector('textarea').value)).toBe('Hello inserted World!'); + keyboard.hold('Shift'); + for (let i = 0; i < 'inserted '.length; i++) + keyboard.press('ArrowLeft'); + keyboard.release('Shift'); + keyboard.hold('Backspace'); + await keyboard.release('Backspace'); + expect(await page.evaluate(() => document.querySelector('textarea').value)).toBe('Hello World!'); + })); + it('should report shiftKey', SX(async function(){ + await page.navigate(PREFIX + '/input/keyboard.html'); + let keyboard = page.keyboard; + let codeForKey = {'Shift': 16, 'Alt': 18, 'Meta': 91, 'Control': 17}; + for (let modifierKey in codeForKey) { + await keyboard.hold(modifierKey); + expect(await page.evaluate(() => getResult())).toBe('Keydown: ' + modifierKey + ' ' + codeForKey[modifierKey] + ' [' + modifierKey + ']'); + await keyboard.hold('!'); + expect(await page.evaluate(() => getResult())).toBe('Keydown: ! 49 [' + modifierKey + ']'); + await keyboard.release('!'); + expect(await page.evaluate(() => getResult())).toBe('Keyup: ! 49 [' + modifierKey + ']'); + await keyboard.release(modifierKey); + expect(await page.evaluate(() => getResult())).toBe('Keyup: ' + modifierKey + ' ' + codeForKey[modifierKey] + ' []'); + } + })); + it('should report multiple modifiers', SX(async function(){ + await page.navigate(PREFIX + '/input/keyboard.html'); + let keyboard = page.keyboard; + await keyboard.hold('Control'); + expect(await page.evaluate(() => getResult())).toBe('Keydown: Control 17 [Control]'); + await keyboard.hold('Meta'); + expect(await page.evaluate(() => getResult())).toBe('Keydown: Meta 91 [Control Meta]'); + await keyboard.hold(';'); + expect(await page.evaluate(() => getResult())).toBe('Keydown: ; 186 [Control Meta]'); + await keyboard.release(';'); + expect(await page.evaluate(() => getResult())).toBe('Keyup: ; 186 [Control Meta]'); + await keyboard.release('Control'); + expect(await page.evaluate(() => getResult())).toBe('Keyup: Control 17 [Meta]'); + await keyboard.release('Meta'); + expect(await page.evaluate(() => getResult())).toBe('Keyup: Meta 91 []'); + })); + it('should send proper codes while typing', SX(async function(){ + await page.navigate(PREFIX + '/input/keyboard.html'); + let keyboard = page.keyboard; + await keyboard.type('!'); + expect(await page.evaluate(() => getResult())).toBe( + [ 'Keydown: ! 49 []', + 'Keypress: ! 33 33 33 []', + 'Keyup: ! 49 []'].join('\n')); + await keyboard.type('^'); + expect(await page.evaluate(() => getResult())).toBe( + [ 'Keydown: ^ 54 []', + 'Keypress: ^ 94 94 94 []', + 'Keyup: ^ 54 []'].join('\n')); + })); + it('should send propery codes while typing with shift', SX(async function(){ + await page.navigate(PREFIX + '/input/keyboard.html'); + let keyboard = page.keyboard; + await keyboard.hold('Shift'); + await keyboard.type('~'); + expect(await page.evaluate(() => getResult())).toBe( + [ 'Keydown: Shift 16 [Shift]', + 'Keydown: ~ 192 [Shift]', // 192 is ` keyCode + 'Keypress: ~ 126 126 126 [Shift]', // 126 is ~ charCode + 'Keyup: ~ 192 [Shift]'].join('\n')); + await keyboard.release('Shift'); + })); + it('should not type canceled events', SX(async function(){ + await page.navigate(PREFIX + '/input/textarea.html'); + await page.focus('textarea'); + await page.evaluate(() => { + window.addEventListener('keydown', event => { + event.stopPropagation(); + event.stopImmediatePropagation(); + if (event.key === 'l') + event.preventDefault(); + if (event.key === 'o') + Promise.resolve().then(() => event.preventDefault()); + }, false); + }); + let keyboard = page.keyboard; + await keyboard.type('Hello World!'); + expect(await page.evaluate(() => textarea.value)).toBe('He Wrd!'); + })); + it('keyboard.modifiers()', SX(async function(){ + let keyboard = page.keyboard; + expect(keyboard.modifiers().Shift).toBe(false); + expect(keyboard.modifiers().Meta).toBe(false); + expect(keyboard.modifiers().Alt).toBe(false); + expect(keyboard.modifiers().Control).toBe(false); + keyboard.hold('Shift'); + expect(keyboard.modifiers().Shift).toBe(true); + expect(keyboard.modifiers().Alt).toBe(false); + keyboard.release('Shift'); + expect(keyboard.modifiers().Shift).toBe(false); + expect(keyboard.modifiers().Alt).toBe(false); + })); }); describe('Page.setUserAgent', function() { it('should work', SX(async function() { diff --git a/third_party/phantomjs/test/module/webpage/keydown-event.js b/third_party/phantomjs/test/module/webpage/keydown-event.js index 12bca8ab0b3..ec9d52edf63 100644 --- a/third_party/phantomjs/test/module/webpage/keydown-event.js +++ b/third_party/phantomjs/test/module/webpage/keydown-event.js @@ -1,4 +1,3 @@ -//! unsupported test(function () { var webpage = require('webpage'); @@ -7,7 +6,7 @@ test(function () { page.evaluate(function() { window.addEventListener('keydown', function(event) { window.loggedEvent = window.loggedEvent || []; - window.loggedEvent.push(event); + window.loggedEvent.push(event.which); }, false); }); @@ -17,5 +16,5 @@ test(function () { }); assert_equals(loggedEvent.length, 1); - assert_equals(loggedEvent[0].which, page.event.key.A); + assert_equals(loggedEvent[0], page.event.key.A); }, "key-down events"); diff --git a/third_party/phantomjs/test/module/webpage/keypress-event.js b/third_party/phantomjs/test/module/webpage/keypress-event.js index e781fdad5a6..b3b86ca77b5 100644 --- a/third_party/phantomjs/test/module/webpage/keypress-event.js +++ b/third_party/phantomjs/test/module/webpage/keypress-event.js @@ -1,4 +1,3 @@ -//! unsupported test(function () { var webpage = require('webpage'); @@ -7,7 +6,7 @@ test(function () { page.evaluate(function() { window.addEventListener('keypress', function(event) { window.loggedEvent = window.loggedEvent || []; - window.loggedEvent.push(event); + window.loggedEvent.push(event.which); }, false); }); @@ -17,7 +16,7 @@ test(function () { }); assert_equals(loggedEvent.length, 1); - assert_equals(loggedEvent[0].which, page.event.key.C); + assert_equals(loggedEvent[0], page.event.key.C); // Send keypress events to an input element and observe the effect. @@ -54,13 +53,15 @@ test(function () { page.sendEvent('keypress', page.event.key.Delete); assert_equals(getText(), ''); + + // Joel: This works, but it causes you to lose your clipboard when running the tests. // Cut and Paste // 0x04000000 is the Control modifier. - page.sendEvent('keypress', 'ABCD'); - assert_equals(getText(), 'ABCD'); - page.sendEvent('keypress', page.event.key.Home, null, null, 0x02000000); - page.sendEvent('keypress', 'x', null, null, 0x04000000); - assert_equals(getText(), ''); - page.sendEvent('keypress', 'v', null, null, 0x04000000); - assert_equals(getText(), 'ABCD'); + // page.sendEvent('keypress', 'ABCD'); + // assert_equals(getText(), 'ABCD'); + // page.sendEvent('keypress', page.event.key.Home, null, null, 0x02000000); + // page.sendEvent('keypress', page.event.key.Cut); + // assert_equals(getText(), ''); + // page.sendEvent('keypress', page.event.key.Paste); + // assert_equals(getText(), 'ABCD'); }, "key press events"); diff --git a/third_party/phantomjs/test/module/webpage/keyup-event.js b/third_party/phantomjs/test/module/webpage/keyup-event.js index c22fe9990ff..383582a6869 100644 --- a/third_party/phantomjs/test/module/webpage/keyup-event.js +++ b/third_party/phantomjs/test/module/webpage/keyup-event.js @@ -1,4 +1,3 @@ -//! unsupported test(function () { var webpage = require('webpage'); @@ -7,7 +6,7 @@ test(function () { page.evaluate(function() { window.addEventListener('keyup', function(event) { window.loggedEvent = window.loggedEvent || []; - window.loggedEvent.push(event); + window.loggedEvent.push(event.which); }, false); }); @@ -17,5 +16,5 @@ test(function () { }); assert_equals(loggedEvent.length, 1); - assert_equals(loggedEvent[0].which, page.event.key.B); + assert_equals(loggedEvent[0], page.event.key.B); }, "key-up events"); diff --git a/utils/doclint/lint.js b/utils/doclint/lint.js index c75984cb762..643f3675499 100644 --- a/utils/doclint/lint.js +++ b/utils/doclint/lint.js @@ -27,6 +27,7 @@ let EXCLUDE_METHODS = new Set([ 'Page.create', 'Request.constructor', 'Response.constructor', + 'Keyboard.constructor', ]); /**