Skip to content

Commit

Permalink
Refactor to make AccessibilityChecker configurable for each checkRobo…
Browse files Browse the repository at this point in the history
…Accessibility.
  • Loading branch information
takahirom committed Nov 20, 2024
1 parent 32426ed commit 77fa9dc
Show file tree
Hide file tree
Showing 7 changed files with 68 additions and 41 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
package com.github.takahirom.roborazzi

interface AccessibilityChecker
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,22 @@ class RoborazziContextImpl {
ruleOverrideImageExtension = null
}

private var ruleOverrideAccessibilityChecker: AccessibilityChecker? = null

@InternalRoborazziApi
fun setRuleOverrideAccessibilityChecker(checker: AccessibilityChecker?) {
ruleOverrideAccessibilityChecker = checker
}

@InternalRoborazziApi
fun clearRuleOverrideAccessibilityChecker() {
ruleOverrideAccessibilityChecker = null
}

@InternalRoborazziApi
val accessibilityChecker: AccessibilityChecker?
get() = ruleOverrideAccessibilityChecker

@InternalRoborazziApi
val imageExtension: String
get() = ruleOverrideImageExtension ?: roborazziSystemPropertyImageExtension()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ import org.hamcrest.Matchers
import org.robolectric.shadows.ShadowBuild

