Issue
I’m trying to use onView()
to get an EditText view that lives inside of a fragment but every EditText in each fragment has the same id.
Given this pseudo-code:
<Activity>
<Fragment>
<EditText android:id"@+id/input" />
</Fragment>
<Fragment>
<EditText android:id"@+id/input" />
</Fragment>
<Fragment>
<EditText android:id"@+id/input" />
</Fragment>
</Activity>
In my test case, I’m doing
onView(withId(R.id.input)).perform(typeText("foo"));
On run, I’m getting with id: com.foo.bar.foobar:id/input' matches multiple views in the hierarchy.
. The view hierarchy is below: (I moved the ‘MATCHES’ before the element for readability)
View Hierarchy:
+>DecorView{id-1, visibilityVISIBLE, width1080, height1920, has-focustrue, has-focusabletrue, has-window-focustrue, is-clickablefalse, is-enabledtrue, is-focusedfalse, is-focusablefalse, is-layout-requestedfalse, is-selectedfalse, root-is-layout-requestedfalse, has-input-connectionfalse, x0.0, y0.0, child-count2}
|
+->LinearLayout{id-1, visibilityVISIBLE, width1080, height1794, has-focustrue, has-focusabletrue, has-window-focustrue, is-clickablefalse, is-enabledtrue, is-focusedfalse, is-focusablefalse, is-layout-requestedfalse, is-selectedfalse, root-is-layout-requestedfalse, has-input-connectionfalse, x0.0, y0.0, child-count2}
|
+-->ViewStub{id16909295, res-nameaction_mode_bar_stub, visibilityGONE, width0, height0, has-focusfalse, has-focusablefalse, has-window-focustrue, is-clickablefalse, is-enabledtrue, is-focusedfalse, is-focusablefalse, is-layout-requestedtrue, is-selectedfalse, root-is-layout-requestedfalse, has-input-connectionfalse, x0.0, y0.0}
|
+-->FrameLayout{id-1, visibilityVISIBLE, width1080, height1794, has-focustrue, has-focusabletrue, has-window-focustrue, is-clickablefalse, is-enabledtrue, is-focusedfalse, is-focusablefalse, is-layout-requestedfalse, is-selectedfalse, root-is-layout-requestedfalse, has-input-connectionfalse, x0.0, y0.0, child-count1}
|
+--->FitWindowsLinearLayout{id2131427402, res-nameaction_bar_root, visibilityVISIBLE, width1080, height1794, has-focustrue, has-focusabletrue, has-window-focustrue, is-clickablefalse, is-enabledtrue, is-focusedfalse, is-focusablefalse, is-layout-requestedfalse, is-selectedfalse, root-is-layout-requestedfalse, has-input-connectionfalse, x0.0, y0.0, child-count2}
|
+---->ViewStubCompat{id2131427403, res-nameaction_mode_bar_stub, visibilityGONE, width0, height0, has-focusfalse, has-focusablefalse, has-window-focustrue, is-clickablefalse, is-enabledtrue, is-focusedfalse, is-focusablefalse, is-layout-requestedtrue, is-selectedfalse, root-is-layout-requestedfalse, has-input-connectionfalse, x0.0, y0.0}
|
+---->ContentFrameLayout{id16908290, res-namecontent, visibilityVISIBLE, width1080, height1794, has-focustrue, has-focusabletrue, has-window-focustrue, is-clickablefalse, is-enabledtrue, is-focusedfalse, is-focusablefalse, is-layout-requestedfalse, is-selectedfalse, root-is-layout-requestedfalse, has-input-connectionfalse, x0.0, y0.0, child-count1}
|
+----->ConstraintLayout{id2131427422, res-nameconstraintLayout, visibilityVISIBLE, width1080, height1794, has-focustrue, has-focusabletrue, has-window-focustrue, is-clickablefalse, is-enabledtrue, is-focusedfalse, is-focusablefalse, is-layout-requestedfalse, is-selectedfalse, root-is-layout-requestedfalse, has-input-connectionfalse, x0.0, y0.0, child-count7}
|
+------>AppCompatTextView{id2131427423, res-namestepHeader, visibilityVISIBLE, width321, height140, has-focusfalse, has-focusablefalse, has-window-focustrue, is-clickablefalse, is-enabledtrue, is-focusedfalse, is-focusablefalse, is-layout-requestedfalse, is-selectedfalse, root-is-layout-requestedfalse, has-input-connectionfalse, x380.0, y168.0, textStep 1:, input-type0, ime-targetfalse, has-linksfalse}
|
+------>AppCompatTextView{id2131427425, res-namestepTitle, visibilityVISIBLE, width521, height88, has-focusfalse, has-focusablefalse, has-window-focustrue, is-clickablefalse, is-enabledtrue, is-focusedfalse, is-focusablefalse, is-layout-requestedfalse, is-selectedfalse, root-is-layout-requestedfalse, has-input-connectionfalse, x280.0, y361.0, textBasic Information, input-type0, ime-targetfalse, has-linksfalse}
|
+------>AppCompatTextView{id2131427426, res-namestepInstruction, visibilityVISIBLE, width141, height71, has-focusfalse, has-focusablefalse, has-window-focustrue, is-clickablefalse, is-enabledtrue, is-focusedfalse, is-focusablefalse, is-layout-requestedfalse, is-selectedfalse, root-is-layout-requestedfalse, has-input-connectionfalse, x470.0, y712.0, textName, input-type0, ime-targetfalse, has-linksfalse}
|
+------>AppCompatButton{id2131427427, res-namenextButton, visibilityVISIBLE, width231, height126, has-focustrue, has-focusabletrue, has-window-focustrue, is-clickabletrue, is-enabledtrue, is-focusedtrue, is-focusabletrue, is-layout-requestedfalse, is-selectedfalse, root-is-layout-requestedfalse, has-input-connectionfalse, x425.0, y1479.0, textNext, input-type0, ime-targettrue, has-linksfalse}
|
+------>AppCompatButton{id2131427424, res-namebackButton, visibilityVISIBLE, width231, height126, has-focusfalse, has-focusabletrue, has-window-focustrue, is-clickabletrue, is-enabledtrue, is-focusedfalse, is-focusabletrue, is-layout-requestedfalse, is-selectedfalse, root-is-layout-requestedfalse, has-input-connectionfalse, x21.0, y21.0, textBack, input-type0, ime-targetfalse, has-linksfalse}
|
+------>ConstraintLayout{id2131427428, res-nameprogressBarContainer, visibilityVISIBLE, width1080, height105, has-focusfalse, has-focusablefalse, has-window-focustrue, is-clickablefalse, is-enabledtrue, is-focusedfalse, is-focusablefalse, is-layout-requestedfalse, is-selectedfalse, root-is-layout-requestedfalse, has-input-connectionfalse, x0.0, y1689.0, child-count2}
|
+------->AppCompatTextView{id2131427429, res-nameprogressBar, visibilityVISIBLE, width1080, height105, has-focusfalse, has-focusablefalse, has-window-focustrue, is-clickablefalse, is-enabledtrue, is-focusedfalse, is-focusablefalse, is-layout-requestedfalse, is-selectedfalse, root-is-layout-requestedfalse, has-input-connectionfalse, x0.0, y0.0, textProgress bar, input-type0, ime-targetfalse, has-linksfalse}
|
+------->View{id2131427430, res-nameprogressIndicator, visibilityVISIBLE, width154, height11, has-focusfalse, has-focusablefalse, has-window-focustrue, is-clickablefalse, is-enabledtrue, is-focusedfalse, is-focusablefalse, is-layout-requestedfalse, is-selectedfalse, root-is-layout-requestedfalse, has-input-connectionfalse, x0.0, y94.0}
|
+------>ConstraintLayout{id2131427431, res-namestepContainer, visibilityVISIBLE, width1080, height696, has-focusfalse, has-focusabletrue, has-window-focustrue, is-clickablefalse, is-enabledtrue, is-focusedfalse, is-focusablefalse, is-layout-requestedfalse, is-selectedfalse, root-is-layout-requestedfalse, has-input-connectionfalse, x0.0, y783.0, child-count6}
|
+------->ConstraintLayout{id2131427436, res-nameviewStepInput, visibilityVISIBLE, width1080, height696, has-focusfalse, has-focusabletrue, has-window-focustrue, is-clickablefalse, is-enabledtrue, is-focusedfalse, is-focusablefalse, is-layout-requestedfalse, is-selectedfalse, root-is-layout-requestedfalse, has-input-connectionfalse, x0.0, y0.0, child-count1}
|
****MATCHES****
+-------->AppCompatEditText{id2131427437, res-nameuserInput, visibilityVISIBLE, width1038, height118, has-focusfalse, has-focusabletrue, has-window-focustrue, is-clickabletrue, is-enabledtrue, is-focusedfalse, is-focusabletrue, is-layout-requestedfalse, is-selectedfalse, root-is-layout-requestedfalse, has-input-connectiontrue, editor-info[inputType0x1 imeOptions0xc000005 privateImeOptionsnull actionLabelnull actionId0 initialSelStart0 initialSelEnd0 initialCapsMode0x0 hintTextnull labelnull packageNamenull fieldId0 fieldNamenull extrasnull hintLocalesnull contentMimeTypesnull ], x21.0, y289.0, text, input-type1, ime-targetfalse, has-linksfalse}
|
+------->ConstraintLayout{id2131427436, res-nameviewStepInput, visibilityGONE, width0, height0, has-focusfalse, has-focusablefalse, has-window-focustrue, is-clickablefalse, is-enabledtrue, is-focusedfalse, is-focusablefalse, is-layout-requestedtrue, is-selectedfalse, root-is-layout-requestedfalse, has-input-connectionfalse, x0.0, y0.0, child-count1}
|
+-------->GridView{id2131427439, res-nameselector_grid, visibilityVISIBLE, width0, height0, has-focusfalse, has-focusabletrue, has-window-focustrue, is-clickabletrue, is-enabledtrue, is-focusedfalse, is-focusabletrue, is-layout-requestedtrue, is-selectedfalse, root-is-layout-requestedfalse, has-input-connectionfalse, x0.0, y0.0, child-count0}
|
+------->ConstraintLayout{id2131427436, res-nameviewStepInput, visibilityGONE, width0, height0, has-focusfalse, has-focusablefalse, has-window-focustrue, is-clickablefalse, is-enabledtrue, is-focusedfalse, is-focusablefalse, is-layout-requestedtrue, is-selectedfalse, root-is-layout-requestedfalse, has-input-connectionfalse, x0.0, y0.0, child-count1}
|
****MATCHES****
+-------->AppCompatEditText{id2131427437, res-nameuserInput, visibilityVISIBLE, width0, height0, has-focusfalse, has-focusabletrue, has-window-focustrue, is-clickabletrue, is-enabledtrue, is-focusedfalse, is-focusabletrue, is-layout-requestedtrue, is-selectedfalse, root-is-layout-requestedfalse, has-input-connectiontrue, editor-info[inputType0x1 imeOptions0xc000005 privateImeOptionsnull actionLabelnull actionId0 initialSelStart0 initialSelEnd0 initialCapsMode0x0 hintTextnull labelnull packageNamenull fieldId0 fieldNamenull extrasnull hintLocalesnull contentMimeTypesnull ], x0.0, y0.0, text, input-type1, ime-targetfalse, has-linksfalse}
|
+------->ConstraintLayout{id2131427436, res-nameviewStepInput, visibilityGONE, width0, height0, has-focusfalse, has-focusablefalse, has-window-focustrue, is-clickablefalse, is-enabledtrue, is-focusedfalse, is-focusablefalse, is-layout-requestedtrue, is-selectedfalse, root-is-layout-requestedfalse, has-input-connectionfalse, x0.0, y0.0, child-count1}
|
+-------->GridView{id2131427439, res-nameselector_grid, visibilityVISIBLE, width0, height0, has-focusfalse, has-focusablefalse, has-window-focustrue, is-clickabletrue, is-enabledtrue, is-focusedfalse, is-focusablefalse, is-layout-requestedtrue, is-selectedfalse, root-is-layout-requestedfalse, has-input-connectionfalse, x0.0, y0.0, child-count0}
|
+------->ConstraintLayout{id2131427436, res-nameviewStepInput, visibilityGONE, width0, height0, has-focusfalse, has-focusablefalse, has-window-focustrue, is-clickablefalse, is-enabledtrue, is-focusedfalse, is-focusablefalse, is-layout-requestedtrue, is-selectedfalse, root-is-layout-requestedfalse, has-input-connectionfalse, x0.0, y0.0, child-count1}
|
+-------->GridView{id2131427439, res-nameselector_grid, visibilityVISIBLE, width0, height0, has-focusfalse, has-focusabletrue, has-window-focustrue, is-clickabletrue, is-enabledtrue, is-focusedfalse, is-focusabletrue, is-layout-requestedtrue, is-selectedfalse, root-is-layout-requestedfalse, has-input-connectionfalse, x0.0, y0.0, child-count0}
|
+------->ConstraintLayout{id2131427436, res-nameviewStepInput, visibilityGONE, width0, height0, has-focusfalse, has-focusablefalse, has-window-focustrue, is-clickablefalse, is-enabledtrue, is-focusedfalse, is-focusablefalse, is-layout-requestedtrue, is-selectedfalse, root-is-layout-requestedfalse, has-input-connectionfalse, x0.0, y0.0, child-count1}
|
****MATCHES****
+-------->AppCompatEditText{id2131427437, res-nameuserInput, visibilityVISIBLE, width0, height0, has-focusfalse, has-focusabletrue, has-window-focustrue, is-clickabletrue, is-enabledtrue, is-focusedfalse, is-focusabletrue, is-layout-requestedtrue, is-selectedfalse, root-is-layout-requestedfalse, has-input-connectiontrue, editor-info[inputType0x1 imeOptions0xc000005 privateImeOptionsnull actionLabelnull actionId0 initialSelStart0 initialSelEnd0 initialCapsMode0x0 hintTextnull labelnull packageNamenull fieldId0 fieldNamenull extrasnull hintLocalesnull contentMimeTypesnull ], x0.0, y0.0, text, input-type1, ime-targetfalse, has-linksfalse}
|
+->View{id16908336, res-namenavigationBarBackground, visibilityVISIBLE, width1080, height126, has-focusfalse, has-focusablefalse, has-window-focustrue, is-clickablefalse, is-enabledtrue, is-focusedfalse, is-focusablefalse, is-layout-requestedfalse, is-selectedfalse, root-is-layout-requestedfalse, has-input-connectionfalse, x0.0, y1794.0}
|
at dalvik.system.VMStack.getThreadStackTrace(Native Method)
at java.lang.Thread.getStackTrace(Thread.java:1566)
at android.support.test.espresso.base.DefaultFailureHandler.getUserFriendlyError(DefaultFailureHandler.java:92)
at android.support.test.espresso.base.DefaultFailureHandler.handle(DefaultFailureHandler.java:56)
at android.support.test.espresso.ViewInteraction.runSynchronouslyOnUiThread(ViewInteraction.java:184)
at android.support.test.espresso.ViewInteraction.doPerform(ViewInteraction.java:115)
at android.support.test.espresso.ViewInteraction.perform(ViewInteraction.java:87)
at com.newfoundry.skyline.facialrecognitionkioskapp.ActivityRegistrationScreenTest.testFilledInputFieldShouldIncrementCurrentStepOnNext(ActivityRegistrationScreenTest.java:73)
at java.lang.reflect.Method.invoke(Native Method)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:26)
at org.junit.internal.runners.statements.RunAfters.evaluate(RunAfters.java:27)
at android.support.test.internal.statement.UiThreadStatement.evaluate(UiThreadStatement.java:55)
at android.support.test.rule.ActivityTestRule$ActivityStatement.evaluate(ActivityTestRule.java:270)
at org.junit.rules.RunRules.evaluate(RunRules.java:20)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
at org.junit.runners.Suite.runChild(Suite.java:128)
at org.junit.runners.Suite.runChild(Suite.java:27)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
at org.junit.runner.JUnitCore.run(JUnitCore.java:115)
at android.support.test.internal.runner.TestExecutor.execute(TestExecutor.java:59)
at android.support.test.runner.AndroidJUnitRunner.onStart(AndroidJUnitRunner.java:262)
at android.app.Instrumentation$InstrumentationThread.run(Instrumentation.java:1932)
I’ve tried doing:
EditText input mActivity.getSupportFragmentManager()
.findFragmentByTag("foo")
.getView()
.findViewById(R.id.input);
onView(withId(input));
But am running into issues with that as well. I haven’t been able to find anything addressing this specific issue. Any help would be tremendously appreciated.
Solution
From my understanding, you have to differentiate the TextViews in some way. Assume the first fragment has the id “fragment1”, the second fragment has the id “fragment2”, and so on.
Then you could use
onView(allOf(withParent(withId(R.id.fragment1)),instanceOf(EditText.class))).perform(typeText("foo"));
to only select the single TextView in that fragment and use it in your test case.
Answered By – Zack