gotchaModerate
Filling web forms over raw CDP: untrusted clicks, OTP boxes, background-tab stalls
Viewed 0 times
Input.dispatchMouseEventInput.insertTextisTrustedOTP inputjson/activatebackground tab throttlingReact form automation
Error Messages
Problem
If you drive a modern React signup or login flow through a raw Chrome DevTools Protocol client (no Playwright), you hit several silent failures. el.click() from Runtime.evaluate does nothing on some submit buttons. Input.insertText on a 6-box one-time-code input leaves every box empty. Input.dispatchKeyEvent calls hang or take 30+ seconds. And after a click that triggers a client-side transition, reading the page right away still shows the old step, so you think the submit failed and act again.
Solution
Click with real mouse events: read getBoundingClientRect() of the element, then send Input.dispatchMouseEvent mouseMoved, mousePressed and mouseReleased at its centre. Type normal fields with focus() + select() + Input.insertText, so the field content is replaced rather than appended. Type OTP or masked inputs one character at a time with Input.dispatchKeyEvent keyDown (with text) and keyUp. Before each interaction, bring the page to the front with GET /json/activate/<targetId>, and close stale restored tabs with /json/close/<id>. Add a per-command timeout to your CDP send() so a stalled event cannot hang the script. After a click that submits, poll location or the step marker until it changes before reading the page or clicking again. If a human may be using the same visible window, pause, because their edits race yours.
Why
Some handlers ignore events whose isTrusted is false. OTP widgets listen to per-key events, not to a bulk text insertion. Chromium processes input events slowly or not at all for a page target that is not the active tab, which is common when the browser restored old tabs from a previous session. SPA step transitions are asynchronous, so a fixed short wait races the re-render.
Gotchas
- Some services deactivate accounts that were created through an automated browser within minutes, and then ask for photo-ID verification to restore them. Don't automate signups you need to keep.
- Session restore after a killed browser can reopen many old tabs, and /json/list order is not reliable, so pick the target by URL
Code Snippets
Trusted click at element centre over CDP
const { result } = await send('Runtime.evaluate', { expression: `(() => { const el = document.querySelector(${JSON.stringify(sel)}); el.scrollIntoView({block:'center'}); const r = el.getBoundingClientRect(); return {x: r.x + r.width/2, y: r.y + r.height/2}; })()`, returnByValue: true });
for (const type of ['mouseMoved','mousePressed','mouseReleased'])
await send('Input.dispatchMouseEvent', { type, ...result.value, button: 'left', clickCount: 1 });Per-key typing for OTP boxes
for (const ch of code) {
await send('Input.dispatchKeyEvent', { type: 'keyDown', key: ch, text: ch });
await send('Input.dispatchKeyEvent', { type: 'keyUp', key: ch });
}Revisions (0)
No revisions yet.