TextInputLayout / TextInputEditText fail accessibility scans
inktomi opened this issue · comments
Build: AI-203.6682.168.2031.7101492, 202101251652,
AI-203.6682.168.2031.7101492, JRE 11.0.8+10-b944.6842174x64 JetBrains s.r.o, OS Mac OS X(x86_64) v10.15.7, screens 5120.0x2880.0, 3384.0x6016.0, 3360.0x2100.0; Retina
AS: Arctic Fox | 2020.3.1 Canary 5; Kotlin plugin: 1.4.21-release-Studio4.2-1; Android Gradle Plugin: 7.0.0-alpha05; Gradle: 6.8; NDK: from local.properties: (not specified), latest from SDK: (not found); LLDB: LLDB 3.1 (revision: 3.1.4508709); CMake: from local.properties: (not specified), latest from SDK: (not found), from PATH: (not found)
TextInputLayout
with a TextInputEditText
inside it does not pass accessibility scans.
Create a sample project with the following:
app.gradle
implementation 'com.google.android.material:material:1.2.1'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0-alpha03'
androidTestImplementation 'androidx.test.espresso:espresso-accessibility:3.4.0-alpha03'
ExampleInstrumentedTest
@RunWith(AndroidJUnit4::class)
class ExampleInstrumentedTest {
@Rule
@JvmField
var rule: ActivityScenarioRule<*> = ActivityScenarioRule(MainActivity::class.java)
@Test
fun justLoadHome() {
AccessibilityChecks.enable()
onView(withId(R.id.input_field)).perform(typeText("A - B - C"))
}
}
MainActivity.kt
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val inputLayout = findViewById<TextInputLayout>(R.id.input_layout)
inputLayout.hint = "A hint!"
val inputField = findViewById<TextInputEditText>(R.id.input_field)
}
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<com.google.android.material.textfield.TextInputLayout
style="@style/Widget.MaterialComponents.TextInputLayout.OutlinedBox"
android:id="@+id/input_layout"
android:layout_width="300dp"
android:layout_height="wrap_content"
android:labelFor="@id/input_field"
android:hint="A hint!"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent">
<com.google.android.material.textfield.TextInputEditText
android:id="@+id/input_field"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
</com.google.android.material.textfield.TextInputLayout>
</androidx.constraintlayout.widget.ConstraintLayout>
Then, run the test. It will fail with an accessibility issue:
com.google.android.apps.common.testing.accessibility.framework.integrations.espresso.AccessibilityViewCheckException: There was 1 accessibility result:
TextInputEditText{id=2131230901, res-name=input_field, visibility=VISIBLE, width=300, height=54, has-focus=true, has-focusable=true, has-window-focus=false, is-clickable=true, is-enabled=true, is-focused=true, is-focusable=true, is-layout-requested=false, is-selected=false, layout-params=android.widget.FrameLayout$LayoutParams@ca43d75, tag=null, root-is-layout-requested=false, has-input-connection=true, editor-info=[inputType=0x20001 imeOptions=0x40000006 privateImeOptions=null actionLabel=null actionId=0 initialSelStart=0 initialSelEnd=0 initialCapsMode=0x0 hintText=A hint! label=null packageName=null fieldId=0 fieldName=null extras=null ], x=0.0, y=0.0, text=, hint=A hint!, input-type=131073, ime-target=false, has-links=false}: This item may not have a label readable by screen readers. Reported by com.google.android.apps.common.testing.accessibility.framework.checks.SpeakableTextPresentCheck
at com.google.android.apps.common.testing.accessibility.framework.integrations.espresso.AccessibilityValidator.processResults(AccessibilityValidator.java:270)
at com.google.android.apps.common.testing.accessibility.framework.integrations.espresso.AccessibilityValidator.runAccessibilityChecks(AccessibilityValidator.java:228)
at com.google.android.apps.common.testing.accessibility.framework.integrations.espresso.AccessibilityValidator.checkAndReturnResults(AccessibilityValidator.java:87)
at androidx.test.espresso.accessibility.AccessibilityChecks$2.check(AccessibilityChecks.java:65)
at androidx.test.espresso.action.ViewActions$1.perform(ViewActions.java:3)
at androidx.test.espresso.ViewInteraction$SingleExecutionViewAction.perform(ViewInteraction.java:2)
at androidx.test.espresso.ViewInteraction.doPerform(ViewInteraction.java:22)
at androidx.test.espresso.ViewInteraction.access$100(ViewInteraction.java:1)
at androidx.test.espresso.ViewInteraction$1.call(ViewInteraction.java:2)
at androidx.test.espresso.ViewInteraction$1.call(ViewInteraction.java:1)
at java.util.concurrent.FutureTask.run(FutureTask.java:237)
at android.os.Handler.handleCallback(Handler.java:739)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:148)
at android.app.ActivityThread.main(ActivityThread.java:5417)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)
Note that the hint is being set in code & in the layout, and the error even reports that it's set, but the SpeakableTextPresentCheck
still fails. TalkBack will read the hint when this code is on screen.
In this use of TextInputLayout, the android:labelFor
is not required. This is similar to the example on material.io.
The implementation of TextInputEditText will pick up the hint from the TextInputLayout automatically. In this particular construct, adding android:labelFor
causes the hint to be ignored when testing accessibility on Espresso. Removing the attribute will eliminate the test failure.