Skip to content

Add supports for Accessibility domain#378

Open
j0j1j2 wants to merge 1 commit intoautoscrape-labs:mainfrom
j0j1j2:feat/impl-accessibility-domain
Open

Add supports for Accessibility domain#378
j0j1j2 wants to merge 1 commit intoautoscrape-labs:mainfrom
j0j1j2:feat/impl-accessibility-domain

Conversation

@j0j1j2
Copy link
Contributor

@j0j1j2 j0j1j2 commented Mar 6, 2026

Pull Request

Description

I have added support for the Chrome DevTools Protocol's Accessibility domain. Users can now inspect the accessibility tree and retrieve essential accessibility metadata directly, facilitating easier auditing and support for accessible web development. Furthermore, this structured data enhances the LLM's ability to parse and understand the page document more accurately.

image

Related Issue(s)

Type of Change

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to not work as expected)
  • Documentation update
  • Refactoring (no functional changes, no API changes)
  • Performance improvement
  • Tests (adding missing tests or correcting existing tests)
  • Build or CI/CD related changes

How Has This Been Tested?

I've created test code on tests/test_commands/test_accessibility_commands.py.
In addition to test, you can test accessiblity domain with this code snippet.

import asyncio

from pydoll.browser import Chrome
from pydoll.commands.accessibility_commands import AccessibilityCommands
from pydoll.protocol.accessibility.types import AXNode

MAX_LINKS_SHOWN = 10


# ---------------------------------------------------------------------------
# Helpers
# ---------------------------------------------------------------------------

def _label(node: AXNode) -> str:
    """Return a one-line description of an AX node."""
    role = node.get('role', {}).get('value', '?')
    name_val = node.get('name', {}).get('value', '')
    ignored = node.get('ignored', False)

    parts = [f'[{role}]']
    if name_val:
        parts.append(f'"{name_val}"')
    if ignored:
        reasons = [str(r.get('name', '')) for r in node.get('ignoredReasons', [])]
        parts.append(f'(ignored: {", ".join(r for r in reasons if r)})')
    return ' '.join(parts)


def _build_index(nodes: list[AXNode]) -> dict[str, AXNode]:
    return {n['nodeId']: n for n in nodes}


def _print_tree(node: AXNode, index: dict[str, AXNode], indent: int = 0) -> None:
    """Recursively print the accessibility tree."""
    prefix = '  ' * indent + ('└─ ' if indent else '')
    print(f'{prefix}{_label(node)}')
    for child_id in node.get('childIds', []):
        child = index.get(child_id)
        if child:
            _print_tree(child, index, indent + 1)


def _nodes(response: dict) -> list[AXNode]:
    """Safely extract a node list from a CDP response."""
    return response.get('result', {}).get('nodes', [])


# ---------------------------------------------------------------------------
# Per-section audit functions
# ---------------------------------------------------------------------------

async def _print_root_info(page) -> tuple[str, int | None]:
    """Fetch and display the root AX node. Returns (root_id, backend_id)."""
    response = await page._execute_command(AccessibilityCommands.get_root_ax_node())
    root_node: AXNode = response.get('result', {}).get('node', {})
    root_id = root_node.get('nodeId', '')
    backend_id = root_node.get('backendDOMNodeId')
    print(f'Root AX node  → {_label(root_node)}')
    print(f'Root node ID  → {root_id}')
    return root_id, backend_id


async def _print_full_tree(page) -> None:
    """Fetch and display the full AX tree (depth ≤ 4)."""
    response = await page._execute_command(
        AccessibilityCommands.get_full_ax_tree(depth=4)
    )
    all_nodes: list[AXNode] = _nodes(response)
    print(f'Total AX nodes in tree (depth≤4): {len(all_nodes)}\n')

    index = _build_index(all_nodes)
    document_node = next((n for n in all_nodes if not n.get('parentId')), None)
    if document_node:
        print('── Accessibility tree (truncated) ─────────────────────────')
        _print_tree(document_node, index)


async def _print_headings(page) -> None:
    """Query and print all heading nodes."""
    response = await page._execute_command(
        AccessibilityCommands.query_ax_tree(role='heading')
    )
    headings: list[AXNode] = _nodes(response)
    print(f'── Headings found: {len(headings)} ──────────────────────────────')
    for h in headings:
        level = next(
            (
                p.get('value', {}).get('value')
                for p in h.get('properties', [])
                if p.get('name') == 'level'
            ),
            None,
        )
        name = h.get('name', {}).get('value', '<no name>')
        level_str = f' (level={level})' if level else ''
        print(f'  {name}{level_str}')


async def _print_links(page) -> None:
    """Query and print link nodes."""
    response = await page._execute_command(
        AccessibilityCommands.query_ax_tree(role='link')
    )
    links: list[AXNode] = _nodes(response)
    print(f'── Links found: {len(links)} ─────────────────────────────────────')
    for link in links[:MAX_LINKS_SHOWN]:
        name = link.get('name', {}).get('value', '<no name>')
        print(f'  • {name}')
    if len(links) > MAX_LINKS_SHOWN:
        print(f'  … and {len(links) - MAX_LINKS_SHOWN} more')


async def _print_partial_and_ancestors(page, backend_id: int) -> None:
    """Fetch and display partial subtree and ancestors for a backend node."""
    partial_response = await page._execute_command(
        AccessibilityCommands.get_partial_ax_tree(
            backend_node_id=backend_id,
            fetch_relatives=False,
        )
    )
    partial_nodes: list[AXNode] = _nodes(partial_response)
    print(
        f'── Partial tree for root (backendNodeId={backend_id}): '
        f'{len(partial_nodes)} node(s)'
    )
    for n in partial_nodes[:5]:
        print(f'  {_label(n)}')

    ancestors_response = await page._execute_command(
        AccessibilityCommands.get_ax_node_and_ancestors(backend_node_id=backend_id)
    )
    ancestors: list[AXNode] = ancestors_response.get('result', {}).get('nodes', [])
    print(f'── Ancestors of root (including self): {len(ancestors)} node(s)')
    for a in ancestors:
        print(f'  {_label(a)}')


async def _print_children(page, root_id: str) -> None:
    """Fetch and display direct children of the root AX node."""
    response = await page._execute_command(
        AccessibilityCommands.get_child_ax_nodes(id=root_id)
    )
    children: list[AXNode] = _nodes(response)
    print(f'── Direct children of root AX node: {len(children)} node(s)')
    for c in children:
        print(f'  {_label(c)}')


# ---------------------------------------------------------------------------
# Main
# ---------------------------------------------------------------------------

async def run_audit(url: str) -> None:
    browser = Chrome()
    page = await browser.start()

    print(f'\n{"=" * 60}')
    print(f'Accessibility Audit: {url}')
    print('=' * 60)

    await page.go_to(url)
    print('Page loaded.\n')

    await page._execute_command(AccessibilityCommands.enable())
    print('Accessibility domain enabled.\n')

    root_id, backend_id = await _print_root_info(page)
    print()

    await _print_full_tree(page)
    print()

    await _print_headings(page)
    print()

    await _print_links(page)
    print()

    if backend_id:
        await _print_partial_and_ancestors(page, backend_id)
        print()

    await _print_children(page, root_id)
    print()

    await page._execute_command(AccessibilityCommands.disable())
    print('Accessibility domain disabled.')

    await browser.stop()
    print('Browser closed.\n')


if __name__ == '__main__':
    asyncio.run(run_audit('https://www.ebay.com'))

Testing Checklist

  • Unit tests added/updated
  • Integration tests added/updated
  • All existing tests pass

Screenshots

Implementation Details

API Changes

Additional Info

Checklist before requesting a review

  • My code follows the style guidelines of this project
  • I have performed a self-review of my code
  • I have commented my code, particularly in hard-to-understand areas
  • I have made corresponding changes to the documentation
  • My changes generate no new warnings
  • I have added tests that prove my fix is effective or that my feature works
  • New and existing unit tests pass locally with my changes
  • I have run poetry run task lint and fixed any issues
  • I have run poetry run task test and all tests pass
  • My commits follow the conventional commits style

