Methodology 0.2-preview

How the diagnostic works

The test records browser-observed mouse-like events only while you interact with the test surface. Raw events remain in page memory and are cleared on refresh.

What is measured

  • Complete, trusted mouse pointerdown/pointerup pairs for one button and one round.
  • Down-to-down intervals, plus click and dblclick as supplementary browser evidence.
  • Sample count, minimum, linear-interpolation median and P95.

Quality limits

Hidden pages, cancelled input, incomplete pairs, non-monotonic timestamps and reduced timer precision lower confidence. Touch and pen input are excluded. This tool cannot identify a device model, connection type or electrical switch condition.

Observation bands

The current bands are ≤ 50 ms (candidate) and ≤ 100 ms (review). They are versioned observational aids, not an operating-system double-click setting or a universal hardware threshold.

Basis for the bands

  • Mechanical switch contacts bounce for roughly 1–6 ms in published measurements, so a same-button repeat of 50 ms or less is almost impossible to produce deliberately.
  • Deliberate human double-clicks usually take 100 ms or more, so intervals up to 100 ms are marked only for review, not as confirmed faults.
  • The operating-system double-click window is a separate concept: Windows uses a default of 500 ms for the maximum interval between two intentional clicks.

Double-click speed test boundaries

The double-click speed test uses different observation windows than the diagnostic tool. It measures the time between two intentional clicks and observes whether the browser dispatches dblclick. It does not diagnose hardware faults or read operating-system settings.

  • First-click expiry: 5000 ms — the maximum time between the first and second click to form a pair. This is the session pairing limit, not an OS threshold.
  • dblclick dispatch wait: 250 ms — the observation window after the second click for the browser to dispatch dblclick. This is not a speed recommendation or OS default.

These values are versioned separately from the diagnostic observation bands and may be adjusted after cross-browser verification.

Keyboard tester boundaries

The keyboard tester (keyboard checker / key tester) highlights physical key positions from trusted KeyboardEvent values while the test area has focus. It tracks pressed vs tested coverage on a US ANSI full-size diagram and shows Last Key details (key, code, location). It does not score “keyboard health,” detect chatter gaps, or certify multi-key rollover.

  • Identity: coverage uses event.code (physical position). Display text uses event.key.
  • Pressed: codes with an outstanding keydown (no matching keyup yet).
  • Tested: codes that received at least one non-repeat trusted keydown this session. Auto-repeat does not increase coverage.
  • Untested: no event yet for that diagram key — not a hardware fault label.
  • Focus gate: listening requires the test panel to be focused. Space / arrows / PageUp / PageDown may be prevented from scrolling the page while focused; Tab and Escape remain available to leave focus.
  • Interrupt: window blur or tab hide clears live pressed highlights. Pause does the same and suspends new sampling until Resume.
  • Privacy: pressed/tested sets and last-key fields stay in page memory only; GA4 receives aggregate tool events without raw key streams.

Keyboard tester uses a separate versioned config (version 0.1-preview) from chatter, ghosting, and mouse diagnostic bands. Fn-layer keys, many media keys, and OS-level shortcuts may never reach the page.

Keyboard chatter test boundaries

The keyboard double typing test observes browser keyboard events per physical key (event.code) while the test area has focus. Only trusted keydown and keyup events enter the sample. Auto-repeat events (KeyboardEvent.repeat === true) are recorded separately as held repeats and excluded from chatter detection.

  • Gap after release (up → down): after a completed keyup, the next same-key non-repeat keydown is classified by the release-to-press interval. This catches post-release bounce that a pure keydown→keydown gap can hide when the previous press was held.
  • Gap while still down (down → down): if another non-repeat keydown arrives before a clean keyup, the interval from the previous keydown is used instead.
  • Chatter candidate: a classified same-key gap within 30 ms.
  • Review: a classified same-key gap between 30 ms and 80 ms.
  • Suggested sample: about 20 slow single presses on one key before treating a clean round as “no suspicious repeats observed.” Fewer presses stay on Keep testing. This is a diagnostic aid, not a hardware pass mark.
  • Long hold: holding a key for more than 1500 ms is surfaced as a long hold note, not a fault.
  • Timeline: the latest 50 events are shown in memory only and cleared on refresh.

