Skip to content

Instantly share code, notes, and snippets.

@WestonThayer
Last active September 18, 2023 16:24
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save WestonThayer/da07c2dc6f4bb9447187fdbdfb4fff07 to your computer and use it in GitHub Desktop.
Save WestonThayer/da07c2dc6f4bb9447187fdbdfb4fff07 to your computer and use it in GitHub Desktop.
// https://github.com/microsoft/playwright/issues/27130
/**
* Turn a single string character into KeyboardEvent.code and whether a Shift
* modifier is required.
*
* I have no idea how this works if your local keyboard layout isn't US.
*
* @param {string} char
*
* @returns {{ code: string; shift?: boolean }}
*/
const printableCharToKeyCode = (char) => {
const charCode = char.charCodeAt(0);
if (charCode >= 0x41 && charCode <= 0x5a) {
// A-Z
return { shift: true, code: `Key${char}` };
} else if (charCode >= 0x61 && charCode <= 0x7a) {
// a-z
return { code: `Key${char.toUpperCase()}` };
} else if (charCode >= 0x30 && charCode <= 0x39) {
// 0-9
return { code: `Digit${char}` };
} else {
switch (char) {
case " ":
return { code: "Space" };
// Special chars, US keyboard top left to bottom right without SHIFT
case "`":
return { code: "Backquote" };
case "-":
return { code: "Minus" };
case "=":
return { code: "Equal" };
case "[":
return { code: "BracketLeft" };
case "]":
return { code: "BracketRight" };
case "\\":
return { code: "Backslash" };
case ";":
return { code: "Semicolon" };
case "'":
return { code: "Quote" };
case ",":
return { code: "Comma" };
case ".":
return { code: "Period" };
case "/":
return { code: "Slash" };
// Special chars, US keyboard top left to bottom right with SHIFT
case "~":
return { code: "Backquote", shift: true };
case "!":
return { code: "Digit1", shift: true };
case "@":
return { code: "Digit2", shift: true };
case "#":
return { code: "Digit3", shift: true };
case "$":
return { code: "Digit4", shift: true };
case "%":
return { code: "Digit5", shift: true };
case "^":
return { code: "Digit6", shift: true };
case "&":
return { code: "Digit7", shift: true };
case "*":
return { code: "Digit8", shift: true };
case "(":
return { code: "Digit9", shift: true };
case ")":
return { code: "Digit0", shift: true };
case "_":
return { code: "Minus", shift: true };
case "+":
return { code: "Equal", shift: true };
case "{":
return { code: "BracketLeft", shift: true };
case "}":
return { code: "BracketRight", shift: true };
case "|":
return { code: "Backslash", shift: true };
case ":":
return { code: "Semicolon", shift: true };
case '"':
return { code: "Quote", shift: true };
case "<":
return { code: "Comma", shift: true };
case ">":
return { code: "Period", shift: true };
case "?":
return { code: "Slash", shift: true };
}
}
throw new Error(`Couldn't process ${char}`);
};
/**
* @param {{ press: (text: string) => Promise<void> }} keyboard
* @param {string} text
* @returns {Promise<void>}
*/
const tryType = async (keyboard, text) => {
for (const char of text) {
const key = printableCharToKeyCode(char);
await keyboard.press(`${key.shift ? "Shift+" : ""}${key.code}`);
}
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment