fix(input) Send .code with keyboard events (#1015)
This patch starts sending proper `.code` field with emulated keyboard events. References #777.
This commit is contained in:
parent
23c0ba0727
commit
c893bf3684
293
lib/Input.js
293
lib/Input.js
@ -38,7 +38,8 @@ class Keyboard {
|
||||
await this._client.send('Input.dispatchKeyEvent', {
|
||||
type: text ? 'keyDown' : 'rawKeyDown',
|
||||
modifiers: this._modifiers,
|
||||
windowsVirtualKeyCode: codeForKey(key),
|
||||
windowsVirtualKeyCode: keyCodeForKey(key),
|
||||
code: codeForKey(key),
|
||||
key,
|
||||
text,
|
||||
unmodifiedText: text,
|
||||
@ -72,7 +73,8 @@ class Keyboard {
|
||||
type: 'keyUp',
|
||||
modifiers: this._modifiers,
|
||||
key,
|
||||
windowsVirtualKeyCode: codeForKey(key),
|
||||
windowsVirtualKeyCode: keyCodeForKey(key),
|
||||
code: codeForKey(key)
|
||||
});
|
||||
}
|
||||
|
||||
@ -224,125 +226,200 @@ class Touchscreen {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @type {Object<string, {keyCode: number, code: string}>}
|
||||
*/
|
||||
const 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,
|
||||
'AudioVolumeMute': 173,
|
||||
'AudioVolumeDown': 174,
|
||||
'AudioVolumeUp': 175,
|
||||
'MediaTrackNext': 176,
|
||||
'MediaTrackPrevious': 177,
|
||||
'MediaStop': 178,
|
||||
'MediaPlayPause': 179,
|
||||
';': 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
|
||||
'Cancel': {keyCode: 3, code: 'Abort'},
|
||||
'Help': {keyCode: 6, code: 'Help'},
|
||||
'Backspace': {keyCode: 8, code: 'Backspace'},
|
||||
'Tab': {keyCode: 9, code: 'Tab'},
|
||||
'Clear': {keyCode: 12, code: ''},
|
||||
'Enter': {keyCode: 13, code: 'Enter'},
|
||||
'Shift': {keyCode: 16, code: 'ShiftLeft'},
|
||||
'Control': {keyCode: 17, code: 'ControlLeft'},
|
||||
'Alt': {keyCode: 18, code: 'AltLeft'},
|
||||
'Pause': {keyCode: 19, code: 'Pause'},
|
||||
'CapsLock': {keyCode: 20, code: 'CapsLock'},
|
||||
'Escape': {keyCode: 27, code: 'Escape'},
|
||||
'Convert': {keyCode: 28, code: 'Convert'},
|
||||
'NonConvert': {keyCode: 29, code: 'NonConvert'},
|
||||
'Accept': {keyCode: 30, code: ''},
|
||||
'ModeChange': {keyCode: 31, code: ''},
|
||||
'PageUp': {keyCode: 33, code: 'PageUp'},
|
||||
'PageDown': {keyCode: 34, code: 'PageDown'},
|
||||
'End': {keyCode: 35, code: 'End'},
|
||||
'Home': {keyCode: 36, code: 'Home'},
|
||||
'ArrowLeft': {keyCode: 37, code: 'ArrowLeft'},
|
||||
'ArrowUp': {keyCode: 38, code: 'ArrowUp'},
|
||||
'ArrowRight': {keyCode: 39, code: 'ArrowRight'},
|
||||
'ArrowDown': {keyCode: 40, code: 'ArrowDown'},
|
||||
'Select': {keyCode: 41, code: 'Select'},
|
||||
'Print': {keyCode: 42, code: ''},
|
||||
'Execute': {keyCode: 43, code: 'Open'},
|
||||
'PrintScreen': {keyCode: 44, code: 'PrintScreen'},
|
||||
'Insert': {keyCode: 45, code: 'Insert'},
|
||||
'Delete': {keyCode: 46, code: 'Delete'},
|
||||
')': {keyCode: 48, code: 'Digit0'},
|
||||
'!': {keyCode: 49, code: 'Digit1'},
|
||||
'@': {keyCode: 50, code: 'Digit2'},
|
||||
'#': {keyCode: 51, code: 'Digit3'},
|
||||
'$': {keyCode: 52, code: 'Digit4'},
|
||||
'%': {keyCode: 53, code: 'Digit5'},
|
||||
'^': {keyCode: 54, code: 'Digit6'},
|
||||
'&': {keyCode: 55, code: 'Digit7'},
|
||||
'*': {keyCode: 56, code: 'Digit8'},
|
||||
'(': {keyCode: 57, code: 'Digit9'},
|
||||
'Meta': {keyCode: 91, code: 'MetaLeft'},
|
||||
'ContextMenu': {keyCode: 93, code: 'ContextMenu'},
|
||||
'F1': {keyCode: 112, code: 'F1'},
|
||||
'F2': {keyCode: 113, code: 'F2'},
|
||||
'F3': {keyCode: 114, code: 'F3'},
|
||||
'F4': {keyCode: 115, code: 'F4'},
|
||||
'F5': {keyCode: 116, code: 'F5'},
|
||||
'F6': {keyCode: 117, code: 'F6'},
|
||||
'F7': {keyCode: 118, code: 'F7'},
|
||||
'F8': {keyCode: 119, code: 'F8'},
|
||||
'F9': {keyCode: 120, code: 'F9'},
|
||||
'F10': {keyCode: 121, code: 'F10'},
|
||||
'F11': {keyCode: 122, code: 'F11'},
|
||||
'F12': {keyCode: 123, code: 'F12'},
|
||||
'F13': {keyCode: 124, code: 'F13'},
|
||||
'F14': {keyCode: 125, code: 'F14'},
|
||||
'F15': {keyCode: 126, code: 'F15'},
|
||||
'F16': {keyCode: 127, code: 'F16'},
|
||||
'F17': {keyCode: 128, code: 'F17'},
|
||||
'F18': {keyCode: 129, code: 'F18'},
|
||||
'F19': {keyCode: 130, code: 'F19'},
|
||||
'F20': {keyCode: 131, code: 'F20'},
|
||||
'F21': {keyCode: 132, code: 'F21'},
|
||||
'F22': {keyCode: 133, code: 'F22'},
|
||||
'F23': {keyCode: 134, code: 'F23'},
|
||||
'F24': {keyCode: 135, code: 'F24'},
|
||||
'NumLock': {keyCode: 144, code: 'NumLock'},
|
||||
'ScrollLock': {keyCode: 145, code: 'ScrollLock'},
|
||||
'AudioVolumeMute': {keyCode: 173, code: 'AudioVolumeMute'},
|
||||
'AudioVolumeDown': {keyCode: 174, code: 'AudioVolumeDown'},
|
||||
'AudioVolumeUp': {keyCode: 175, code: 'AudioVolumeUp'},
|
||||
'MediaTrackNext': {keyCode: 176, code: 'MediaTrackNext'},
|
||||
'MediaTrackPrevious': {keyCode: 177, code: 'MediaTrackPrevious'},
|
||||
'MediaStop': {keyCode: 178, code: 'MediaStop'},
|
||||
'MediaPlayPause': {keyCode: 179, code: 'MediaPlayPause'},
|
||||
';': {keyCode: 186, code: 'Semicolon'},
|
||||
':': {keyCode: 186, code: 'Semicolon'},
|
||||
'=': {keyCode: 187, code: 'Equal'},
|
||||
'+': {keyCode: 187, code: 'Equal'},
|
||||
',': {keyCode: 188, code: 'Comma'},
|
||||
'<': {keyCode: 188, code: 'Comma'},
|
||||
'-': {keyCode: 189, code: 'Minus'},
|
||||
'_': {keyCode: 189, code: 'Minus'},
|
||||
'.': {keyCode: 190, code: 'Period'},
|
||||
'>': {keyCode: 190, code: 'Period'},
|
||||
'/': {keyCode: 191, code: 'Slash'},
|
||||
'?': {keyCode: 191, code: 'Slash'},
|
||||
'`': {keyCode: 192, code: 'Backquote'},
|
||||
'~': {keyCode: 192, code: 'Backquote'},
|
||||
'[': {keyCode: 219, code: 'BracketLeft'},
|
||||
'{': {keyCode: 219, code: 'BracketLeft'},
|
||||
'\\': {keyCode: 220, code: 'Backslash'},
|
||||
'|': {keyCode: 220, code: 'Backslash'},
|
||||
']': {keyCode: 221, code: 'BracketRight'},
|
||||
'}': {keyCode: 221, code: 'BracketRight'},
|
||||
'\'': {keyCode: 222, code: 'Quote'},
|
||||
'"': {keyCode: 222, code: 'Quote'},
|
||||
'AltGraph': {keyCode: 225, code: 'AltGraph'},
|
||||
'Attn': {keyCode: 246, code: ''},
|
||||
'CrSel': {keyCode: 247, code: 'Props'},
|
||||
'ExSel': {keyCode: 248, code: ''},
|
||||
'EraseEof': {keyCode: 249, code: ''},
|
||||
'Play': {keyCode: 250, code: ''},
|
||||
'ZoomOut': {keyCode: 251, code: ''},
|
||||
'0': { keyCode: 48, code: 'Digit0'},
|
||||
'1': { keyCode: 49, code: 'Digit1'},
|
||||
'2': { keyCode: 50, code: 'Digit2'},
|
||||
'3': { keyCode: 51, code: 'Digit3'},
|
||||
'4': { keyCode: 52, code: 'Digit4'},
|
||||
'5': { keyCode: 53, code: 'Digit5'},
|
||||
'6': { keyCode: 54, code: 'Digit6'},
|
||||
'7': { keyCode: 55, code: 'Digit7'},
|
||||
'8': { keyCode: 56, code: 'Digit8'},
|
||||
'9': { keyCode: 57, code: 'Digit9'},
|
||||
'q': { keyCode: 81, code: 'KeyQ'},
|
||||
'w': { keyCode: 87, code: 'KeyW'},
|
||||
'e': { keyCode: 69, code: 'KeyE'},
|
||||
'r': { keyCode: 82, code: 'KeyR'},
|
||||
't': { keyCode: 84, code: 'KeyT'},
|
||||
'y': { keyCode: 89, code: 'KeyY'},
|
||||
'u': { keyCode: 85, code: 'KeyU'},
|
||||
'i': { keyCode: 73, code: 'KeyI'},
|
||||
'o': { keyCode: 79, code: 'KeyO'},
|
||||
'p': { keyCode: 80, code: 'KeyP'},
|
||||
'a': { keyCode: 65, code: 'KeyA'},
|
||||
's': { keyCode: 83, code: 'KeyS'},
|
||||
'd': { keyCode: 68, code: 'KeyD'},
|
||||
'f': { keyCode: 70, code: 'KeyF'},
|
||||
'g': { keyCode: 71, code: 'KeyG'},
|
||||
'h': { keyCode: 72, code: 'KeyH'},
|
||||
'j': { keyCode: 74, code: 'KeyJ'},
|
||||
'k': { keyCode: 75, code: 'KeyK'},
|
||||
'l': { keyCode: 76, code: 'KeyL'},
|
||||
'z': { keyCode: 90, code: 'KeyZ'},
|
||||
'x': { keyCode: 88, code: 'KeyX'},
|
||||
'c': { keyCode: 67, code: 'KeyC'},
|
||||
'v': { keyCode: 86, code: 'KeyV'},
|
||||
'b': { keyCode: 66, code: 'KeyB'},
|
||||
'n': { keyCode: 78, code: 'KeyN'},
|
||||
'm': { keyCode: 77, code: 'KeyM'},
|
||||
'Q': { keyCode: 81, code: 'KeyQ'},
|
||||
'W': { keyCode: 87, code: 'KeyW'},
|
||||
'E': { keyCode: 69, code: 'KeyE'},
|
||||
'R': { keyCode: 82, code: 'KeyR'},
|
||||
'T': { keyCode: 84, code: 'KeyT'},
|
||||
'Y': { keyCode: 89, code: 'KeyY'},
|
||||
'U': { keyCode: 85, code: 'KeyU'},
|
||||
'I': { keyCode: 73, code: 'KeyI'},
|
||||
'O': { keyCode: 79, code: 'KeyO'},
|
||||
'P': { keyCode: 80, code: 'KeyP'},
|
||||
'A': { keyCode: 65, code: 'KeyA'},
|
||||
'S': { keyCode: 83, code: 'KeyS'},
|
||||
'D': { keyCode: 68, code: 'KeyD'},
|
||||
'F': { keyCode: 70, code: 'KeyF'},
|
||||
'G': { keyCode: 71, code: 'KeyG'},
|
||||
'H': { keyCode: 72, code: 'KeyH'},
|
||||
'J': { keyCode: 74, code: 'KeyJ'},
|
||||
'K': { keyCode: 75, code: 'KeyK'},
|
||||
'L': { keyCode: 76, code: 'KeyL'},
|
||||
'Z': { keyCode: 90, code: 'KeyZ'},
|
||||
'X': { keyCode: 88, code: 'KeyX'},
|
||||
'C': { keyCode: 67, code: 'KeyC'},
|
||||
'V': { keyCode: 86, code: 'KeyV'},
|
||||
'B': { keyCode: 66, code: 'KeyB'},
|
||||
'N': { keyCode: 78, code: 'KeyN'},
|
||||
'M': { keyCode: 77, code: 'KeyM'}
|
||||
};
|
||||
|
||||
/**
|
||||
* @param {string} key
|
||||
* @return {number}
|
||||
*/
|
||||
function codeForKey(key) {
|
||||
function keyCodeForKey(key) {
|
||||
if (keys[key])
|
||||
return keys[key];
|
||||
return keys[key].keyCode;
|
||||
if (key.length === 1)
|
||||
return key.toUpperCase().charCodeAt(0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} key
|
||||
* @return {string}
|
||||
*/
|
||||
function codeForKey(key) {
|
||||
if (!keys[key])
|
||||
return '';
|
||||
return keys[key].code;
|
||||
}
|
||||
|
||||
module.exports = { Keyboard, Mouse, Touchscreen};
|
||||
helper.tracePublicAPI(Keyboard);
|
||||
helper.tracePublicAPI(Mouse);
|
||||
|
@ -10,13 +10,13 @@
|
||||
let textarea = document.querySelector('textarea');
|
||||
textarea.focus();
|
||||
textarea.addEventListener('keydown', event => {
|
||||
log('Keydown:', event.key, event.which, modifiers(event));
|
||||
log('Keydown:', event.key, event.code, event.which, modifiers(event));
|
||||
});
|
||||
textarea.addEventListener('keypress', event => {
|
||||
log('Keypress:', event.key, event.which, event.keyCode, event.charCode, modifiers(event));
|
||||
log('Keypress:', event.key, event.code, event.which, event.keyCode, event.charCode, modifiers(event));
|
||||
});
|
||||
textarea.addEventListener('keyup', event => {
|
||||
log('Keyup:', event.key, event.which, modifiers(event));
|
||||
log('Keyup:', event.key, event.code, event.which, modifiers(event));
|
||||
});
|
||||
function modifiers(event) {
|
||||
let m = [];
|
||||
|
40
test/test.js
40
test/test.js
@ -1607,43 +1607,43 @@ describe('Page', function() {
|
||||
const codeForKey = {'Shift': 16, 'Alt': 18, 'Meta': 91, 'Control': 17};
|
||||
for (const modifierKey in codeForKey) {
|
||||
await keyboard.down(modifierKey);
|
||||
expect(await page.evaluate(() => getResult())).toBe('Keydown: ' + modifierKey + ' ' + codeForKey[modifierKey] + ' [' + modifierKey + ']');
|
||||
expect(await page.evaluate(() => getResult())).toBe('Keydown: ' + modifierKey + ' ' + modifierKey + 'Left ' + codeForKey[modifierKey] + ' [' + modifierKey + ']');
|
||||
await keyboard.down('!');
|
||||
expect(await page.evaluate(() => getResult())).toBe('Keydown: ! 49 [' + modifierKey + ']');
|
||||
expect(await page.evaluate(() => getResult())).toBe('Keydown: ! Digit1 49 [' + modifierKey + ']');
|
||||
await keyboard.up('!');
|
||||
expect(await page.evaluate(() => getResult())).toBe('Keyup: ! 49 [' + modifierKey + ']');
|
||||
expect(await page.evaluate(() => getResult())).toBe('Keyup: ! Digit1 49 [' + modifierKey + ']');
|
||||
await keyboard.up(modifierKey);
|
||||
expect(await page.evaluate(() => getResult())).toBe('Keyup: ' + modifierKey + ' ' + codeForKey[modifierKey] + ' []');
|
||||
expect(await page.evaluate(() => getResult())).toBe('Keyup: ' + modifierKey + ' ' + modifierKey + 'Left ' + codeForKey[modifierKey] + ' []');
|
||||
}
|
||||
}));
|
||||
it('should report multiple modifiers', SX(async function(){
|
||||
await page.goto(PREFIX + '/input/keyboard.html');
|
||||
const keyboard = page.keyboard;
|
||||
await keyboard.down('Control');
|
||||
expect(await page.evaluate(() => getResult())).toBe('Keydown: Control 17 [Control]');
|
||||
expect(await page.evaluate(() => getResult())).toBe('Keydown: Control ControlLeft 17 [Control]');
|
||||
await keyboard.down('Meta');
|
||||
expect(await page.evaluate(() => getResult())).toBe('Keydown: Meta 91 [Control Meta]');
|
||||
expect(await page.evaluate(() => getResult())).toBe('Keydown: Meta MetaLeft 91 [Control Meta]');
|
||||
await keyboard.down(';');
|
||||
expect(await page.evaluate(() => getResult())).toBe('Keydown: ; 186 [Control Meta]');
|
||||
expect(await page.evaluate(() => getResult())).toBe('Keydown: ; Semicolon 186 [Control Meta]');
|
||||
await keyboard.up(';');
|
||||
expect(await page.evaluate(() => getResult())).toBe('Keyup: ; 186 [Control Meta]');
|
||||
expect(await page.evaluate(() => getResult())).toBe('Keyup: ; Semicolon 186 [Control Meta]');
|
||||
await keyboard.up('Control');
|
||||
expect(await page.evaluate(() => getResult())).toBe('Keyup: Control 17 [Meta]');
|
||||
expect(await page.evaluate(() => getResult())).toBe('Keyup: Control ControlLeft 17 [Meta]');
|
||||
await keyboard.up('Meta');
|
||||
expect(await page.evaluate(() => getResult())).toBe('Keyup: Meta 91 []');
|
||||
expect(await page.evaluate(() => getResult())).toBe('Keyup: Meta MetaLeft 91 []');
|
||||
}));
|
||||
it('should send proper codes while typing', SX(async function(){
|
||||
await page.goto(PREFIX + '/input/keyboard.html');
|
||||
await page.keyboard.type('!');
|
||||
expect(await page.evaluate(() => getResult())).toBe(
|
||||
[ 'Keydown: ! 49 []',
|
||||
'Keypress: ! 33 33 33 []',
|
||||
'Keyup: ! 49 []'].join('\n'));
|
||||
[ 'Keydown: ! Digit1 49 []',
|
||||
'Keypress: ! Digit1 33 33 33 []',
|
||||
'Keyup: ! Digit1 49 []'].join('\n'));
|
||||
await page.keyboard.type('^');
|
||||
expect(await page.evaluate(() => getResult())).toBe(
|
||||
[ 'Keydown: ^ 54 []',
|
||||
'Keypress: ^ 94 94 94 []',
|
||||
'Keyup: ^ 54 []'].join('\n'));
|
||||
[ 'Keydown: ^ Digit6 54 []',
|
||||
'Keypress: ^ Digit6 94 94 94 []',
|
||||
'Keyup: ^ Digit6 54 []'].join('\n'));
|
||||
}));
|
||||
it('should send proper codes while typing with shift', SX(async function(){
|
||||
await page.goto(PREFIX + '/input/keyboard.html');
|
||||
@ -1651,10 +1651,10 @@ describe('Page', function() {
|
||||
await keyboard.down('Shift');
|
||||
await page.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'));
|
||||
[ 'Keydown: Shift ShiftLeft 16 [Shift]',
|
||||
'Keydown: ~ Backquote 192 [Shift]', // 192 is ` keyCode
|
||||
'Keypress: ~ Backquote 126 126 126 [Shift]', // 126 is ~ charCode
|
||||
'Keyup: ~ Backquote 192 [Shift]'].join('\n'));
|
||||
await keyboard.up('Shift');
|
||||
}));
|
||||
it('should not type canceled events', SX(async function(){
|
||||
|
Loading…
Reference in New Issue
Block a user