Skip to content
PD
Browser Automation Studio

Finding Elements in BAS: Selectors That Don't Break

How element search works in Browser Automation Studio — CSS vs XPath selectors, why recorded ones break, and how to write selectors that survive page changes.

Every BAS action that touches the page — click, type, extract — first has to find the element. Get the selector right and your bot keeps working for months; get it wrong and it breaks the next time the site ships a redesign. This is the single most important skill for reliable browser automation.

How element search works in BAS

When you record an action, BAS captures a selector pointing at the element you interacted with. On replay, it queries the live DOM with that selector and acts on the match. The recorder is convenient, but it often picks fragile selectors — long chains of auto-generated classes or nth-child positions that change easily.

The fix is to treat the recorded selector as a draft and tighten it by hand.

CSS selectors: your default

CSS selectors cover the vast majority of cases and are the fastest option. The priority order for what to anchor on:

  1. id#login-button. Unique and stable when present.
  2. nameinput[name="email"]. Common and reliable on forms.
  3. data-* attributes[data-testid="submit"]. Often added by developers specifically as stable hooks.
  4. Semantic class or attribute combosbutton.primary[type="submit"].

Avoid anchoring on classes like css-1a2b3c — those are generated by build tools and change on every release.

XPath: when CSS isn’t enough

XPath is more powerful but slower and more verbose. Use it for the two things CSS can’t do:

  • Match by visible text: //button[contains(text(),"Sign in")] — invaluable when buttons have no stable attributes.
  • Navigate relative to another element: find a label, then its sibling input.

If you can express the target in CSS, prefer CSS. Drop to XPath only for text matching and relational queries.

Writing selectors that survive

  • Anchor on intent, not layout. [name="password"] describes what the field is; div:nth-child(3) > input describes where it happens to sit today.
  • Keep it short. Each extra step in the chain is another thing that can change.
  • Prefer one strong attribute over a long fragile path.
  • Test against reload. Re-run after a hard refresh; a good selector matches every time.

Handling timing, not just selection

A correct selector still fails if the element hasn’t rendered yet. Pages load asynchronously, so pair selection with a wait-for-element step before acting. Most “selector not found” errors are really timing errors — the element simply wasn’t there yet.

With solid selectors and waits in place, the next browser skill worth mastering is filling and submitting forms — covered in the companion article.

FAQ

Should I use CSS or XPath selectors in BAS?

Use CSS selectors for most cases — they are shorter and faster. Reach for XPath only when you need to match by visible text or navigate relative to another element, which CSS cannot do.

Why does my BAS bot stop finding an element?

Usually the selector relied on an auto-generated class or absolute position that changed on the next deploy. Anchor the selector to stable attributes like id, name, or data-* instead.

More on this topic

  • #Browser Automation Studio
  • #BAS
  • #Selectors
  • #CSS
  • #XPath

Have an idea? Let’s turn it into a working product.

Skip months of uncertainty. Get a clear architecture, a working MVP and a system you can test, sell and scale.