For AI agents: a documentation index is available at /llms.txt
Skip to main content

Form Submission

The type, click, select, checkbox, and solve mutations let you fill, submit, and bypass CAPTCHAs in forms. BrowserQL handles element waiting, scrolling, and human-like input timing automatically.

Basic Usage

The example below navigates to a form, fills two fields, selects a dropdown option, solves a CAPTCHA, and then clicks submit. For explicit control over timing, see Waiting for Things.

mutation FormExample {
goto(url: "https://www.browserless.io/practice-form") {
status
}

typeEmail: type(text: "john@email.com", selector: "#Email") {
time
}

typeMessage: type(
selector: "#Message"
text: "Watching BrowserQL do cool things!"
) {
time
}

subject: select(selector: "select#Subject", value: "Support") {
selector
}

solve {
time
solved
}

submitForm: click(selector: "button[type='submit']") {
time
}
}

Deep Selectors for Iframes and Shadow DOM

Deep selectors target elements inside iframes or shadow DOMs. Add < at the start of any selector to enable deep traversal.

selector: "< [optional URL pattern] css-selector"
  • < signals a deep selector.
  • URL pattern (optional) matches the iframe source URL with glob syntax.
  • CSS selector identifies the target element inside the matched frame.

Target a button inside any iframe from cnn.com:

selector: "< *cnn.com* button#submit"
Restrictions
  • Parent-child combinators (e.g., div > span) are not supported in deep selectors.
  • Each deep selector must target a single node.

Humanized Typing and Clicking

BrowserQL types with randomized delays between keystrokes to mimic human behavior. Two ways to control this:

Query parameter: Add humanlike=true to the connection URL to enable human-like behavior globally for the session.

Per-mutation delay: Set a delay range on the type mutation to control keystroke timing explicitly.

mutation HumanizedForm {
goto(url: "https://www.browserless.io/practice-form") {
status
}

# Randomize keystroke delay between 80ms and 200ms
typeMessage: type(
selector: "#Message"
text: "Hello, this looks human!"
delay: [80, 200]
) {
time
}
}

For session-level configuration, see Session Settings.

Keyboard Events

BrowserQL does not have a dedicated mutation for sending keyboard events like Enter, Tab, or arrow keys. The recommended approach for form submission is to use click on the submit button (as shown in the examples above).

If you need to simulate keyboard events, you can use the evaluate mutation to dispatch KeyboardEvent objects:

warning

Events created via evaluate have isTrusted: false, and some sites may ignore untrusted events for security reasons.

mutation KeyboardEnter {
goto(url: "https://example.com/form") {
status
}

type(text: "search query", selector: "input[name='q']") {
time
}

pressEnter: evaluate(content: """
const enterEvent = new KeyboardEvent('keydown', {
key: 'Enter',
code: 'Enter',
keyCode: 13,
which: 13,
bubbles: true,
cancelable: true
});
document.activeElement.dispatchEvent(enterEvent);
""") {
value
}
}

Next Steps