fun SemanticsNodeInteraction.checkRoboAccessibility(
checker: RoborazziATFAccessibilityChecker = RoborazziATFAccessibilityChecker(),
checker: RoborazziATFAccessibilityChecker = provideATFAccessibilityCheckerOrCreateDefault(),
failureLevel: RoborazziATFAccessibilityChecker.CheckLevel = RoborazziATFAccessibilityChecker.CheckLevel.Error,
roborazziOptions: RoborazziOptions = provideRoborazziContext().options,
) {
Expand All @@ -37,7 +37,7 @@ fun SemanticsNodeInteraction.checkRoboAccessibility(
}

fun ViewInteraction.checkRoboAccessibility(
checker: RoborazziATFAccessibilityChecker = RoborazziATFAccessibilityChecker(),
checker: RoborazziATFAccessibilityChecker = provideATFAccessibilityCheckerOrCreateDefault(),
failureLevel: RoborazziATFAccessibilityChecker.CheckLevel = RoborazziATFAccessibilityChecker.CheckLevel.Error,
roborazziOptions: RoborazziOptions = provideRoborazziContext().options,
) {
Expand All @@ -48,13 +48,18 @@ fun ViewInteraction.checkRoboAccessibility(
)
}

private fun provideATFAccessibilityCheckerOrCreateDefault() =
((provideRoborazziContext().accessibilityChecker as? RoborazziATFAccessibilityChecker)
?: RoborazziATFAccessibilityChecker())


@ExperimentalRoborazziApi
data class RoborazziATFAccessibilityChecker(
val checks: Set<AccessibilityHierarchyCheck> = AccessibilityCheckPreset.getAccessibilityHierarchyChecksForPreset(
AccessibilityCheckPreset.LATEST
),
val suppressions: Matcher<in AccessibilityViewCheckResult> = Matchers.not(Matchers.anything()),
) {
) : AccessibilityChecker {
constructor(
preset: AccessibilityCheckPreset,
suppressions: Matcher<in AccessibilityViewCheckResult> = Matchers.not(Matchers.anything()),
Expand Down Expand Up @@ -201,25 +206,25 @@ data class RoborazziATFAccessibilityChecker(

@ExperimentalRoborazziApi
data class AccessibilityCheckAfterTest(
val checker: RoborazziATFAccessibilityChecker = RoborazziATFAccessibilityChecker(),
val failureLevel: RoborazziATFAccessibilityChecker.CheckLevel = RoborazziATFAccessibilityChecker.CheckLevel.Error,
) : RoborazziRule.AccessibilityChecks {
) : RoborazziRule.AccessibilityCheckStrategy {
override fun runAccessibilityChecks(
captureRoot: CaptureRoot, roborazziOptions: RoborazziOptions
) {
checker.runAccessibilityChecks(
checkNode = when (captureRoot) {
is CaptureRoot.Compose -> RoborazziATFAccessibilityChecker.CheckNode.Compose(
semanticsNodeInteraction = captureRoot.semanticsNodeInteraction
)
provideATFAccessibilityCheckerOrCreateDefault()
.runAccessibilityChecks(
checkNode = when (captureRoot) {
is CaptureRoot.Compose -> RoborazziATFAccessibilityChecker.CheckNode.Compose(
semanticsNodeInteraction = captureRoot.semanticsNodeInteraction
)

CaptureRoot.None -> return
is CaptureRoot.View -> RoborazziATFAccessibilityChecker.CheckNode.View(
viewInteraction = captureRoot.viewInteraction
)
},
roborazziOptions = roborazziOptions,
failureLevel = failureLevel,
)
CaptureRoot.None -> return
is CaptureRoot.View -> RoborazziATFAccessibilityChecker.CheckNode.View(
viewInteraction = captureRoot.viewInteraction
)
},
roborazziOptions = roborazziOptions,
failureLevel = failureLevel,
)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -56,18 +56,19 @@ class RoborazziRule private constructor(
val outputFileProvider: FileProvider = provideRoborazziContext().fileProvider
?: defaultFileProvider,
val roborazziOptions: RoborazziOptions = provideRoborazziContext().options,
val accessibilityChecks: AccessibilityChecks = AccessibilityChecks.Disabled,
val accessibilityChecker: AccessibilityChecker? = null,
val accessibilityCheckStrategy: AccessibilityCheckStrategy = AccessibilityCheckStrategy.None,
)

@ExperimentalRoborazziApi
interface AccessibilityChecks {
interface AccessibilityCheckStrategy {
@InternalRoborazziApi
fun runAccessibilityChecks(
captureRoot: CaptureRoot,
roborazziOptions: RoborazziOptions,
)
// Use `roborazzi-accessibility-check`'s ValidateAfterTest
data object Disabled : AccessibilityChecks {
// Use `roborazzi-accessibility-check`'s AccessibilityCheckAfterTest
data object None : AccessibilityCheckStrategy {
override fun runAccessibilityChecks(
captureRoot: CaptureRoot,
roborazziOptions: RoborazziOptions
Expand Down Expand Up @@ -161,12 +162,14 @@ class RoborazziRule private constructor(
provideRoborazziContext().setRuleOverrideRoborazziOptions(options.roborazziOptions)
provideRoborazziContext().setRuleOverrideFileProvider(options.outputFileProvider)
provideRoborazziContext().setRuleOverrideDescription(description)
provideRoborazziContext().setRuleOverrideAccessibilityChecker(options.accessibilityChecker)
runTest(base, description, captureRoot)
} finally {
provideRoborazziContext().clearRuleOverrideOutputDirectory()
provideRoborazziContext().clearRuleOverrideRoborazziOptions()
provideRoborazziContext().clearRuleOverrideFileProvider()
provideRoborazziContext().clearRuleOverrideDescription()
provideRoborazziContext().clearRuleOverrideAccessibilityChecker()
}
}
}
Expand All @@ -179,7 +182,7 @@ class RoborazziRule private constructor(
) {
val evaluate: () -> Unit = {
try {
val accessibilityChecks = options.accessibilityChecks
val accessibilityChecks = options.accessibilityCheckStrategy
// TODO enable a11y before showing content

base.evaluate()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,11 +54,11 @@ class ComposeA11yTest {
composeRule = composeTestRule,
captureRoot = composeTestRule.onRoot(),
options = Options(
accessibilityChecks = AccessibilityCheckAfterTest(
checker = RoborazziATFAccessibilityChecker(
preset = AccessibilityCheckPreset.LATEST,
suppressions = matchesElements(withTestTag("suppress"))
),
accessibilityChecker = RoborazziATFAccessibilityChecker(
preset = AccessibilityCheckPreset.LATEST,
suppressions = matchesElements(withTestTag("suppress"))
),
accessibilityCheckStrategy = AccessibilityCheckAfterTest(
failureLevel = RoborazziATFAccessibilityChecker.CheckLevel.Warning,
)
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,11 @@ import androidx.compose.ui.test.junit4.createAndroidComposeRule
import androidx.compose.ui.test.onRoot
import androidx.compose.ui.unit.dp
import androidx.test.ext.junit.runners.AndroidJUnit4
import com.github.takahirom.roborazzi.RoborazziATFAccessibilityChecker
import com.github.takahirom.roborazzi.AccessibilityCheckAfterTest
import com.github.takahirom.roborazzi.RobolectricDeviceQualifiers
import com.github.takahirom.roborazzi.RoborazziATFAccessibilityChecker
import com.github.takahirom.roborazzi.RoborazziRule
import com.github.takahirom.roborazzi.RoborazziRule.Options
import com.github.takahirom.roborazzi.AccessibilityCheckAfterTest
import com.google.android.apps.common.testing.accessibility.framework.AccessibilityCheckResult.AccessibilityCheckResultType
import com.google.android.apps.common.testing.accessibility.framework.AccessibilityCheckResult.AccessibilityCheckResultType.ERROR
import com.google.android.apps.common.testing.accessibility.framework.AccessibilityCheckResult.AccessibilityCheckResultType.INFO
Expand Down Expand Up @@ -59,11 +59,11 @@ class ComposeA11yWithCustomCheckTest {
composeRule = composeTestRule,
captureRoot = composeTestRule.onRoot(),
options = Options(
accessibilityChecks = AccessibilityCheckAfterTest(
checker = RoborazziATFAccessibilityChecker(
checks = setOf(NoRedTextCheck()),
suppressions = matchesElements(withTestTag("suppress"))
),
accessibilityChecker = RoborazziATFAccessibilityChecker(
checks = setOf(NoRedTextCheck()),
suppressions = matchesElements(withTestTag("suppress"))
),
accessibilityCheckStrategy = AccessibilityCheckAfterTest(
failureLevel = RoborazziATFAccessibilityChecker.CheckLevel.Warning,
)
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,9 @@ import androidx.test.espresso.assertion.ViewAssertions
import androidx.test.espresso.matcher.ViewMatchers
import androidx.test.ext.junit.rules.ActivityScenarioRule
import androidx.test.ext.junit.runners.AndroidJUnit4
import com.github.takahirom.roborazzi.RoborazziATFAccessibilityChecker
import com.github.takahirom.roborazzi.AccessibilityCheckAfterTest
import com.github.takahirom.roborazzi.RobolectricDeviceQualifiers
import com.github.takahirom.roborazzi.RoborazziATFAccessibilityChecker
import com.github.takahirom.roborazzi.RoborazziRule
import com.github.takahirom.roborazzi.RoborazziRule.Options
import com.google.android.apps.common.testing.accessibility.framework.AccessibilityCheckPreset
Expand Down Expand Up @@ -41,11 +41,11 @@ class ViewA11yTest {
val roborazziRule = RoborazziRule(
captureRoot = Espresso.onView(ViewMatchers.isRoot()),
options = Options(
accessibilityChecks = AccessibilityCheckAfterTest(
checker = RoborazziATFAccessibilityChecker(
preset = AccessibilityCheckPreset.LATEST,
suppressions = matchesElements(withTestTag("suppress"))
),
accessibilityChecker = RoborazziATFAccessibilityChecker(
preset = AccessibilityCheckPreset.LATEST,
suppressions = matchesElements(withTestTag("suppress"))
),
accessibilityCheckStrategy = AccessibilityCheckAfterTest(
failureLevel = RoborazziATFAccessibilityChecker.CheckLevel.Warning,
)
)
Expand Down

0 comments on commit 77fa9dc

Please sign in to comment.