Keyboard observation uses a separate versioned config (version 0.2-preview) from the mouse diagnostic bands, because keyboard chatter and mouse switch bounce are different measurements. Different keys never form a chatter pair. Page blur, pause, or focus loss clears in-progress down state and both gap anchors (last down and last up), so the next press is not paired across the interruption. Orphan or duplicate keyup events do not revive those anchors.

Keyboard rollover and ghosting test boundaries

The keyboard ghosting test (also used as a key rollover / NKRO observation tool) tracks simultaneous trusted non-repeat keydown positions by event.code while the test area has focus and a run is active. It does not reuse chatter gap thresholds and does not certify hardware KRO ratings.

  • Modes: Ghosting Test compares a preset or custom expected set with keys held together; Rollover / NKRO tracks current and maximum simultaneous counts with ordinary vs modifier splits.
  • Simultaneous set: only keys with an outstanding keydown (no matching keyup yet) count. KeyboardEvent.repeat is ignored so auto-repeat cannot inflate the held set.
  • Full combination: marked only when every expected code is present in the held set at the same moment during the run.
  • Result labels: Not started, Testing, All selected keys observed, Some keys not observed, Interrupted — never a bare Pass/Fail hardware verdict.
  • User confirmation: “possible blocking / rollover limit” wording for missing preset keys is strengthened only after the user confirms they held the full combination. Without confirmation, the page keeps an observation record only.
  • Interrupt: window blur or tab hide finishes the run as Interrupted and clears held state. Pause suspends listening and clears live holds without finishing; panel blur alone does not wipe the held set so Finish still sees keys that were down.
  • History: up to 12 local chord summaries may be kept in page memory for the rollover view; nothing is uploaded or written to LocalStorage.

Ghosting / rollover observation uses a separate versioned config (version 0.1-preview) from keyboard chatter and mouse diagnostic bands. Fn keys, many media keys, and OS-level shortcuts may never reach the page.

CPS / click speed test boundaries

The CPS test (click speed test) counts intentional mouse clicks during a timed run. It is a self-test of click pace, not a diagnostic. It does not detect double-clicking, autoclickers or hardware faults, and it cannot measure input latency, polling rate, reaction speed or your physical capability limit.

  • Durations: 1, 5, 10, 15, 30, 60 seconds. The run ends at the logical start time plus the chosen duration, not at the last click.
  • Final CPS: total clicks divided by the selected duration, from a finished run only.
  • Best 1-second burst: the highest per-second bucket count.
  • Median per-second CPS: the median of the per-second bucket counts.

Click speed uses a separate versioned config (version 0.1-preview) from the mouse diagnostic observation bands and the keyboard chatter thresholds.

Click counter boundaries

The click counter is an untimed tally utility: it accumulates values you enter on the page, not a CPS test, double-click diagnostic, or hardware fault verdict. It does not count every OS-level click outside the tool controls.

  • Input: Count / Minus act on the active counter; Space or Enter may count only while the Count control is focused. Pointer and keyboard paths share the same step size.
  • Counters: up to 20 named counters; names truncated to 48 characters; steps 1, 2, 5, 10.
  • Undo: up to 50 recent value changes stay in page memory and clear on refresh.
  • Local save: counter names, values and steps may be written to this browser under doubleclicktest.click-counter.v1 (schema version 1, bounded parse). Nothing is uploaded. Other tools on this site still avoid LocalStorage for test timelines.

Click counter config lives in src/domain/click-counter.ts and is separate from CPS and mouse diagnostic bands.

Spacebar clicker boundaries

The spacebar clicker counts trusted Space presses while the test area has focus. Counter mode is untimed; speed mode is a self-test of browser-observed presses per second — not a full keyboard coverage checker, chatter diagnostic, or hardware fault verdict.

  • Accepted input: KeyboardEvent.code === "Space" on the focused test target, isTrusted, and not repeat (held-key auto-repeat is ignored).
  • Speed durations: 1, 5, 10, 15, 30, 60 seconds (default 5). Average PPS uses finished runs only (press count ÷ duration).
  • Fastest second: highest fixed wall-second bucket count on a finished run.
  • History: up to 5 finished timed runs and per-duration best scores stay in page memory and clear on refresh; no LocalStorage.
  • Interrupt: tab hide or window blur can end a timed run as interrupted without a full score.

