Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add basic ATF A11y checks via AccessibilityCheckAfterTestStrategy and checkRoboAccessibility #557

Merged
merged 37 commits into from
Nov 21, 2024

Conversation

yschimke
Copy link
Contributor

@yschimke yschimke commented Nov 16, 2024

Run ATF after test completes to check for A11y issues.

Future possible changes

  • Collect results and annotate screenshots with failures
  • demonstrate in CI showing results
 @get:Rule
 val roborazziRule = RoborazziRule(
   composeRule = composeTestRule,
   captureRoot = composeTestRule.onRoot(),
   options = Options(
     roborazziAccessibilityOptions = RoborazziATFAccessibilityCheckOptions(
       RoborazziATFAccessibilityChecker(
         preset = AccessibilityCheckPreset.LATEST,
         suppressions = matchesElements(withTestTag("suppress")),
       ),
       failureLevel = RoborazziATFAccessibilityChecker.CheckLevel.Warning,
     ),
     accessibilityCheckStrategy = AccessibilityCheckAfterTestStrategy()
   )
 )

or

   composeTestRule.onNodeWithTag("contactcard").checkRoboAccessibility(
     roborazziATFAccessibilityCheckOptions = RoborazziATFAccessibilityCheckOptions(
       failureLevel = RoborazziATFAccessibilityChecker.CheckLevel.Warning
     )
   )

Run ATF after test completes to check for A11y issues.
@yschimke yschimke mentioned this pull request Nov 16, 2024
@takahirom
Copy link
Owner

Let me update this branch to check the screenshot differences, as Robolectric has been updated in the main branch.

@takahirom
Copy link
Owner

I don't fully understand what has been done in this pull request yet. I'll take a look tomorrow.🙏

@yschimke
Copy link
Contributor Author

There are multiple ways to achieve this, depending on the end goals.

  1. Apps call enableAccessibilityChecks from compose ui-test
  2. Roborazzi does that
  3. Roborazzi just calls AccessibilityValidator (ATF) similar to ui-test
  4. Hook in to the ATF APIs that AccessibilityValidator is a thin wrapper on

I started at 2, then moved to 3, then ended up at 4.

Firstly, I think we should aim to make this part of most developers toolkit.

But with 2 or 3 it's hard to override the checks, suppressions, how screenshots are taken.

I think it ended up quite clean but also flexible.

@yschimke
Copy link
Contributor Author

I think robolectric 4.14 produces a lot of small diffs. Improvements, but also differences in font handling.

@yschimke
Copy link
Contributor Author

One small example that shows the benefit of this. The stdout for each test shows the errors and warnings notices for checks. So we could have a Log mode and raise awareness in existing tests

Comment on lines 41 to 48
AccessibilityCheckResultType.ERROR -> System.err.println("Error: $check")
AccessibilityCheckResultType.WARNING -> System.err.println(
"Warning: $check"
)

AccessibilityCheckResultType.INFO -> println(
"Info: $check"
)
Copy link
Owner

Choose a reason for hiding this comment

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

📝

Error: [AccessibilityViewCheckResult check=AccessibilityHierarchyCheckResult ERROR SpeakableTextPresentCheck 4 [ViewHierarchyElement class=android.view.View bounds=Rect(474, 1074 - 606, 1206)] null num_answers:0 view=null]
Warning: [AccessibilityViewCheckResult check=AccessibilityHierarchyCheckResult WARNING TextContrastCheck 11 [ViewHierarchyElement class=android.widget.TextView text=Something hard to read bounds=Rect(403, 1002 - 678, 1092)] {KEY_BACKGROUND_COLOR=-12303292, KEY_CONTRAST_RATIO=1.02, KEY_FOREGROUND_COLOR=-12369085, KEY_REQUIRED_CONTRAST_RATIO=3.0} num_answers:0 view=null]
Error: [AccessibilityViewCheckResult check=AccessibilityHierarchyCheckResult ERROR SpeakableTextPresentCheck 4 [ViewHierarchyElement class=android.view.View bounds=Rect(474, 1074 - 606, 1206)] null num_answers:0 view=null]

@yschimke
Copy link
Contributor Author

yschimke commented Nov 17, 2024

Looks like a good compromise.

Ideally this would be on for everyone. This is a great way to make it accessible (pun intended).

I'd like to make the errors visual in future, but this can presumably be done with a similar approach of an optional overlay for screenshots?

…essibility-check/2024-11-17

Takahirom/separate roborazzi accessibility check/2024 11 17
@yschimke
Copy link
Contributor Author

Slight refactor and added a README

Copy link

⚠️ There are differences in library dependencies. See details here.

} else if (captureRoot is CaptureRoot.View) {
val viewInteraction = captureRoot.viewInteraction
// Use perform to get the view
viewInteraction.perform(object : ViewAction {
Copy link
Owner

Choose a reason for hiding this comment

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

I've added View support by using perform(). 👀

@RunWith(AndroidJUnit4::class)
@GraphicsMode(GraphicsMode.Mode.NATIVE)
@Config(qualifiers = RobolectricDeviceQualifiers.Pixel4, sdk = [35])
class ViewA11yTest {
Copy link
Owner

Choose a reason for hiding this comment

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

I've added a test for Android View. 👀

Copy link
Owner

@takahirom takahirom left a comment

Choose a reason for hiding this comment

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

Looks great! Thank you for your contribution. I have a quick question.

@takahirom takahirom changed the title Add basic Compose Android A11y checks Add basic Android A11y checks Nov 18, 2024
@yschimke
Copy link
Contributor Author

@takahirom looks great! I think I successfully nerdsniped you into building the feature I wanted but didn't know how to build. :)

@yschimke yschimke changed the title Add basic Android A11y checks Add basic ATF A11y checks via AccessibilityCheckAfterTestStrategy and checkRoboAccessibility Nov 20, 2024
@takahirom
Copy link
Owner

Thanks! Accessibility is important, and I noticed you wrote a test using a custom check. It made me think that we could also make our apps more accessible for AI agents to further improve their quality, such as by adding content descriptions for image buttons or other elements that agents might need to interact with. I believe this could also be good preparation for AI agent testing.

@yschimke
Copy link
Contributor Author

yschimke commented Nov 20, 2024

and I noticed you wrote a test using a custom check

The intent was to prove it's possible and demystify this.

@takahirom takahirom merged commit 0cf989b into takahirom:main Nov 21, 2024
7 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