diff --git a/lib/Input.js b/lib/Input.js index b14992bfef0..1e6cfb9bcf7 100644 --- a/lib/Input.js +++ b/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} + */ 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); diff --git a/test/assets/input/keyboard.html b/test/assets/input/keyboard.html index 539c327bcac..00df1034610 100644 --- a/test/assets/input/keyboard.html +++ b/test/assets/input/keyboard.html @@ -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 = []; diff --git a/test/test.js b/test/test.js index a7e1e294611..e556fdf72e1 100644 --- a/test/test.js +++ b/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(){