Spacebar clicker config lives in src/domain/spacebar-clicker.ts and is separate from click-speed.ts, keyboard chatter, and keyboard-test coverage rules.

Jitter click test boundaries

The jitter click test counts trusted left-button mouse click events after a matching mouse pointerdown on the test target during a short timed run. It reuses the CPS run state machine with rolling peak CPS, click intervals, and rhythm variation. It is a self-test of browser-observed click pace and spacing for people attempting jitter clicking — not a technique detector, skill rank, hardware fault verdict, autoclicker detector, or butterfly/drag classifier.

  • Durations: 1, 5, 10, 15 seconds (default 5). The run ends at the logical start time plus the chosen duration, not at the last click.
  • Clock: run start, click timestamps, live remaining time, and the finish timer use performance.now() on one timeline.
  • Average CPS: total accepted clicks divided by the selected duration, from a finished run only.
  • Peak 1-second CPS: highest click count inside any continuous 1000 ms window over click timestamps (rolling window), not the max of fixed wall-second buckets.
  • Click intervals: gaps between consecutive accepted clicks; median / min / max when at least two clicks were recorded.
  • Rhythm variation: coefficient of variation (population stddev ÷ mean) of consecutive intervals, shown only on finished runs with at least 4 gaps. Bands: steady if CV < 0.15, mixed if CV < 0.35, otherwise uneven. Descriptive only — not Pro/Expert ranks or percentiles.
  • Per-second chart: fixed wall-second buckets for a simple pace curve on runs longer than 1 second (complementary to rolling peak).
  • Exclusions: touch/pen pointers, keyboard activation, and untrusted events are ignored; interrupted (hidden/blur) runs do not produce a full score; the page does not certify physical technique.

Jitter click uses a separate versioned config (version 0.1-preview) from the regular CPS config, butterfly-click config, drag-click config, right-click CPS config, mouse diagnostic bands, and keyboard chatter thresholds.

Butterfly click test boundaries

The butterfly click test counts trusted left-button mouse click events after a matching mouse pointerdown on the test target during a short timed run. It reuses the CPS run state machine with rolling peak CPS, click intervals, and rhythm variation. It is a self-test of browser-observed click pace and spacing for people attempting two-finger butterfly clicking on the same button — not a finger-count detector, skill rank, hardware fault verdict, autoclicker detector, or left/right alternating game mode.

  • Durations: 1, 5, 10, 15 seconds (default 5). The run ends at the logical start time plus the chosen duration, not at the last click.
  • Clock: run start, click timestamps, live remaining time, and the finish timer use performance.now() on one timeline.
  • Average CPS: total accepted clicks divided by the selected duration, from a finished run only.
  • Peak 1-second CPS: highest click count inside any continuous 1000 ms window over click timestamps (rolling window), not the max of fixed wall-second buckets.
  • Click intervals: gaps between consecutive accepted clicks; median / min / max when at least two clicks were recorded.
  • Rhythm variation: coefficient of variation (population stddev ÷ mean) of consecutive intervals, shown only on finished runs with at least 4 gaps. Bands: steady if CV < 0.15, mixed if CV < 0.35, otherwise uneven. Descriptive only — not Pro/Expert ranks or percentiles.
  • Per-second chart: fixed wall-second buckets for a simple pace curve on runs longer than 1 second (complementary to rolling peak).
  • Exclusions: touch/pen pointers, keyboard activation, and untrusted events are ignored; interrupted (hidden/blur) runs do not produce a full score; the page does not certify physical two-finger technique.

Butterfly click uses a separate versioned config (version 0.1-preview) from the regular CPS config, jitter-click config, drag-click config, right-click CPS config, mouse diagnostic bands, and keyboard chatter thresholds.

Drag click test boundaries