Summary by CodeRabbit

  • New Features

    • Added accessibility tree inspection and querying capabilities, enabling command-based access to accessibility domain information including tree navigation, node inspection, and property queries.
  • Tests

    • Added comprehensive test suite for accessibility command functionality.

@coderabbitai
Copy link

coderabbitai bot commented Mar 6, 2026

📝 Walkthrough

Walkthrough

This pull request introduces a new Accessibility domain implementation for the pydoll Chrome DevTools Protocol library, including command factory methods, comprehensive type definitions, event structures, and test coverage for accessibility tree operations.

Changes

Cohort / File(s) Summary
Command Factory
pydoll/commands/accessibility_commands.py, pydoll/commands/__init__.py
Introduces AccessibilityCommands class with eight static factory methods (disable, enable, get_partial_ax_tree, get_full_ax_tree, get_root_ax_node, get_ax_node_and_ancestors, get_child_ax_nodes, query_ax_tree) that construct CDP Command objects with appropriate parameters. Exports AccessibilityCommands in module public API.
Protocol Types
pydoll/protocol/accessibility/types.py
Defines comprehensive accessibility type system including AXNodeId, AXValueType, AXValueSourceType, AXValueNativeSourceType, AXPropertyName enums; TypedDict structures for AXRelatedNode, AXValueSource, AXValue, AXProperty, and AXNode representing the accessibility tree model.
Protocol Methods
pydoll/protocol/accessibility/methods.py
Establishes AccessibilityMethod enum with eight command identifiers and corresponding TypedDict parameter/result structures (GetPartialAXTreeParams, GetFullAXTreeParams, GetRootAXNodeParams, GetAXNodeAndAncestorsParams, GetChildAXNodesParams, QueryAXTreeParams) and response types; exports command type aliases.
Protocol Events
pydoll/protocol/accessibility/events.py
Adds AccessibilityEvent enum with LOAD_COMPLETE and NODES_UPDATED events; defines LoadCompleteEventParams and NodesUpdatedEventParams TypedDicts; exports strongly-typed event aliases.
Package Init
pydoll/protocol/accessibility/__init__.py
Adds package initializer with module docstring for Accessibility domain implementation.
Test Coverage
tests/test_commands/test_accessibility_commands.py
Comprehensive parametric test suite validating AccessibilityCommands factory methods generate correct CDP methods, properly includes/omits optional parameters, and handles parameter combinations across all eight commands.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Poem

🐰 A-eleven commands hop into view,
With access trees structured bright and true,
Types and params, all neatly defined,
Events and methods, perfectly aligned—
The accessibility realm takes flight! 🌳✨

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 14.81% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Title check ✅ Passed The title 'Add supports for Accessibility domain' clearly summarizes the main change in the PR, which adds comprehensive support for the Chrome DevTools Protocol Accessibility domain.
Description check ✅ Passed The PR description is comprehensive and mostly complete. It includes a clear description of the feature, related test code, practical examples, and demonstrates testing completion with the testing checklist properly filled out.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

Tip

Try Coding Plans. Let us write the prompt for your AI agent so you can ship faster (with fewer bugs).
Share your feedback on Discord.


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@codecov
Copy link

codecov bot commented Mar 6, 2026

Codecov Report

❌ Patch coverage is 93.56061% with 17 lines in your changes missing coverage. Please review.

Files with missing lines Patch % Lines
pydoll/protocol/accessibility/events.py 0.00% 15 Missing ⚠️
pydoll/commands/accessibility_commands.py 97.14% 2 Missing ⚠️

📢 Thoughts on this report? Let us know!

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🧹 Nitpick comments (1)
pydoll/protocol/accessibility/methods.py (1)

52-57: Make id required in GetChildAXNodesParams.

