Skip to content

test: Read accessibility descriptions and placeholders in element snapshots - #3672

Merged
huacnlee merged 1 commit into
longbridge:mainfrom
boboshan:test-support-description-placeholder
Oct 24, 2026
Merged

huacnlee merged 1 commit into
longbridge:mainfrom
boboshan:test-support-description-placeholder

Conversation

@boboshan

@boboshan boboshan commented Oct 24, 2026 •

Copy link
Copy Markdown
Contributor

Description

ElementSnapshot reads role, label, value and the state flags from an observed element's native node, but not its description or placeholder, so a UI test cannot check either on a painted element. Both reach assistive technology: Base's input editor writes aria_placeholder (gpui-component's Input passes its placeholder there), and the questionnaire and diff controls write aria_description. Today a test can only check them by building the element and calling write_a11y_info by hand, as focus_trap.rs and lifecycle.rs do, which reaches the outermost element and not one painted inside a view. GPUI's Window::debug_a11y_tree_json() includes both, but a test window never activates accessibility, so it returns None.

This follows #3531, which added disabled() the same way. Snapshots now record description and placeholder from the node they already read label from. A frame with a semantic owner takes both from its editor, like its other semantic facts, so an Input's placeholder is found through the component ID.

We need this in an application's tests: a picker trigger with nothing chosen gives its prompt as a placeholder and no value, so a screen reader does not read the prompt as the choice, and a toggle without a visible label announces its description.

Public API

gpui-base

  • test_support::ElementSnapshot::description(&self) -> Option<&str> — the accessibility description, read after the label; it does not replace it.
  • test_support::ElementSnapshot::placeholder(&self) -> Option<&str> — the accessibility placeholder, the prompt shown while the element has no value.

Both are also reachable through gpui_kit::test::ElementSnapshot. ElementSnapshot's Debug output lists the two fields after label.

How to Test

  • snapshot_reads_description_and_placeholder (crates/kit/tests/integration/lifecycle.rs) paints an observed div with a label, description and placeholder, and reads all three with no value.
  • placeholder_is_read_from_the_editor_and_is_not_a_value (crates/kit/tests/integration/input.rs) paints a component Input with a label and a placeholder, and reads the placeholder through the semantic owner with an empty value.
  • Negative controls: without the capture in prepaint, both tests fail; without the two fields in the semantic-owner snapshot, only the Input test fails.
  • The English and Chinese testing and accessibility guides list the two readers.
  • On this branch, macOS, Rust 1.99.1: cargo test -p gpui-kit --features test-support,component --locked, cargo test -p gpui-base --features test-support --lib --locked, cargo clippy -p gpui-base -p gpui-kit --features gpui-kit/test-support,gpui-kit/component --all-targets --locked -- --deny warnings, cargo fmt --all --check and typos 1.40.0.

Checklist

  • I have read the CONTRIBUTING document and followed the guidelines.
  • Reviewed the changes in this PR and confirmed AI generated code (If any) is accurate.
  • Passed cargo run for story tests related to the changes.
  • Tested macOS, Windows and Linux platforms performance (if the change is platform-specific)

🤖 Generated with Claude Code

…pshots

ElementSnapshot read role, label, value and the state flags from an
observed element's native node, but not its description or placeholder,
so a UI test could not check either on a painted element. Snapshots now
record both from the same node, and a frame with a semantic owner takes
them from its editor, so an Input's placeholder is found through its
component ID. Follows longbridge#3531, which added disabled() the same way.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@boboshan
boboshan marked this pull request as ready for review October 24, 2026 08:38
@huacnlee
huacnlee merged commit 7b14e03 into longbridge:main Oct 24, 2026
19 checks passed
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