Keyboard Test Guide
A reference for the desktest.net Keyboard Test. Covers how the visual keymap reads input, how to read the verdict, and what to do about stuck keys, missing keys, and dead modifier combos.
What does the Keyboard Test check?
The tool drives the browser's standard KeyboardEvent API: capture-mode keydown and keyup listeners attached at the document level, keyed off KeyboardEvent.code so the physical key position stays stable across QWERTY, AZERTY, and Dvorak. No plugin, no extension, no upload. Works on Chrome, Edge, Firefox, and Safari. The three steps run in order; each must pass before the next:
- Keyboard event API fires. Feature-detects
window.KeyboardEvent, confirmscodeandkeyproperties are present, and attaches a passive watch so any real keystroke during the run gets counted. Also notes whether the page is loaded inside an iframe (some embedded shells swallow keys). - Every key registers. Renders a 104-key US ANSI visual keymap: function row, number row, QWERTY block, ASDF row, ZXCV row, bottom row with modifiers and Space, plus the nav cluster (Insert, Home, PgUp, Delete, End, PgDn, arrows) and the numpad. You press each key; the matching tile turns green.
event.repeatis filtered so the OS auto-repeat does not double-count. If a tile receiveskeydownbut nokeyupwithin 2 seconds, it turns red and is flagged stuck. - Modifier combos work. Four combos:
Shift+A,Ctrl+C,Ctrl+Shift+P, andCapsLockon its own.Ctrl+CandCtrl+Shift+PcallpreventDefault()so they do not copy from the page or trigger Chrome's print dialog.Alt+Tabis deliberately skipped because the OS grabs it before the browser sees it.
When should I run this?
- POS or cashier station. Many barcode scanners present as a HID keyboard. A flaky key on the workstation breaks every scan that includes a checksum letter; a stuck Shift on the scanner side mangles every SKU.
- Data-entry station before a long shift. Catches a sticking Enter or a numpad key that misfires before the operator spends six hours fighting it.
- After spilling coffee on the keyboard. Some switches survive a rinse; some die in a way that only shows up on specific keys. The keymap tells you which.
- Before a typing-heavy interview or exam. ProctorU, HackerRank, and CoderPad lock you into a window. Confirm every key works first.
- After replacing a keyboard. Quick sanity check that the new board enumerates and registers every key before you ship it to a remote site.
Reading the results
The visual keymap uses three colors. Green means a key fired keydown and (eventually) keyup cleanly. Red means a key fired keydown but did not fire keyup within 2 seconds: stuck. Blue marks the modifier keys (Shift, Ctrl, Alt, Win) as a hint that those tiles are special; once pressed, they turn green like any other.
The running counter under the prompt shows X / 104 keys verified. A second strong-red number appears for stuck keys when there are any. You do not have to hit all 104; click Done when you have covered the keys you care about. Anything under 60 unique keys triggers a partial verdict rather than a pass, so the report does not lie about coverage.
Modifier combos render as a list. Each row turns green when the combo is detected. Ctrl+C is intercepted so it does not copy the page text; Ctrl+Shift+P is intercepted so it does not pop Chrome's print preview.
Each row has a status badge: Pending (grey), Running (yellow), Pass (green), Partial (yellow), or Fail (red). On fail or partial the row expands with the diagnosis and a numbered checklist. The verdict panel at the top names the most likely cause and a recommended next step.
Copy Diagnostic Report copies a plain-text report: browser user-agent, platform, per-step results, every key code that registered, every code that stuck, modifier-combo outcomes, and the diagnosis tag from each step. Paste it into a ticket.
Common failures and fixes
The tool produces a named diagnosis for every failure path. Each maps to a fix. In step order:
no-keyboard-api / no-code-property: no keyboard events reach the page
The browser either does not expose KeyboardEvent, or code is missing from the constructed event. On modern desktop browsers this almost never happens by itself; something has intercepted the event flow before the page sees it.
- Focus is somewhere else. Click anywhere on the page first. If the address bar or a browser dev panel has focus, keydown never reaches the document. The test moves focus to a hidden input on Run, but a click outside the tab will steal it.
- A browser extension is blocking input. Vimium, SurfingKeys, Tridactyl, and similar keyboard-driven extensions hijack keys at capture phase. Open the test in an incognito or private window with extensions disabled, or whitelist
desktest.netin the extension's options. - OS accessibility is intercepting. Windows Speech Recognition, macOS Voice Control, and screen readers in input modes can swallow keys. Toggle them off for the duration of the test.
- Page is in an embedded shell. If you opened the test through a kiosk wrapper, an Electron host, or an in-app browser (Slack, Teams preview), open it in a real browser tab instead.
partial-keymap: fewer than 60 keys verified
The keymap recorded under 60 unique keydown events before Done. Two cases:
- You clicked Done early. The common one. Rerun and cover the function row (F1 through F12), the entire number row, both Shift keys, both Ctrl keys, Space, Enter, Backspace, and the arrow cluster. Numpad keys are separate from the number row in
KeyboardEvent.code(Numpad7vsDigit7); press both. - Keys really are missing. Isolate by category. First, common-typing keys (letters, Space, Enter, Backspace, Shift, Ctrl). If any of those fail, the keyboard is broken for normal use. Next, the function row (F1 through F12). Many compact keyboards (60%, 65%, 75%) require an Fn-layer combo for F-keys, and the Fn key itself does not emit a
KeyboardEvent.code; press the F-key directly, not via Fn. Last, media keys (Mute, Volume, Play). These often emit no event at all because the OS or the keyboard firmware consumes them before the browser layer; that is normal and not a failure of the keyboard itself.
Tip: if a specific letter dies, try a different USB port and, for Bluetooth keyboards, repair the device. A flaky USB cable will drop random scancodes under load.
stuck-keys: key fired keydown without keyup
A code stayed asserted for over 2 seconds without a release event. The most common causes:
- Physical key stuck under a crumb. Hair, dried liquid, or grit under the keycap. Pop the cap (most keycaps lift with a fingernail or a wire puller), blow out the switch with a can of compressed air, and reseat the cap. On low-profile laptop scissor switches do not pry hard; the plastic hinges are brittle.
- An OS-level keyboard remapper is masking the real key state. SharpKeys writes a Scancode Map to
HKLM\SYSTEM\CurrentControlSet\Control\Keyboard Layoutand remaps at the kernel level. Microsoft PowerToys Keyboard Manager remaps in user space. AutoHotkey scripts that use$orSendInputcan hold keys in an unexpected state. Quit the remapper, reboot if it was SharpKeys (its remap survives until the registry value is removed and the system reboots), and rerun. - Spilled liquid that dried under the membrane. Sugar from soft drinks is the classic killer. The switch never opens because the contact pad is glued shut. On a membrane keyboard this usually means the whole board is done. On a mechanical board, hot-swap the affected switch.
- Mechanical switch dying. Cherry MX switches are rated for 50 to 100 million keypresses; cheaper clones much less. A switch that randomly chatters or holds is at end of life. Hot-swap or solder a new one in.
- macOS Press and Hold. System Settings, Keyboard, Press and Hold... If on, holding a vowel pops an accent menu; the OS holds the key. Turn it off for testing.
missing-combos: modifier combinations not detected
One or more of Shift+A, Ctrl+C, Ctrl+Shift+P, CapsLock failed to register. Patterns:
- A modifier is physically dead. If
Shift+Afails but Shift lit green in the keymap, the keyboard is reportingShiftas a keystroke but not as a modifier flag. Rare and usually means a custom firmware (QMK / VIA) layer is wrong. If Shift did not light green in step 2 either, the Shift key is dead. Try the opposite Shift;ShiftLeftandShiftRightare separate codes. - AutoHotkey is intercepting. A running AHK script with a hotkey like
^c::or^+p::consumes the combo before the browser sees it. Right-click the AHK tray icon, Suspend Hotkeys, rerun. PowerToys with a Shortcut Guide or remap on the same combo behaves the same. - A password manager is intercepting. 1Password, Bitwarden, and Dashlane bind global shortcuts;
Ctrl+Shift+Pin particular collides with Bitwarden's Lock command on some installs. Open the extension's settings and either reassign or disable the global shortcut. - macOS Caps Lock toggle. macOS treats Caps Lock as a slow toggle by default: a short tap is ignored, only a held press flips state. If
CapsLockdoes not register, tap and hold for half a second, or in System Settings, Keyboard, Modifier Keys, set Caps Lock to act normally. - Windows Sticky Keys. Five rapid Shift presses turns Sticky Keys on; the modifier then latches instead of being held, which changes how the browser sees the modifier flag on a follow-up letter. In Settings, Accessibility, Keyboard, turn Sticky Keys off. Filter Keys can also drop modifier presses below its hold-down threshold; turn it off.
Barcode-scanner-as-keyboard quirks
USB barcode scanners that present as HID keyboards (Honeywell Voyager, Zebra DS2208, Datalogic QuickScan, generic Symcode units) feed scans as a burst of keydown / keyup pairs followed by an Enter. A few specifics when running this test with a scanner connected:
- Scan-of-1-character keys come fast (often under 30 ms per character). Single-character keys come through cleanly. Multi-key codepoints sent as Shift+digit can race the modifier; if the scanner is dropping uppercase or symbol characters in step 2, lower the scan speed in the scanner config sheet.
- Many scanners send F-key sequences as configurable prefix or suffix codes. If you see
F1throughF12light up green without you touching the keyboard, that is the scanner. Reprogram the prefix/suffix to nothing, or toTabif the line-of-business app needs a delimiter. - Test with the actual scanner, not a generic keyboard. A scanner's interpretation of "function key" depends on its current keyboard wedge profile (US, UK, ALT-mode numeric). The diagnostic surfaces whatever code the scanner emits; that may differ from what the receiving app expects.
For IT admins
Keyboard input behavior is governed at three layers: hardware (the keyboard or scanner firmware), OS (driver, accessibility, layout), and per-app (browser, remappers, scripts). The test sees only the last layer's view, but the failure pattern tells you which lower layer to look at.
Windows Scancode Map. Kernel-level remap lives at HKLM\SYSTEM\CurrentControlSet\Control\Keyboard Layout, value Scancode Map (REG_BINARY). SharpKeys writes here. The remap applies to every user on the machine and survives until the value is deleted and the machine reboots. For shared workstations (kiosks, branch tills, call-center seats), baseline the image with no Scancode Map and block users from writing one via Group Policy on the parent key.
Group Policy for accessibility. Sticky Keys, Filter Keys, and Toggle Keys live under Computer Configuration, Administrative Templates, Control Panel, Personalization on newer templates, and in user mode under Ease of Access Center settings. Push them off on shared workstations: Filter Keys in particular can silently drop short keypresses, which looks identical to a dying keyboard.
Known hardware quirks. Logitech Unifying receivers can drop modifier events when paired with more than four devices on the same dongle; pair the keyboard to its own receiver. Microsoft Surface Type Cover firmware has shipped revisions that misreport Fn-layer keys; the Surface app updates firmware separately from Windows Update, so check it explicitly. Mechanical keyboards running custom firmware can be inspected with VIA Configurator (or its successor, Vial) for VIA-compatible boards, and with the QMK Toolbox plus a JSON keymap for QMK firmware; a wrong layout JSON will silently swap codes.
Recommended baseline. For shared workstations, no third-party keyboard remapper (no SharpKeys, no AutoHotkey on startup, no PowerToys Keyboard Manager). Sticky Keys, Filter Keys, Toggle Keys off. Native US (or local) layout only. The test then reports the keyboard's real state, not the state filtered through a stack of user tools.
Behind the scenes
The tool keys everything off KeyboardEvent.code, not KeyboardEvent.key. code is the physical key location: KeyA is the key second from the left on the ASDF row, regardless of whether the layout is QWERTY or AZERTY. key is the character that would be produced, which changes with modifiers (Shift+a vs a), layout (AZERTY a is at physical KeyQ), and dead-key state (the dieresis dead key followed by a is "a-umlaut"). For a hardware test we want the physical key, so code wins.
Listeners attach at the document level in capture phase so we see every event before any in-page handler can stopPropagation(). event.repeat is filtered so OS auto-repeat (typically 30 ms after a 500 ms hold on Windows defaults) does not register as multiple presses. Tab, Backspace, and Space get preventDefault() so Tab does not move focus away, Backspace does not navigate back (a Firefox default until v86), and Space does not scroll.
Stuck-key detection is a 2-second timer started on keydown and cleared on keyup. If the timer fires first, the code is flagged stuck and turns red. A subsequent clean keyup clears the flag and turns it green; the diagnostic records both the moment of stuck-state and the recovery in the report.
Step 3 combos call preventDefault() on Ctrl+C and Ctrl+Shift+P only after they match, so an unrelated Ctrl+Shift+P outside the combo phase still pops the browser's print preview. Alt+Tab is intentionally not in the combo list because Windows and macOS grab it at the window-manager layer before the browser sees it; testing it here would always fail and tell you nothing useful.
Nothing leaves the browser tab. No keystroke is logged to a server, no telemetry beacon is fired, no analytics. The diagnostic report is built on Copy from in-memory state, and the page discards everything on reload. Open DevTools, Network tab, and confirm: no outbound requests while the test runs.
Related
- Keyboard Test - the diagnostic itself
- USB Test Guide - check the port and cable feeding a wired keyboard or scanner
- Display Test Guide - pair with a keyboard check for a full station sweep
- desktest.net home
- About desktest.net