The drag click test counts trusted left-button pointerdown events (pointerType === "mouse", button 0) during a timed run while you attempt drag clicking. Press-down counting is intentional: rapid drag-click bounces often do not synthesize a full click per bounce. It is a self-test of browser-observed press pace and spacing, not a technique detector, mouse-model identifier, hardware fault verdict, or mouse-drag (hold-and-move) test.

  • Durations: 1, 5, 10, 15 seconds. The run ends at the logical start time plus the chosen duration, not at the last accepted press.
  • Clock: run start, press timestamps, live remaining time, and the finish timer use performance.now() on one timeline.
  • Average CPS: total accepted presses divided by the selected duration, from a finished run only.
  • Peak 1-second CPS: highest press count inside any continuous 1000 ms window over press timestamps (rolling window), not the max of fixed wall-second buckets.
  • Press intervals: gaps between consecutive accepted presses; median / min / max when at least two presses were recorded.
  • Exclusions: touch/pen pointers and untrusted events are ignored; does not certify physical technique, switch life, debounce settings, or OS/game client behavior outside this page.

Drag click uses a separate versioned config (version 0.1-preview) from the regular CPS config, right-click CPS config, mouse diagnostic bands, and keyboard chatter thresholds.

Right click CPS test boundaries

The right click CPS test counts intentional right mouse-button clicks during a timed run. Left and middle buttons are ignored. It is a self-test of right-click pace, not a right-button hardware check, left-click CPS test, or double-click diagnostic.

  • Durations: 1, 5, 10, 30, 60 seconds. The run ends at the logical start time plus the chosen duration, not at the last click.
  • Accepted input: trusted mouse pointer events with button 2 (right) on the test target. The browser context menu is suppressed on the target.
  • Final CPS: total right clicks divided by the selected duration, from a finished run only.
  • Best 1-second burst: the highest per-second bucket count (same calculation shape as the regular CPS test).
  • Pace labels: optional fun bands only; not an official standard and not a hardware grade.

Right-click CPS uses a separate versioned config (version 0.1-preview) from the regular CPS config, mouse diagnostic bands, and keyboard chatter thresholds.

Mouse test boundaries

The mouse test is a hardware input hub: it checks whether left, right, middle, optional side buttons, scroll up/down, basic movement, and button hold/release are observed by the browser. It is not a CPS test, polling-rate test, DPI meter, or full double-click diagnostic. Detection confirms browser input, not certified hardware health.

  • Common channels: Left, Right, Middle, Scroll Up, Scroll Down — each marked Detected after at least one trusted event. Coverage is reported as detected / 5 for these channels only.
  • Optional side buttons: Back (MB4) and Forward (MB5) are tracked separately; missing them is normal on mice without side buttons.
  • Movement: throttled pointer-move samples (about every 80 ms) show that motion reached the browser, with a coarse last direction. Not a polling-rate or distance measurement.
  • Hold / release: pointer down → Pressed with live hold duration; pointer up → Released. pointercancel or lost capture while pressed may show an interrupted release hint to retest — not a fault verdict.
  • Possible fast repeat: same-button press within 50 ms (stronger timing flag) or up to 100 ms (review band). Timing only; not a double-click diagnosis.
  • Timeline: latest 40 inputs stay in page memory and clear on refresh.

Mouse test uses a separate versioned config (version 0.1-preview). Deep scroll analysis and polling-rate measurement belong on dedicated pages.

Scroll wheel test boundaries

The scroll wheel test observes browser wheel events over the test pad: direction counts, a rolling 1-second speed window, an optional timed speed run, horizontal scroll channels, and reverse-event detection for skipping. It cannot read the wheel encoder, distinguish input sources (tilt wheel and touchpad gestures arrive as wheel events; Shift + wheel only counts as horizontal when the browser emits deltaX), or measure polling rate.

  • Reverse event candidate: after at least 3 wheel events in one direction, an opposite-direction event within 250 ms of the previous one.
  • Confirmation: the next event returns to the original direction within 250 ms. Isolated reverse events are counted; deliberate direction changes are not.
  • Scroll Health gate: reverse events can flag early; a clean “no skipping detected” label requires at least 12 vertical-primary wheel events (same axis rule as reverse detection: |deltaY| ≥ |deltaX|). Channel hit counts that include diagonal deltaY do not count toward the gate. Fewer samples stay on Insufficient data. No reverse events still is not a full hardware pass. Confirmed reverse totals are kept even when the on-screen note list is capped at 12.
  • Speed: browser wheel events per second over a 1000 ms window; timed runs of 5 / 10 / 30 seconds count events, not physical detents. The UI may still say scrolls per second as the familiar label.
  • Timeline: the latest 40 events stay in page memory and clear on refresh.

