ToolActToolAct

Gamepad Test

Test gamepad buttons, sticks, triggers, D-pad and rumble in your browser

No gamepad detected
Connect a gamepad and press any button to activate it
LBRBYXBA

Left Stick

X: 0.00Y: 0.00
Centered

Right Stick

X: 0.00Y: 0.00
Centered

Triggers

LT
0.00
RT
0.00

Rumble Test

This gamepad or browser does not support rumble.

Event History

Press a gamepad button to start testing...

What is a Gamepad Test?

A gamepad test reads the signals your controller sends to the browser through the W3C Gamepad API and shows them in real time: every button press, analog stick position, trigger depth, D-pad direction and rumble motor. It is the fastest way to check whether a controller works before a game, diagnose a sticky face button, catch stick drift on an aging pad, or verify that both rumble motors fire. The page highlights each input on an on-screen Xbox-style layout, reports raw axis and trigger values, and keeps a short event log. Because the Gamepad API only exposes a controller after you press a button on it, the page will ask you to press any key first - that is a browser security rule, not a fault with your pad. Everything runs locally in your browser; no input data leaves your device.

How to Use

How to use

  1. Connect your gamepad via USB or Bluetooth
  2. Press any button on the gamepad to activate it
  3. Watch the on-screen layout light up as you press buttons or move sticks
  4. Use the rumble buttons to test the vibration motors
  5. Review the event history to confirm every press registered

Tips

  • Green highlight means the input is reaching the browser correctly
  • A controller only appears after you press a button on it - this is a browser security rule
  • Rumble support depends on the browser and gamepad; Firefox has the broadest support
  • If a stick shows a non-zero value at rest, the drift tag warns you of stick drift
  • Multiple connected gamepads can be switched between with the slot chips

Use Cases

Diagnose unresponsive or double-firing buttonsTap each face button, shoulder and D-pad direction once and watch the on-screen layout light up from real button state. The event history records every press and release, so a switch that fires twice from a single tap or fails to register at all is immediately visible against a known-good button.
Detect analog stick driftLeave both sticks centered and read the live X/Y values. A healthy stick rests near 0.00; the drift tag turns orange when a stick reports more than 0.12 at rest, the classic symptom of worn stick modules that pulls your character or cursor on its own.
Verify trigger linearitySlowly squeeze LT and RT and watch the value climb from 0.00 to 1.00 on the trigger bars. A trigger that jumps, maxes out too early, or never reaches full value has a worn potentiometer - useful to confirm before blaming a racing game's throttle feel.
Test rumble motors independentlyThe weak, strong and dual-rumble buttons drive the high-frequency and low-frequency motors separately through the GamepadHapticActuator API. If only one intensity fires, one motor is dead; if nothing happens at all, either the pad or the browser lacks rumble support and the page shows that explicitly.
Identify and switch between multiple gamepadsThe status panel reports each pad's vendor ID string, mapping type (standard vs non-standard), slot index, button and axis count. When several pads are paired, the slot chips let you switch the tester between them without reconnecting - handy for checking a full set of controllers before a local multiplayer session.

Technical Principle

The browser exposes gamepads through the W3C Gamepad API. A controller is represented by a Gamepad object obtained from navigator.getGamepads(), which returns up to four slots. Each gamepad carries an id string (vendor and product), a mapping field ('standard' for Xbox-layout devices, empty otherwise), a buttons array and an axes array. Under the standard mapping, buttons has 17 entries: four face buttons (A/B/X/Y), two bumpers (LB/RB), two analog triggers (LT/RT), Select/Start, two stick-clicks (L3/R3), four D-pad directions and the Home/Guide button. Each button exposes .pressed (boolean) and .value (0 to 1 - triggers go analog, digital buttons are 0 or 1). The axes array holds four values in the range -1 to 1: left stick X/Y then right stick X/Y. The API is poll-based, not event-based, so the page runs a requestAnimationFrame loop and reads a fresh snapshot every frame. To avoid useless re-renders while the pad is idle, it only updates state when gamepad.timestamp changes - that timestamp advances on every new input report. Connect and disconnect arrive as gamepadconnected and gamepaddisconnected window events. For security, a gamepad object stays null until the user presses a button on it, so the page cannot read a freshly plugged-in pad silently. Rumble is optional: if gamepad.vibrationActuator exists, calling playEffect('dual-rumble', { duration, weakMagnitude, strongMagnitude }) drives the two motors; Safari and some Chromium builds do not implement it, which is why the page feature-detects it and disables the buttons otherwise.

  • navigator.getGamepads() returns up to four slots; a pad is only non-null after you press a button on it.
  • Standard mapping: buttons[0-3] face, [4-5] bumpers, [6-7] analog triggers, [8-9] Select/Start, [10-11] L3/R3, [12-15] D-pad, [16] Home.
  • axes[0-1] is the left stick (X, Y), axes[2-3] the right stick, each ranging -1 to 1.
  • Polling model: a requestAnimationFrame loop reads snapshots; gamepad.timestamp gates updates so idle frames do nothing.
  • Rumble via gamepad.vibrationActuator.playEffect('dual-rumble', ...) - feature-detected, not supported in every browser.
  • gamepadconnected / gamepaddisconnected events signal connect and disconnect; the pad's .index identifies its slot.

Examples

Pressing a Face Button

Press A -> buttons[0].pressed = true, value = 1.0

Pushing the Left Stick

Push left stick up-right -> axes[0] = 0.71, axes[1] = -0.68

Squeezing a Trigger

Squeeze RT halfway -> buttons[7].value = 0.50, pressed = false (below threshold)

FAQ

Why doesn't my gamepad show up after I plug it in?

The Gamepad API keeps a controller hidden until you press a button on it, to prevent pages from silently fingerprinting connected devices. Connect the pad over USB or Bluetooth, focus this tab, then press any button - the status panel will switch to Connected. This activation step is a browser security rule, not a defect.

Which controllers are supported?

Any controller the browser exposes with the standard mapping: Xbox One/Series controllers, DualShock 4 and DualSense (which most systems map to standard), and most generic USB gamepads. Over Bluetooth or USB, the browser normalizes them to the same 17-button, 4-axis layout. Non-standard pads still work but their button order may not match the on-screen labels.

Why is rumble not working?

Rumble support varies. Firefox has the broadest support; Chrome and Edge support it on recent versions; Safari does not implement it. The pad itself must also expose gamepad.vibrationActuator. The page detects this and shows an explicit 'not supported' notice instead of silently doing nothing, so a missing rumble is a browser or hardware limit, not a bug here.

My stick shows a value when I'm not touching it - is it broken?

A small value near 0 is normal dead-zone noise. If a stick rests above about 0.12 on either axis, the drift tag turns orange - that is classic stick drift, caused by worn potentiometer modules. It is a hardware issue that usually gets worse over time; the tool lets you confirm it before blaming a game.

Is any of this sent to a server?

No. The Gamepad API is read entirely in your browser. Button presses, stick positions and rumble commands never leave your device. Nothing is logged or transmitted.

Can it test DualSense adaptive triggers, the touchpad or gyro?

No. The standard Gamepad API only exposes buttons, axes and basic rumble. DualSense adaptive triggers, the capacitive touchpad and motion sensors are not part of the web standard (some live behind experimental extensions with poor browser support), so they cannot be tested reliably from a browser.