Accessibility-focused DOM testing library for tdom, built with modern Python 3.14+.
π Full Documentation | π¦ * PyPI Package* | π * GitHub Repository*
aria-testing is a Python DOM testing library that provides accessibility-focused query functions for tdom. It follows
the DOM Testing Library philosophy: "The more your tests resemble the way your software is used, the more confidence
they can give you."
- β¨ Modern Python 3.14+ - Uses structural pattern matching, PEP 695 generics, and modern type hints
- π― Accessibility-first - Query by role, label text, and semantic attributes
- β‘ High performance - Optimized traversal with early-exit strategies
- π Type-safe - Full type annotations with strict type checking
- π§ͺ Well-tested - 179 tests, 100% passing, comprehensive coverage
uv add --dev aria-testingfrom tdom.processor import html
from aria_testing import get_by_role, get_by_text, get_by_label_text
# Create a tdom structure
document = html(t"""<div>
<h1>Welcome</h1>
<nav>
<a href="/home">Home</a>
</nav>
<form>
<label>Email
<input type="email" />
</label>
<button>Submit</button>
</form>
</div>""")
# Find elements using accessibility patterns
heading = get_by_role(document, "heading", level=1)
nav = get_by_role(document, "navigation")
link = get_by_role(document, "link", name="Home")
email_input = get_by_label_text(document, "Email")
button = get_by_text(document, "Submit")Queries are prioritized by accessibility best practices:
Find elements by their ARIA role - mirrors how screen readers interact with your app.
button = get_by_role(document, "button")
heading = get_by_role(document, "heading", level=1)
link = get_by_role(document, "link", name="Home")Find form elements by their associated label - how users identify form fields.
username = get_by_label_text(document, "Username")
email = get_by_label_text(document, "Email Address")Find elements by their text content.
button = get_by_text(document, "Click me")
heading = get_by_text(document, "Welcome")Find elements by data-testid attribute - useful when semantic queries aren't possible.
component = get_by_test_id(document, "user-menu")Find elements by HTML tag name - use sparingly, prefer semantic queries.
all_links = get_all_by_tag_name(document, "a")Find elements by HTML attributes - available but less recommended.
element = get_by_id(document, "main-content")
buttons = get_all_by_class(document, "btn-primary")Each query type comes in four variants for different use cases:
| Variant | Returns | Not Found | Multiple Found |
|---|---|---|---|
get_by_* |
Single element | β Raises error | β Raises error |
query_by_* |
Element or None | β Returns None | β Raises error |
get_all_by_* |
List of elements | β Raises error | β Returns all |
query_all_by_* |
List (possibly empty) | β
Returns [] |
β Returns all |
get_by_*: When element MUST exist and be unique (most common)query_by_*: When checking if element existsget_all_by_*: When multiple elements MUST existquery_all_by_*: When finding zero or more elements
Frozen dataclass-based assertion helpers for deferred execution in dynamic systems. Create assertions up front, apply them later when the DOM is available.
from aria_testing import GetByRole, GetAllByRole
# Define assertion early (no DOM needed yet)
assert_button = GetByRole(role="button").text_content("Save")
# Apply later when container becomes available
def verify_component(container):
assert_button(container) # Raises AssertionError if failsUse Cases:
- Component testing frameworks that render components dynamically
- Story-based testing where assertions are defined separately from execution
- Test fixtures that verify DOM structure after setup
- Reusable assertion sets applied across multiple test scenarios
Key Features:
- Immutable frozen dataclasses
- Fluent API:
.not_(),.text_content(),.with_attribute() - List operations:
.count(),.nth() - Type-safe with full IDE support
π See full documentation β
Built with cutting-edge Python 3.14+ features:
- Structural pattern matching (
match/case) for clean conditionals - PEP 695 generic functions for type-safe query factories
- Modern type hints (
X | Yunions, built-in generics) - Keyword-only arguments for clear, readable APIs
- Walrus operator (
:=) for concise, performant code
aria-testing is optimized for speed with multiple performance strategies:
Query Performance (200-element DOM on Python 3.14t free-threaded):
- Average query time: 3.99ΞΌs β‘ (21% faster than regular Python!)
- Role queries: 2.85ΞΌs
- Text queries: 12.18ΞΌs
- Class/tag queries: 2.34ΞΌs
Test Suite:
- 179 tests complete in 0.78 seconds (parallel mode)
- Average: 4.4ms per test
Free-Threading Advantage: Python 3.14t (no-GIL) is 21% faster than regular Python 3.14, even in single-threaded code, due to reduced GIL overhead and optimized reference counting for interned strings.
- Early-exit strategies - Stops searching after finding matches
- Iterative traversal - Non-recursive DOM traversal for large trees
- String interning - Fast identity-based comparisons for common roles
- Set-based class matching - O(1) class lookups
- Free-threading compatible - Full Python 3.14+ free-threading support (PEP 703)
aria-testing is fully thread-safe and designed for Python 3.14's free-threaded (no-GIL) interpreter:
β
No shared mutable state - All operations use function-local variables
β
Immutable data structures - Module constants use MappingProxyType
β
No locking required - Lock-free design for maximum performance
β
Parallel test execution - Works with pytest-xdist and concurrent.futures
The library was designed from the ground up for concurrent execution. Previous caching mechanisms were intentionally removed to ensure race-condition-free operation in multi-threaded environments.
π See detailed benchmarks β
Run benchmarks yourself:
just benchmark # Performance benchmark
just profile-queries # Detailed profiling- Python 3.14+
- tdom
π Read the full documentation on GitHub Pages β
The documentation includes:
- Complete API reference for all query functions
- Detailed guides on accessibility testing patterns
- Performance optimization techniques
- Type safety and modern Python features
- Advanced usage examples and best practices
MIT