Scroll test uses a separate versioned config (version 0.1-preview). Reverse events are an observational skipping signal, not a confirmed encoder fault.

Browser-based DPI estimation

The mouse DPI test divides absolute net horizontal movement by a ruler-measured physical distance in inches. Sampling starts only after Pointer Lock is confirmed. Unadjusted movement is requested, not certified: older browsers may ignore options, and success does not authenticate sensor counts. OS-adjusted results are labeled effective pointer units per inch. No devicePixelRatio or system scaling correction is applied.

  • Physical distance: 2–60 cm, with inch conversion supported.
  • Valid pass: at least 4 nonzero movement samples and 40 net horizontal units.
  • Backtracking check: sum of absolute horizontal movement ÷ absolute net horizontal movement must not exceed 1.1.
  • Vertical drift check: absolute vertical travel ÷ absolute horizontal travel must not exceed 0.25.
  • Summary: median of up to 5 latest valid passes per mode; request at least 3. Raw-requested and OS-adjusted runs are never combined.
  • Variation: (maximum − minimum) ÷ median × 100. Above 10% prompts a repeat, not a sensor-fault judgment.
  • Esc, cancellation, focus loss, hidden pages and lost Pointer Lock discard the current pass. Rejected requests do not silently fall back.

DPI config version 0.1-preview: these are engineering quality checks, not validated industry standards. Hardware accuracy and cross-browser compatibility remain unverified. Before production acceptance, compare known 800/1600 presets, three repeats and slow/fast passes on Windows Chrome/Edge, and check rejection, unsupported environments and Firefox/macOS/Safari fallback behavior. Repeatability alone cannot certify hardware DPI. See MDN Pointer Lock API.

Mouse polling rate test boundaries

The mouse polling rate test estimates the effective mouse report rate (Hz) from trusted browser pointer-move events over the test pad. It is not a USB HID descriptor reader, factory certificate, or input-latency lab instrument.

  • Current rate: pointer-move events counted in a rolling 1000 ms window (scaled for short partial windows).
  • Average rate (free-play): (in-window event count − 1) ÷ span inside a sliding 5000 ms window. Pauses longer than 1200 ms start a new peak/min segment and clear the rate trail.
  • Average rate (timed run): only moves after Start, on a run-private timestamp buffer — pre-run motion never enters peak, stability, or distribution.
  • Tier mapping: averages are matched to the nearest common tier (125 / 250 / 500 / 1000 / 2000 / 4000 / 8000 Hz) only when enough samples and duration are present and the relative error stays within the configured band.
  • Stability: share of sampled window rates within ±12% of the expected tier.
  • Distribution: histogram of sampled rates in 50 Hz buckets (top buckets shown; remainder collapsed to Other).
  • Timed runs: optional 5 / 10 second locks for average, peak, minimum, stability, and distribution. Hidden or blurred pages interrupt a run.
  • Coalesced moves: when the browser exposes getCoalescedEvents(), each coalesced move timestamp is counted separately.
  • Exclusions: touch and pen pointers are ignored; untrusted events are ignored.

Polling-rate estimation uses a separate versioned config (version 0.1-preview). Browser coalescing limits, OS scheduling, wireless links, and slow movement can all lower the observed rate versus the mouse software setting.

Sources: Microsoft SetDoubleClickTime; OMRON chattering FAQ; Analog Devices Switch Bounce and Other Dirty Little Secrets; Texas Instruments Debounce a Switch; EEJournal Ultimate Guide to Switch Debounce; QMK debounce configuration.