key events named the key they carried
Every keypress naming its character in .key. .code is empty on real keypress events and is deliberately not scored (severity: warn).
What a detector infers
A keypress the engine generates names the character it is delivering in .key. CDP's Input.dispatchKeyEvent with type "char" accepts text without a key, and a driver that supplies only the text leaves .key as the empty string while the character still reaches the field - a keypress that delivered something it cannot name.
Kept as its own row rather than folded into the sequence check above because it reads the CONTENT of the event rather than its ordering, so a driver that fixed one and not the other is still visible - and that separation earned itself, because the two were fixed together upstream and would otherwise have looked like one result. A CORRECTION WORTH RECORDING, because it nearly became a false claim on this page.
An earlier version of this entry stated that .code is empty on a real keypress too, and that a row demanding it would therefore fail every genuine keypress. That was measured against a CDP control arm, not against hardware - and the control arm dispatched its char events WITHOUT a code, so the empty value was the test's own artifact rather than anything the browser does.
A physical keyboard on Chrome 150 produces a keypress carrying key 'a', code 'KeyA' and keyCode 97, with .code fully populated. The row still scores .key alone, which is the conservative choice and unaffected; but the reasoning behind that choice was wrong, and the general lesson is the one that matters: a control arm built from the same protocol as the thing under test is not a baseline, it is a second sample of the same thing.
MEASURED, AND NOW FIXED UPSTREAM: SeleniumBase 4.51.3 produced keypress events with key "" and keyCode set, against a control arm that produced key "h" for the same character; 4.51.5 populates key, code and the virtual key code and passes this row.
How to resolve it
Populate key, code and the virtual key codes on the keydown and keyUp events you dispatch, and let the char event carry the text. A character arriving in the field from an event that names no key is not a shape the engine produces.
Nearby checks in Automation surface
- the gesture that started this audit registered as a real user activation
user-activation-vs-interactionThis audit only runs when you press the Run button, and pressing a button is exactly what grants user activation — by pointer, by Enter or… - user activation only ever appeared after a real input event
activation-without-inputThe row above this one reads navigator.userActivation once and expects it to be true, because the audit is reached by pressing a button. - the clicks this page received were real clicks
interaction-click-trustEvent.isTrusted is set by the engine when it dispatches an event it generated itself, and it cannot be set from script - a constructed… - every keypress had a keydown behind it
interaction-keypress-without-keydownThe UI Events spec generates keypress as the DEFAULT ACTION of a keydown - it is not an independent event, it is what a keydown does when it… - the dropdown change came from the browser, not from a script
interaction-select-change-trustThe same isTrusted argument as the click row, on the surface where the shortcut is most common. - the dropdown fired input before change
interaction-select-input-precedes-changeHTML's "send select update notifications" steps fire input and THEN change when a selection is committed, so the pair is what the algorithm… - the text in the field arrived through events
interaction-value-without-eventsText cannot appear in a field without the engine having put it there, and every route the engine offers announces itself with an input event… - the pointer moved before it clicked
pointer-movement-precedes-clickA mouse reaches a target by crossing the document, and every position it crosses is an event.
Clearcote is a browser built for fingerprint coherence
It is a Chromium fork, maintained by the same people who wrote this reference. It ships as a compiled browser rather than as a stealth script injected into someone else's — which is a description of how it is built, and is not an argument about how it behaves on this check.
This audit takes no position on how Clearcote scores on Automation surface checks, on this one, or anywhere else. It has no baseline corpus of other people's fingerprints to rank you against and no vendor scoreboard — nearly every check is self-referential, asking one browser the same question through two independent APIs and reporting whether both answers can be true at once. It runs identically on any browser, including ours. Run it on yours and read the result yourself.
See the other checks in Automation surface — the family interaction-key-identity-populated belongs to.
