I have my test setup like this:
Base class:
public class AccessibilityBase {
public static AccessibilityValidator accessibilityValidator;
@BeforeClass
public static void enableAccessibilityChecks() {
accessibilityValidator = AccessibilityChecks.enable();
accessibilityValidator.setThrowExceptionForErrors(true);
}
...
Test class:
public class LoginAccessibilityTest extends AccessibilityBase {
@Rule
public ActivityTestRule<LoginActivity> activityTestRule = new ActivityTestRule<>(LoginActivity.class, true, false);
private static Matcher<? super AccessibilityViewCheckResult> suppress = Matchers.anyOf(
allOf(matchesCheckNames(is("TouchTargetSizeViewCheck")),
matchesViews(withId(R.id.main_button_login)))
);
@BeforeClass
public static void enableAccessibilityChecks() {
accessibilityValidator = AccessibilityChecks.enable();
accessibilityValidator.setSuppressingResultMatcher(suppress);
}
@Test
public void testLoginActivity() {
Context context = InstrumentationRegistry.getInstrumentation().getTargetContext();
Intent intent = new Intent(context, LoginActivity.class);
LoginActivity loginActivity = activityTestRule.launchActivity(intent);
// UPDATE: Had to pass suppress through here to the base class
runAllTests(loginActivity, suppress);
}
}
And yet, when I run this it still fails with this error message:
java.lang.AssertionError: Button app:id/main_button_login: View falls below the minimum recommended size for touch targets. Minimum touch target size is 48x48dp. Actual size is 446.0x45.0dp (screen density is 3.0).
UPDATE: The key was in my runAllTests method. I've fixed it by passing the suppress matcher in the test class to runAllTests()
private static void runTests(Activity activity, Set<AccessibilityViewHierarchyCheck> checks, Matcher<? super AccessibilityViewCheckResult> suppress) {
List<AccessibilityViewCheckResult> results = new LinkedList<>();
View rootView = activity.findViewById(android.R.id.content);
for (AccessibilityViewHierarchyCheck check : checks) {
try {
results.addAll(check.runCheckOnViewHierarchy(rootView));
} catch (Exception ex) {
}
}
if (suppress != null) {
AccessibilityCheckResultUtils.suppressMatchingResults(results, suppress);
}
That last bit was necessary even though I had it set in the test's @BeforeClass.
There are two answers depending on which libraries are being used. As a note, the first example here is deprecated, but works fine:
import com.google.android.apps.common.testing.accessibility.framework.AccessibilityViewCheckResult // <-- deprecated
...
companion object {
@BeforeClass
@JvmStatic
fun enableAccessibilityChecks() {
val suppress: Matcher<AccessibilityViewCheckResult> = anyOf(
allOf(matchesCheckNames(`is`("TouchTargetSizeViewCheck")),
matchesViews(withId(R.id.small_button))),
allOf(matchesCheckNames(`is`("DuplicateClickableBoundsViewCheck")),
matchesViews(withId(R.id.overlap_button)))
)
AccessibilityChecks.enable()
.setRunChecksFromRootView(true)
.setSuppressingResultMatcher(suppress)
}
}
And the newer version:
import androidx.test.espresso.accessibility.AccessibilityChecks
import androidx.test.espresso.matcher.ViewMatchers.withId
import com.google.android.apps.common.testing.accessibility.framework.AccessibilityCheckResultUtils.matchesCheckNames
import com.google.android.apps.common.testing.accessibility.framework.AccessibilityCheckResultUtils.matchesViews
import org.hamcrest.CoreMatchers.*
...
init {
AccessibilityChecks.enable()
.setRunChecksFromRootView(true)
.apply {
setSuppressingResultMatcher(
anyOf(
allOf(matchesCheckNames(`is`("TouchTargetSizeViewCheck")),
matchesViews(withId(R.id.small_button))),
allOf(matchesCheckNames(`is`("DuplicateClickableBoundsViewCheck")),
matchesViews(withId(R.id.overlap_button)))
)
)
}
}