VLearnVibium

Finding Elements with the Accessibility Tree in Vibium

Use Vibium's a11y_tree() to inspect a page the way assistive tech sees it, then find and click elements by role and name — resilient, human-like selectors.

By Pramod Dutta··4 min read·Verified with Vibium 26.2
▶ Animated overview · made with Remotion

Vibium's a11y_tree() lets you inspect a page the way assistive technology sees it, then find elements by role and name instead of brittle CSS selectors. Each node carries a role (what it is) and often a name (its accessible label), which you can feed straight into find() to click and fill like a real user would.

What is the accessibility tree?

The accessibility tree is a structured view of every meaningful element on a page — the same model screen readers use. Instead of tags and classes, it describes roles: button, textbox, heading, checkbox. In Vibium you read it with a11y_tree(), which returns it as a plain Python dict.

Here's what the tree looks like for a login form:

{
    "role": "WebArea",
    "name": "Login",
    "children": [
        {"role": "heading", "level": 1},
        {"role": "textbox", "name": "Username"},
        {"role": "textbox", "name": "Password"},
        {"role": "checkbox", "name": "Remember me", "checked": False},
        {"role": "button", "name": "Sign in"}
    ]
}

Every node has a role. Nodes with explicit labels (aria-label, <label for>, and so on) also have a name, and many carry state like checked, disabled, or expanded.

How do you read the tree?

Launch a browser, open a page, and call a11y_tree():

from vibium import browser
 
bro = browser.launch()
vibe = bro.page()
vibe.go("https://example.com")
 
tree = vibe.a11y_tree()
print(tree)
 
bro.close()

By default the tree hides generic containers (plain divs and spans) so the output stays focused on meaningful elements. Pass everything=True to see all nodes, or root="nav" to scope the tree to one section of a complex page.

How do you turn the tree into action?

The tree tells you what's on the page; find() lets you act on it. Vibium's find() accepts semantic keyword arguments that mirror the tree:

# Tree shows: {"role": "button", "name": "Sign in"}  (name came from aria-label)
vibe.find(role="button", label="Sign in").click()
 
# For a button whose name comes from its visible text, use text:
vibe.find(role="button", text="Submit").click()

The key distinction is where the name comes from. Use label for explicit labels (aria-label, aria-labelledby, <label for>); use text for names that come from visible text content:

Source of the namefind() parameter
aria-label / aria-labelledbylabel
<label for="id"> elementlabel
Visible text contenttext
alt attribute (images)alt
placeholder attributeplaceholder

A practical workflow

The real power shows when you let a script — or an AI agent — discover the page at runtime, then act on what it found:

from vibium import browser
 
bro = browser.launch()
vibe = bro.page()
vibe.go("https://app.example.com/login")
 
# 1. Inspect the tree to understand the page
tree = vibe.a11y_tree()
 
# 2. Walk the tree to find a node by role
def find_by_role(node, role):
    if node["role"] == role:
        return node
    for child in node.get("children", []):
        found = find_by_role(child, role)
        if found:
            return found
    return None
 
btn = find_by_role(tree, "button")
print(f'Found: {btn["role"]} "{btn["name"]}"')   # Found: button "Sign in"
 
# 3. Fill inputs with CSS selectors (precise when you know the structure)
vibe.find("#user").fill("alice")
 
# 4. Click using the name discovered from the tree
vibe.find(role="button", label=btn["name"]).click()
 
bro.close()

The tree also exposes element state, so an agent can decide whether to act. For a checkbox, you can read checked and only click if it isn't already on:

checkbox = find_by_role(vibe.a11y_tree(), "checkbox")
if not checkbox.get("checked"):
    vibe.find(role="checkbox", label=checkbox["name"]).click()

CSS or semantic selectors — which one?

Both work; reach for the right one:

Use CSS selectors when...Use semantic selectors when...
Reading element state (text, value)Interacting (click, fill, check)
You know the exact HTML structureThe structure might change
Targeting by id or classFinding by role and name, like a user

Semantic selectors are why accessibility-tree finding is so resilient for AI agents: they describe intent ("the Sign in button") rather than implementation ("div.form > button:nth-child(3)"), so they survive markup changes.

One common gotcha: label only matches explicit labels. If a button's name comes from its visible text, find(role="button", label="Submit") won't match — use text instead.

Why this matters for Vibium

Finding by role and name is a natural fit for the AI-agent era Vibium targets. An agent can read the tree, understand the page semantically, and act — the same loop a person follows. It pairs perfectly with Vibium's built-in MCP server, which lets Claude drive the browser and reason about what it sees.

Next steps

Frequently asked questions

What is the accessibility tree in Vibium?

The accessibility tree is a structured view of every meaningful element on a page as assistive technology sees it — each node has a role and often a name. In Vibium you read it with a11y_tree(), which returns it as a Python dict you can inspect or feed into find().

How do I find an element by role in Vibium?

Call vibe.find() with semantic keyword arguments like role and label or text. For example, vibe.find(role='button', text='Submit').click() locates and clicks a button by what it is and what it says, instead of relying on a brittle CSS selector.

When should I use semantic selectors instead of CSS in Vibium?

Use semantic selectors (role plus label or text) when interacting with elements the way a user would, especially if the HTML structure may change. Use CSS selectors when reading element state or when you know the exact structure, such as targeting by id or class.

Vibium is created by Jason Huggins. This is an independent tutorial — see the official Vibium site and GitHub repo for canonical docs.

Related guides