The CDP docs define getChildAXNodes around an AXNodeId, and only frameId is described as omittable. Keeping this TypedDict as total=False weakens the public type and lets empty/invalid param shapes pass static checks. (chromedevtools.github.io)

💡 Proposed fix
-class GetChildAXNodesParams(TypedDict, total=False):
+class GetChildAXNodesParams(TypedDict):
     """Parameters for getChildAXNodes command."""
 
     id: AXNodeId
-    frameId: str
+    frameId: NotRequired[str]

Add the missing import at the top of the file:

from typing_extensions import NotRequired, TypedDict
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@pydoll/protocol/accessibility/methods.py` around lines 52 - 57,
GetChildAXNodesParams currently uses total=False making all keys optional;
change the TypedDict so AXNodeId 'id' is required and 'frameId' remains optional
by importing and using NotRequired from typing_extensions (or make total=True
and mark frameId as NotRequired) so that GetChildAXNodesParams requires id:
AXNodeId while frameId stays optional.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@pydoll/commands/accessibility_commands.py`:
- Around line 190-225: The query_ax_tree function currently allows no selector
params and sends empty QueryAXTreeParams to the protocol; add a local validation
at the start of query_ax_tree to ensure at least one of node_id,
backend_node_id, or object_id is provided and raise a ValueError with a clear
message if none are set, then proceed to build params (QueryAXTreeParams) and
return the Command (AccessibilityMethod.QUERY_AX_TREE) as before; also update
the function docstring briefly to state that one of
node_id/backend_node_id/object_id is required.

In `@pydoll/protocol/accessibility/types.py`:
- Around line 57-107: AXPropertyName enum is missing many Accessibility domain
values causing payloads to be unsupported; update the AXPropertyName class to
include the remaining property names from the Chrome DevTools Protocol schema —
add "actions" and "url" plus the 17 hidden-reason values (the
hidden/visibility-related keys starting from activeFullscreenElement through
uninteresting) as enum members, keeping the existing str, Enum inheritance and
docstring; ensure the member names follow existing naming style (UPPER_SNAKE or
exact names used elsewhere) and string values match the protocol (e.g.,
'actions', 'url', 'activeFullscreenElement', ..., 'uninteresting'), so code that
parses Accessibility payloads finds all valid AXPropertyName values.

---

Nitpick comments:
In `@pydoll/protocol/accessibility/methods.py`:
- Around line 52-57: GetChildAXNodesParams currently uses total=False making all
keys optional; change the TypedDict so AXNodeId 'id' is required and 'frameId'
remains optional by importing and using NotRequired from typing_extensions (or
make total=True and mark frameId as NotRequired) so that GetChildAXNodesParams
requires id: AXNodeId while frameId stays optional.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 47f39e82-dca1-498f-af25-3da57cb6fc12

📥 Commits

Reviewing files that changed from the base of the PR and between e184833 and bd33dff.

📒 Files selected for processing (7)
  • pydoll/commands/__init__.py
  • pydoll/commands/accessibility_commands.py
  • pydoll/protocol/accessibility/__init__.py
  • pydoll/protocol/accessibility/events.py
  • pydoll/protocol/accessibility/methods.py
  • pydoll/protocol/accessibility/types.py
  • tests/test_commands/test_accessibility_commands.py

Comment on lines +190 to +225
def query_ax_tree(
node_id: Optional[int] = None,
backend_node_id: Optional[int] = None,
object_id: Optional[str] = None,
accessible_name: Optional[str] = None,
role: Optional[str] = None,
) -> QueryAXTreeCommand:
"""
Queries the accessibility tree for a DOM subtree for nodes with a
given name and/or role.

Args:
node_id: Identifier of the node for the root of the subtree to
search in.
backend_node_id: Identifier of the backend node for the root of
the subtree to search in.
object_id: JavaScript object id of the node wrapper for the root
of the subtree to search in.
accessible_name: Find nodes with this computed name.
role: Find nodes with this computed role.

Returns:
QueryAXTreeCommand: CDP command to query the AX tree.
"""
params = QueryAXTreeParams()
if node_id is not None:
params['nodeId'] = node_id
if backend_node_id is not None:
params['backendNodeId'] = backend_node_id
if object_id is not None:
params['objectId'] = object_id
if accessible_name is not None:
params['accessibleName'] = accessible_name
if role is not None:
params['role'] = role
return Command(method=AccessibilityMethod.QUERY_AX_TREE, params=params)
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🌐 Web query:

Chrome DevTools Protocol Accessibility queryAXTree parameters requirements

💡 Result:

Accessibility.queryAXTree requires you to specify the root DOM node to query, using exactly one of these identifiers (otherwise CDP returns an error): nodeId, backendNodeId, or objectId. [1]

Filtering parameters are optional:

  • accessibleName (string): match nodes by computed accessible name. [1]
  • role (string): match nodes by computed accessible role. [1]
  • If neither accessibleName nor role is provided, it returns all accessibility nodes in the specified node’s subtree. [1]

Related note: Accessibility.enable() is not listed as a prerequisite for queryAXTree, but enabling the domain is what makes AXNodeIds remain consistent across calls. [1]

Sources
[1] Chrome DevTools Protocol (tip-of-tree): Accessibility domain – Accessibility.queryAXTree documentation. (chromedevtools.github.io)

Citations:


🏁 Script executed:

# Find test files related to query_ax_tree
find . -type f -name "*.py" | xargs grep -l "query_ax_tree" | head -20

Repository: autoscrape-labs/pydoll

Length of output: 162


🏁 Script executed:

# Get context around the test assertions for query_ax_tree
rg -A 10 -B 5 "query_ax_tree" --type py | head -100

Repository: autoscrape-labs/pydoll

Length of output: 8195


Add validation: query_ax_tree() requires one of node_id, backend_node_id, or object_id.

The Chrome DevTools Protocol requires exactly one DOM node selector for queryAXTree; the protocol returns an error when none are specified. The current implementation permits calling with no arguments (resulting in params={}), and the new tests explicitly assert this invalid state is acceptable. Validate locally to fail fast with a clear ValueError rather than a round-trip protocol failure.

Proposed fix
     def query_ax_tree(
         node_id: Optional[int] = None,
         backend_node_id: Optional[int] = None,
         object_id: Optional[str] = None,
         accessible_name: Optional[str] = None,
         role: Optional[str] = None,
     ) -> QueryAXTreeCommand:
@@
+        if node_id is None and backend_node_id is None and object_id is None:
+            raise ValueError(
+                'query_ax_tree requires one of node_id, backend_node_id, or object_id'
+            )
+
         params = QueryAXTreeParams()
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@pydoll/commands/accessibility_commands.py` around lines 190 - 225, The
query_ax_tree function currently allows no selector params and sends empty
QueryAXTreeParams to the protocol; add a local validation at the start of
query_ax_tree to ensure at least one of node_id, backend_node_id, or object_id
is provided and raise a ValueError with a clear message if none are set, then
proceed to build params (QueryAXTreeParams) and return the Command
(AccessibilityMethod.QUERY_AX_TREE) as before; also update the function
docstring briefly to state that one of node_id/backend_node_id/object_id is
required.

Comment on lines +57 to +107
class AXPropertyName(str, Enum):
"""Values of AXProperty name.

See https://chromedevtools.github.io/devtools-protocol/tot/Accessibility/#type-AXPropertyName
"""

# States
BUSY = 'busy'
DISABLED = 'disabled'
EDITABLE = 'editable'
FOCUSABLE = 'focusable'
FOCUSED = 'focused'
HIDDEN = 'hidden'
HIDDEN_ROOT = 'hiddenRoot'
INVALID = 'invalid'
KEYSHORTCUTS = 'keyshortcuts'
SETTABLE = 'settable'
ROLEDESCRIPTION = 'roledescription'
# Live region attributes
LIVE = 'live'
ATOMIC = 'atomic'
RELEVANT = 'relevant'
ROOT = 'root'
# Widget attributes
AUTOCOMPLETE = 'autocomplete'
HAS_POPUP = 'hasPopup'
LEVEL = 'level'
MULTISELECTABLE = 'multiselectable'
ORIENTATION = 'orientation'
MULTILINE = 'multiline'
READONLY = 'readonly'
REQUIRED = 'required'
VALUEMIN = 'valuemin'
VALUEMAX = 'valuemax'
VALUETEXT = 'valuetext'
# Widget states
CHECKED = 'checked'
EXPANDED = 'expanded'
MODAL = 'modal'
PRESSED = 'pressed'
SELECTED = 'selected'
# Relationship attributes
ACTIVEDESCENDANT = 'activedescendant'
CONTROLS = 'controls'
DESCRIBEDBY = 'describedby'
DETAILS = 'details'
ERRORMESSAGE = 'errormessage'
FLOWTO = 'flowto'
LABELLEDBY = 'labelledby'
OWNS = 'owns'

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

cat -n pydoll/protocol/accessibility/types.py | sed -n '57,107p'

Repository: autoscrape-labs/pydoll

Length of output: 1758


🌐 Web query:

Chrome DevTools Protocol Accessibility AXPropertyName allowed values schema

💡 Result:

In the Chrome DevTools Protocol (CDP) Accessibility domain, AXPropertyName is a string enum defined in the protocol schema.

Where it’s defined (schema)

  • In the published protocol JSON schema (npm devtools-protocol), see json/browser_protocol.jsondomains[]Accessibilitytypes[]id: "AXPropertyName""enum": [...]. The enum values there are:
    busy, disabled, hidden, hiddenRoot, invalid, keyshortcuts, roledescription, live, atomic, relevant, root, autocomplete, haspopup, level, multiselectable, orientation, multiline, readonly, required, valuemin, valuemax, valuetext, checked, expanded, modal, pressed, selected, activedescendant, controls, describedby, details, errormessage, flowto, labelledby, owns. [2]

Protocol viewer (“Allowed Values”)

The protocol viewer page for Accessibility.AXPropertyName often shows a larger set of “Allowed Values” (including additional/internal names such as actions, editable, focusable, focused, settable, plus various internal flags like uninteresting, etc.). [1]

If you need the authoritative list for codegen/validation, use the JSON schema enum from browser_protocol.json; if you’re matching what DevTools UI may surface, consult the protocol viewer list too. [1][2]


🌐 Web query:

devtools-protocol npm AXPropertyName complete enum values browser_protocol.json

💡 Result:

In browser_protocol.json (CDP Accessibility.AXPropertyName), the enum values are:

actions
busy
disabled
editable
focusable
focused
hidden
hiddenRoot
invalid
keyshortcuts
settable
roledescription
live
atomic
relevant
root
autocomplete
hasPopup
level
multiselectable
orientation
multiline
readonly
required
valuemin
valuemax
valuetext
checked
expanded
modal
pressed
selected
activedescendant
controls
describedby
details
errormessage
flowto
labelledby
owns
url
activeFullscreenElement
activeModalDialog
activeAriaModalDialog
ariaHiddenElement
ariaHiddenSubtree
emptyAlt
emptyText
inertElement
inertSubtree
labelContainer
labelFor
notRendered
notVisible
presentationalRole
probablyPresentational
inactiveCarouselTabContent
uninteresting

[1]


🏁 Script executed:

# Check if there's any reference documentation or schema in the repo
find . -type f -name "*protocol*" -o -name "*schema*" | grep -i access | head -20

Repository: autoscrape-labs/pydoll

Length of output: 48


Complete the AXPropertyName enum with all valid Accessibility domain values.

The enum is incomplete. According to the official Chrome DevTools Protocol schema, it should include actions, url, and 17 hidden-reason values (activeFullscreenElement through uninteresting). The current implementation stops at owns, leaving 23 valid property names out of the enum, which breaks support for legitimate Accessibility payloads.

💡 Proposed fix
 class AXPropertyName(str, Enum):
     """Values of AXProperty name.
 
     See https://chromedevtools.github.io/devtools-protocol/tot/Accessibility/#type-AXPropertyName
     """
 
     # States
+    ACTIONS = 'actions'
     BUSY = 'busy'
     DISABLED = 'disabled'
     EDITABLE = 'editable'
     FOCUSABLE = 'focusable'
     FOCUSED = 'focused'
     HIDDEN = 'hidden'
     HIDDEN_ROOT = 'hiddenRoot'
     INVALID = 'invalid'
     KEYSHORTCUTS = 'keyshortcuts'
     SETTABLE = 'settable'
     ROLEDESCRIPTION = 'roledescription'
     # Live region attributes
     LIVE = 'live'
     ATOMIC = 'atomic'
     RELEVANT = 'relevant'
     ROOT = 'root'
     # Widget attributes
     AUTOCOMPLETE = 'autocomplete'
     HAS_POPUP = 'hasPopup'
     LEVEL = 'level'
     MULTISELECTABLE = 'multiselectable'
     ORIENTATION = 'orientation'
     MULTILINE = 'multiline'
     READONLY = 'readonly'
     REQUIRED = 'required'
     VALUEMIN = 'valuemin'
     VALUEMAX = 'valuemax'
     VALUETEXT = 'valuetext'
     # Widget states
     CHECKED = 'checked'
     EXPANDED = 'expanded'
     MODAL = 'modal'
     PRESSED = 'pressed'
     SELECTED = 'selected'
     # Relationship attributes
     ACTIVEDESCENDANT = 'activedescendant'
     CONTROLS = 'controls'
     DESCRIBEDBY = 'describedby'
     DETAILS = 'details'
     ERRORMESSAGE = 'errormessage'
     FLOWTO = 'flowto'
     LABELLEDBY = 'labelledby'
     OWNS = 'owns'
     URL = 'url'
     # Hidden reasons
+    ACTIVE_FULLSCREEN_ELEMENT = 'activeFullscreenElement'
+    ACTIVE_MODAL_DIALOG = 'activeModalDialog'
+    ACTIVE_ARIA_MODAL_DIALOG = 'activeAriaModalDialog'
+    ARIA_HIDDEN_ELEMENT = 'ariaHiddenElement'
+    ARIA_HIDDEN_SUBTREE = 'ariaHiddenSubtree'
+    EMPTY_ALT = 'emptyAlt'
+    EMPTY_TEXT = 'emptyText'
+    INERT_ELEMENT = 'inertElement'
+    INERT_SUBTREE = 'inertSubtree'
+    LABEL_CONTAINER = 'labelContainer'
+    LABEL_FOR = 'labelFor'
+    NOT_RENDERED = 'notRendered'
+    NOT_VISIBLE = 'notVisible'
+    PRESENTATIONAL_ROLE = 'presentationalRole'
+    PROBABLY_PRESENTATIONAL = 'probablyPresentational'
+    INACTIVE_CAROUSEL_TAB_CONTENT = 'inactiveCarouselTabContent'
+    UNINTERESTING = 'uninteresting'
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@pydoll/protocol/accessibility/types.py` around lines 57 - 107, AXPropertyName
enum is missing many Accessibility domain values causing payloads to be
unsupported; update the AXPropertyName class to include the remaining property
names from the Chrome DevTools Protocol schema — add "actions" and "url" plus
the 17 hidden-reason values (the hidden/visibility-related keys starting from
activeFullscreenElement through uninteresting) as enum members, keeping the
existing str, Enum inheritance and docstring; ensure the member names follow
existing naming style (UPPER_SNAKE or exact names used elsewhere) and string
values match the protocol (e.g., 'actions', 'url', 'activeFullscreenElement',
..., 'uninteresting'), so code that parses Accessibility payloads finds all
valid AXPropertyName values.

@thalissonvs
Copy link
Member

thanks @j0j1j2 ! I'll review as soon as I can

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants