Gamepad Test
Test gamepad buttons, sticks, triggers, D-pad and rumble in your browser
Left Stick
Right Stick
Triggers
Rumble Test
Event History
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
- Connect your gamepad via USB or Bluetooth
- Press any button on the gamepad to activate it
- Watch the on-screen layout light up as you press buttons or move sticks
- Use the rumble buttons to test the vibration motors
- 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
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.0Pushing the Left Stick
Push left stick up-right -> axes[0] = 0.71, axes[1] = -0.68Squeezing 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.