Intorduce Page.keyboard (#74)

Introduce page.keyboard to provide low-level access to the keyboard.
This commit is contained in:
JoelEinbinder 2017-07-17 18:49:52 -07:00 committed by Andrey Lushnikov
parent 895f69d17a
commit bf7698e8f8
11 changed files with 576 additions and 38 deletions

1
.gitignore vendored
View File

@ -5,3 +5,4 @@
.DS_Store
*.swp
*.pyc
.vscode

View File

@ -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"

238
lib/Keyboard.js Normal file
View File

@ -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<string>} */
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;

View File

@ -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<string, function>} */
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<!Frame>}
*/
@ -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);
}
/**

View File

@ -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

View File

@ -0,0 +1,44 @@
<!DOCTYPE html>
<html>
<head>
<title>Keyboard test</title>
</head>
<body>
<textarea></textarea>
<script>
window.result = "";
let textarea = document.querySelector('textarea');
textarea.focus();
textarea.addEventListener('keydown', event => {
log('Keydown:', event.key, event.which, modifiers(event));
});
textarea.addEventListener('keypress', event => {
log('Keypress:', event.key, event.which, event.keyCode, event.charCode, modifiers(event));
});
textarea.addEventListener('keyup', event => {
log('Keyup:', event.key, event.which, modifiers(event));
});
function modifiers(event) {
let m = [];
if (event.altKey)
m.push('Alt')
if (event.ctrlKey)
m.push('Control');
if (event.metaKey)
m.push('Meta')
if (event.shiftKey)
m.push('Shift')
return '[' + m.join(' ') + ']';
}
function log(...args) {
console.log.apply(console, args);
result += args.join(' ') + '\n';
}
function getResult() {
let temp = result.trim();
result = "";
return temp;
}
</script>
</body>
</html>

View File

@ -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() {

View File

@ -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");

View File

@ -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");

View File

@ -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");

View File

@ -27,6 +27,7 @@ let EXCLUDE_METHODS = new Set([
'Page.create',
'Request.constructor',
'Response.constructor',
'Keyboard.constructor',
]);
/**