Skip to content

Add some violations in a11y inspector - #191994

Merged
hannah-hyj merged 14 commits into
flutter:masterfrom
hannah-hyj:add-issues-in-a11y-inspector
Oct 9, 2026
Merged

hannah-hyj merged 14 commits into
flutter:masterfrom
hannah-hyj:add-issues-in-a11y-inspector

Conversation

@hannah-hyj

@hannah-hyj hannah-hyj commented Aug 28, 2026 •

Copy link
Copy Markdown
Member

Make the traverse function in [_accessibility_evaluations.dart] public.
Add violations in a11y inspector.

tracking issue: flutter/devtools#9893

Pre-launch Checklist

If you need help, consider asking for advice on the #hackers-new channel on Discord.

If this change needs to override an active code freeze, provide a comment explaining why. The code freeze workflow can be overridden by code reviewers. See pinned issues for any active code freezes with guidance.

Note: The Flutter team is currently trialing the use of Gemini Code Assist for GitHub. Comments from the gemini-code-assist bot should not be taken as authoritative feedback from the Flutter team. If you find its comments useful you can update your code accordingly, but if you are unsure or disagree with the feedback, please feel free to wait for a Flutter team member's review for guidance on which automated comments should be addressed.

@flutter-dashboard flutter-dashboard Bot added the CICD Run CI/CD label Aug 28, 2026
@github-actions github-actions Bot added framework flutter/packages/flutter repository. See also f: labels. a: accessibility Accessibility, e.g. VoiceOver or TalkBack. (aka a11y) labels Aug 28, 2026

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Code Review

This pull request integrates accessibility evaluations into the AccessibilityInspector to append detected accessibility issues, such as tap target size, missing labels, and unlabeled leaf nodes, directly to the JSON representation of semantics nodes. To support this, the traversal methods in several accessibility evaluations were made public. Feedback suggests simplifying the retrieval of the PipelineOwner by utilizing the new _findRenderView helper, which would eliminate the redundant _findPipelineOwner method.

@hannah-hyj
hannah-hyj requested a review from chunhtai August 28, 2026 20:37

List<Violation> _traverse(SemanticsNode node) {
/// Traverses the given [node] and returns all found violations.
List<Violation> traverse(SemanticsNode node) {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

we should consider move traverse to base class if this is going to be the entry point of evaluation, I originally created evaluate method as entry point to work with bindings, should remove that if that is not useful.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

added traverse in the base class

nodes[node.id.toString()] = node.toJson();

nodes[node.id.toString()] = <String, Object?>{
...node.toJson(),

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

why expand the map? if we are going to inject other property like issues in line 132, we should probably put node.toJson as a object of its own to avoid property override

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

sounds good!

}

// TODO(hannahjin): This returns the first SemanticsOwner of any RenderView.
// TODO(hannah-hyj): This returns the first RenderView with a SemanticsOwner.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

We should file an issue for this

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

chunhtai
chunhtai previously approved these changes Sep 1, 2026

@chunhtai chunhtai left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

LGTM, except some minor comments

}

/// Evaluate whether the current state of the `binding` conforms to the rule.
FutureOr<EvaluationResult> evaluate(WidgetsBinding binding) {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

if there is practical use case this method, we should remove it

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Looks like evaluate(binding) is still necessary because evaluations like MinimumTextContrastEvaluation (which asynchronously rasterizes renderView.debugLayer to check pixel contrast) and TitleEvaluation (which inspects the element tree via binding.rootElement) require WidgetsBinding and cannot be implemented as a synchronous traverse(SemanticsNode)."

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Is it possible to have a single entry point for all the guideline? better to keep it unify and abstract.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

updated the PR and removed removed traverse() from the Public API, evaluate() will be the single entry point.

@chunhtai chunhtai left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

my latest comment #191994 (comment)

@hannah-hyj
hannah-hyj force-pushed the add-issues-in-a11y-inspector branch from d0870e6 to 174cd00 Compare September 23, 2026 00:25
@hannah-hyj
hannah-hyj requested a review from chunhtai September 23, 2026 00:26
@hannah-hyj

Copy link
Copy Markdown
Member Author

@chunhtai comment resolved!

}

// The violations are displayed in Devtool.
// TODO(hannah-hyj): If we add a "target platforms" option on the devtool side,

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I imagine this should be something set by the devtools instead of hardcoded in framework

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

yeah that's why I added a TODO here, should pass the target platform from the devtool

expect(labeledResult['result'], isEmpty);
final Map<String, Object?> labeledTapTargetResult = await _runEvaluation(
tester,
<String, String>{'type': 'LabeledTapTargetEvaluation'},

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

This string should be defined somewhere same for other checks

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Added AccessibilityEvaluationType enum and AccessibilityInspectorKeys constants

final nodeIssues = <int, List<Map<String, Object?>>>{};

final evaluations = <(AccessibilityEvaluation, String)>[
(MinimumTapTargetEvaluation(size: minSize), 'tapTargetSize'),

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

looks like we will have a bunch of strings. We should define them in somewhere and document how each strings are used.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Added AccessibilityEvaluationType enum and AccessibilityInspectorKeys constants

@victorsanni
victorsanni removed their request for review September 24, 2026 21:38
@hannah-hyj
hannah-hyj requested a review from chunhtai September 25, 2026 03:39
@hannah-hyj
hannah-hyj force-pushed the add-issues-in-a11y-inspector branch from 5b0c1b0 to df98f5a Compare September 25, 2026 03:59
@@ -62,17 +92,54 @@ class AccessibilityInspector {
/// Evaluates and returns the semantics tree hierarchy of the application.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

We probably shouldn't mixing evaluation result with semantics tree. We may have more guideline later on that doesn't tight to semantics tree. for example the TitleEvaluation

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Updated! now it returnes evaluation results under the top-level AccessibilityInspectorKeys.issues key

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I meant should we have two endpoints, one for getting semantics tree only, the other for getting violations? The current endpoint, If one only wants to get semantics tree, they will also have to wait for inspection result even if they don't need it.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

i worry if there're two endpoints , one for getting semantics tree only, one for getting violations only, they may be called in different frames and the results dont match.
I updated it to two endpoints, but one for getting semantics tree only, one for getting tree and violations, wdyt?

@chunhtai chunhtai Oct 8, 2026 •

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

ok that sounds good

@hannah-hyj
hannah-hyj requested a review from chunhtai October 1, 2026 19:30

@chunhtai chunhtai left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

my latest comment #191994 (comment)

@hannah-hyj
hannah-hyj requested a review from chunhtai October 6, 2026 20:37

@chunhtai chunhtai left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

LGTM

@hannah-hyj
hannah-hyj added this pull request to the merge queue Oct 9, 2026
Merged via the queue into flutter:master with commit 6cfc099 Oct 9, 2026
18 checks passed
@hannah-hyj
hannah-hyj deleted the add-issues-in-a11y-inspector branch October 9, 2026 03:44
suryaKommana2662 pushed a commit to suryaKommana2662/flutter that referenced this pull request Oct 29, 2026
Make the traverse function in [_accessibility_evaluations.dart] public.
Add violations in a11y inspector.

tracking issue: flutter/devtools#9893



## Pre-launch Checklist

- [ ] I read the [Contributor Guide] and followed the process outlined
there for submitting PRs.
- [ ] I read the [AI contribution guidelines] and understand my
responsibilities, or I am not using AI tools.
- [ ] I read the [Tree Hygiene] wiki page, which explains my
responsibilities.
- [ ] I read and followed the [Flutter Style Guide], including [Features
we expect every widget to implement].
- [ ] I signed the [CLA].
- [ ] I listed at least one issue that this PR fixes in the description
above.
- [ ] I updated/added relevant documentation (doc comments with `///`).
- [ ] I added new tests to check the change I am making, or this PR is
[test-exempt].
- [ ] I followed the [breaking change policy] and added [Data Driven
Fixes] where supported.
- [ ] All existing and new tests are passing.

If you need help, consider asking for advice on the #hackers-new channel
on [Discord].

If this change needs to override an active code freeze, provide a
comment explaining why. The code freeze workflow can be overridden by
code reviewers. See pinned issues for any active code freezes with
guidance.

**Note**: The Flutter team is currently trialing the use of [Gemini Code
Assist for
GitHub](https://developers.google.com/gemini-code-assist/docs/review-github-code).
Comments from the `gemini-code-assist` bot should not be taken as
authoritative feedback from the Flutter team. If you find its comments
useful you can update your code accordingly, but if you are unsure or
disagree with the feedback, please feel free to wait for a Flutter team
member's review for guidance on which automated comments should be
addressed.

<!-- Links -->
[Contributor Guide]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#overview
[AI contribution guidelines]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#ai-contribution-guidelines
[Tree Hygiene]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md
[test-exempt]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#tests
[Flutter Style Guide]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Style-guide-for-Flutter-repo.md
[Features we expect every widget to implement]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Style-guide-for-Flutter-repo.md#features-we-expect-every-widget-to-implement
[CLA]: https://cla.developers.google.com/
[flutter/tests]: https://github.com/flutter/tests
[breaking change policy]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#handling-breaking-changes
[Discord]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Chat.md
[Data Driven Fixes]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Data-driven-Fixes.md

---------

Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

a: accessibility Accessibility, e.g. VoiceOver or TalkBack. (aka a11y) CICD Run CI/CD framework flutter/packages/flutter repository. See also f: labels.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants