From 2b2e84971fe13f1a0cd65873c8b433eafcd73c8a Mon Sep 17 00:00:00 2001 From: Yury Semikhatsky Date: Mon, 13 Jan 2025 17:22:00 -0800 Subject: [PATCH] chore(bidi): use original key name when computing bidi value (#34317) --- .../playwright-core/src/server/bidi/bidiInput.ts | 9 ++++----- .../src/server/bidi/third_party/bidiKeyboard.ts | 14 +++++++------- .../playwright-core/src/server/chromium/crInput.ts | 10 ++++++---- .../playwright-core/src/server/firefox/ffInput.ts | 11 +++++++---- packages/playwright-core/src/server/input.ts | 11 +++++------ .../playwright-core/src/server/webkit/wkInput.ts | 12 +++++++----- 6 files changed, 36 insertions(+), 31 deletions(-) diff --git a/packages/playwright-core/src/server/bidi/bidiInput.ts b/packages/playwright-core/src/server/bidi/bidiInput.ts index 01b773178d..e149bb4a3f 100644 --- a/packages/playwright-core/src/server/bidi/bidiInput.ts +++ b/packages/playwright-core/src/server/bidi/bidiInput.ts @@ -31,16 +31,15 @@ export class RawKeyboardImpl implements input.RawKeyboard { this._session = session; } - async keydown(modifiers: Set, code: string, keyCode: number, keyCodeWithoutLocation: number, key: string, location: number, autoRepeat: boolean, text: string | undefined): Promise { + async keydown(modifiers: Set, keyName: string, description: input.KeyDescription, autoRepeat: boolean): Promise { const actions: bidi.Input.KeySourceAction[] = []; - actions.push({ type: 'keyDown', value: getBidiKeyValue(code) }); - // TODO: add modifiers? + actions.push({ type: 'keyDown', value: getBidiKeyValue(keyName) }); await this._performActions(actions); } - async keyup(modifiers: Set, code: string, keyCode: number, keyCodeWithoutLocation: number, key: string, location: number): Promise { + async keyup(modifiers: Set, keyName: string, description: input.KeyDescription): Promise { const actions: bidi.Input.KeySourceAction[] = []; - actions.push({ type: 'keyUp', value: getBidiKeyValue(code) }); + actions.push({ type: 'keyUp', value: getBidiKeyValue(keyName) }); await this._performActions(actions); } diff --git a/packages/playwright-core/src/server/bidi/third_party/bidiKeyboard.ts b/packages/playwright-core/src/server/bidi/third_party/bidiKeyboard.ts index c2d60ff66b..611135e2c8 100644 --- a/packages/playwright-core/src/server/bidi/third_party/bidiKeyboard.ts +++ b/packages/playwright-core/src/server/bidi/third_party/bidiKeyboard.ts @@ -7,18 +7,18 @@ /* eslint-disable curly */ -export const getBidiKeyValue = (code: string) => { - switch (code) { +export const getBidiKeyValue = (keyName: string) => { + switch (keyName) { case '\r': case '\n': - code = 'Enter'; + keyName = 'Enter'; break; } // Measures the number of code points rather than UTF-16 code units. - if ([...code].length === 1) { - return code; + if ([...keyName].length === 1) { + return keyName; } - switch (code) { + switch (keyName) { case 'Cancel': return '\uE001'; case 'Help': @@ -228,6 +228,6 @@ export const getBidiKeyValue = (code: string) => { case 'Quote': return '"'; default: - throw new Error(`Unknown key: "${code}"`); + throw new Error(`Unknown key: "${keyName}"`); } }; diff --git a/packages/playwright-core/src/server/chromium/crInput.ts b/packages/playwright-core/src/server/chromium/crInput.ts index bbfd973d10..e08f3b0233 100644 --- a/packages/playwright-core/src/server/chromium/crInput.ts +++ b/packages/playwright-core/src/server/chromium/crInput.ts @@ -50,14 +50,15 @@ export class RawKeyboardImpl implements input.RawKeyboard { return commands.map(c => c.substring(0, c.length - 1)); } - async keydown(modifiers: Set, code: string, keyCode: number, keyCodeWithoutLocation: number, key: string, location: number, autoRepeat: boolean, text: string | undefined): Promise { + async keydown(modifiers: Set, keyName: string, description: input.KeyDescription, autoRepeat: boolean): Promise { + const { code, key, location, text } = description; if (code === 'Escape' && await this._dragManger.cancelDrag()) return; const commands = this._commandsForCode(code, modifiers); await this._client.send('Input.dispatchKeyEvent', { type: text ? 'keyDown' : 'rawKeyDown', modifiers: toModifiersMask(modifiers), - windowsVirtualKeyCode: keyCodeWithoutLocation, + windowsVirtualKeyCode: description.keyCodeWithoutLocation, code, commands, key, @@ -69,12 +70,13 @@ export class RawKeyboardImpl implements input.RawKeyboard { }); } - async keyup(modifiers: Set, code: string, keyCode: number, keyCodeWithoutLocation: number, key: string, location: number): Promise { + async keyup(modifiers: Set, keyName: string, description: input.KeyDescription): Promise { + const { code, key, location } = description; await this._client.send('Input.dispatchKeyEvent', { type: 'keyUp', modifiers: toModifiersMask(modifiers), key, - windowsVirtualKeyCode: keyCodeWithoutLocation, + windowsVirtualKeyCode: description.keyCodeWithoutLocation, code, location }); diff --git a/packages/playwright-core/src/server/firefox/ffInput.ts b/packages/playwright-core/src/server/firefox/ffInput.ts index 66f35399a5..42d2c71ebf 100644 --- a/packages/playwright-core/src/server/firefox/ffInput.ts +++ b/packages/playwright-core/src/server/firefox/ffInput.ts @@ -61,13 +61,15 @@ export class RawKeyboardImpl implements input.RawKeyboard { this._client = client; } - async keydown(modifiers: Set, code: string, keyCode: number, keyCodeWithoutLocation: number, key: string, location: number, autoRepeat: boolean, text: string | undefined): Promise { + async keydown(modifiers: Set, keyName: string, description: input.KeyDescription, autoRepeat: boolean): Promise { + let text = description.text; // Firefox will figure out Enter by itself if (text === '\r') text = ''; + const { code, key, location } = description; await this._client.send('Page.dispatchKeyEvent', { type: 'keydown', - keyCode: keyCodeWithoutLocation, + keyCode: description.keyCodeWithoutLocation, code, key, repeat: autoRepeat, @@ -76,11 +78,12 @@ export class RawKeyboardImpl implements input.RawKeyboard { }); } - async keyup(modifiers: Set, code: string, keyCode: number, keyCodeWithoutLocation: number, key: string, location: number): Promise { + async keyup(modifiers: Set, keyName: string, description: input.KeyDescription): Promise { + const { code, key, location } = description; await this._client.send('Page.dispatchKeyEvent', { type: 'keyup', key, - keyCode: keyCodeWithoutLocation, + keyCode: description.keyCodeWithoutLocation, code, location, repeat: false diff --git a/packages/playwright-core/src/server/input.ts b/packages/playwright-core/src/server/input.ts index 4e4c95a8f3..f8beb789f8 100644 --- a/packages/playwright-core/src/server/input.ts +++ b/packages/playwright-core/src/server/input.ts @@ -22,7 +22,7 @@ import type { CallMetadata } from './instrumentation'; export const keypadLocation = keyboardLayout.keypadLocation; -type KeyDescription = { +export type KeyDescription = { keyCode: number, keyCodeWithoutLocation: number, key: string, @@ -35,8 +35,8 @@ type KeyDescription = { const kModifiers: types.KeyboardModifier[] = ['Alt', 'Control', 'Meta', 'Shift']; export interface RawKeyboard { - keydown(modifiers: Set, code: string, keyCode: number, keyCodeWithoutLocation: number, key: string, location: number, autoRepeat: boolean, text: string | undefined): Promise; - keyup(modifiers: Set, code: string, keyCode: number, keyCodeWithoutLocation: number, key: string, location: number): Promise; + keydown(modifiers: Set, keyName: string, description: KeyDescription, autoRepeat: boolean): Promise; + keyup(modifiers: Set, keyName: string, description: KeyDescription): Promise; sendText(text: string): Promise; } @@ -55,8 +55,7 @@ export class Keyboard { this._pressedKeys.add(description.code); if (kModifiers.includes(description.key as types.KeyboardModifier)) this._pressedModifiers.add(description.key as types.KeyboardModifier); - const text = description.text; - await this._raw.keydown(this._pressedModifiers, description.code, description.keyCode, description.keyCodeWithoutLocation, description.key, description.location, autoRepeat, text); + await this._raw.keydown(this._pressedModifiers, key, description, autoRepeat); } private _keyDescriptionForString(str: string): KeyDescription { @@ -77,7 +76,7 @@ export class Keyboard { if (kModifiers.includes(description.key as types.KeyboardModifier)) this._pressedModifiers.delete(description.key as types.KeyboardModifier); this._pressedKeys.delete(description.code); - await this._raw.keyup(this._pressedModifiers, description.code, description.keyCode, description.keyCodeWithoutLocation, description.key, description.location); + await this._raw.keyup(this._pressedModifiers, key, description); } async insertText(text: string) { diff --git a/packages/playwright-core/src/server/webkit/wkInput.ts b/packages/playwright-core/src/server/webkit/wkInput.ts index 0732f246d1..5769fd6465 100644 --- a/packages/playwright-core/src/server/webkit/wkInput.ts +++ b/packages/playwright-core/src/server/webkit/wkInput.ts @@ -59,12 +59,13 @@ export class RawKeyboardImpl implements input.RawKeyboard { this._session = session; } - async keydown(modifiers: Set, code: string, keyCode: number, keyCodeWithoutLocation: number, key: string, location: number, autoRepeat: boolean, text: string | undefined): Promise { + async keydown(modifiers: Set, keyName: string, description: input.KeyDescription, autoRepeat: boolean): Promise { const parts = []; for (const modifier of (['Shift', 'Control', 'Alt', 'Meta']) as types.KeyboardModifier[]) { if (modifiers.has(modifier)) parts.push(modifier); } + const { code, keyCode, key, text } = description; parts.push(code); const shortcut = parts.join('+'); let commands = macEditingCommands[shortcut]; @@ -80,18 +81,19 @@ export class RawKeyboardImpl implements input.RawKeyboard { unmodifiedText: text, autoRepeat, macCommands: commands, - isKeypad: location === input.keypadLocation + isKeypad: description.location === input.keypadLocation }); } - async keyup(modifiers: Set, code: string, keyCode: number, keyCodeWithoutLocation: number, key: string, location: number): Promise { + async keyup(modifiers: Set, keyName: string, description: input.KeyDescription): Promise { + const { code, key } = description; await this._pageProxySession.send('Input.dispatchKeyEvent', { type: 'keyUp', modifiers: toModifiersMask(modifiers), key, - windowsVirtualKeyCode: keyCode, + windowsVirtualKeyCode: description.keyCode, code, - isKeypad: location === input.keypadLocation + isKeypad: description.location === input.keypadLocation }); }