Issue
I have a suite of Android UI tests running using Cucumber-JVM and Espresso. However, I am facing issues with interacting with a dialog fragment.
Another fragment creates a dialog fragment on top with some view elements. When I try to check/interact with these, Espresso doesn't seem to find them at all in the view hierarchy. The view hierarchy it displays in the error message is that of the underlying fragment, and not the dialog fragment, which makes me think it is picking up an incorrect Root View.
To try to fix this, I added inRoot(isDialog()) into the statement:
onView(withText("Ok")).inRoot(isDialog()).check(matches(isDisplayed()));
This results in the following error message:
android.support.test.espresso.NoMatchingRootException: Matcher 'is dialog' did not match any of the following roots: [Root{application-window-token=android.view.ViewRootImpl$W@f99cfec, window-token=android.view.ViewRootImpl$W@f99cfec, has-window-focus=true, layout-params-type=1, layout-params-string=WM.LayoutParams{(0,0)(fillxfill) sim=#20 ty=1 fl=#1810100 wanim=0x10303e5 needsMenuKey=2}, decor-view-string=DecorView{id=-1, visibility=VISIBLE, width=1080, height=1794, has-focus=true, has-focusable=true, has-window-focus=true, is-clickable=false, is-enabled=true, is-focused=false, is-focusable=false, is-layout-requested=false, is-selected=false, root-is-layout-requested=false, has-input-connection=false, x=0.0, y=0.0, child-count=1}}, Root{application-window-token=android.view.ViewRootImpl$W@e5f9fb5, window-token=android.view.ViewRootImpl$W@e5f9fb5, has-window-focus=false, layout-params-type=1, layout-params-string=WM.LayoutParams{(0,0)(fillxfill) sim=#20 ty=1 fl=#1810100 wanim=0x10303e5 needsMenuKey=2}, decor-view-string=DecorView{id=-1, visibility=INVISIBLE, width=1080, height=1794, has-focus=true, has-focusable=false, has-window-focus=false, is-clickable=false, is-enabled=true, is-focused=false, is-focusable=false, is-layout-requested=false, is-selected=false, root-is-layout-requested=false, has-input-connection=false, x=0.0, y=0.0, child-count=1}}, Root{application-window-token=android.view.ViewRootImpl$W@c5e564a, window-token=android.view.ViewRootImpl$W@c5e564a, has-window-focus=false, layout-params-type=1, layout-params-string=WM.LayoutParams{(0,0)(fillxfill) ty=1 fl=#1810100 wanim=0x10303e5 needsMenuKey=2}, decor-view-string=DecorView{id=-1, visibility=INVISIBLE, width=1080, height=1794, has-focus=true, has-focusable=false, has-window-focus=false, is-clickable=false, is-enabled=true, is-focused=false, is-focusable=false, is-layout-requested=false, is-selected=false, root-is-layout-requested=false, has-input-connection=false, x=0.0, y=0.0, child-count=1}}, Root{application-window-token=android.view.ViewRootImpl$W@9b179bb, window-token=android.view.ViewRootImpl$W@9b179bb, has-window-focus=false, layout-params-type=1, layout-params-string=WM.LayoutParams{(0,0)(fillxfill) ty=1 fl=#1810100 wanim=0x10303e5 needsMenuKey=2}, decor-view-string=DecorView{id=-1, visibility=INVISIBLE, width=1080, height=1794, has-focus=false, has-focusable=false, has-window-focus=false, is-clickable=false, is-enabled=true, is-focused=false, is-focusable=false, is-layout-requested=false, is-selected=false, root-is-layout-requested=false, has-input-connection=false, x=0.0, y=0.0, child-count=1}}]
at dalvik.system.VMStack.getThreadStackTrace(Native Method)
at java.lang.Thread.getStackTrace(Thread.java:580)
The code for creating the dialog:
public class ServiceItemFragment extends Fragment {
...
public void showASampleDialog() {
DialogFragment newFragment = SampleDialogFragment.newInstance(
R.string.dialog_title);
newFragment.show(getFragmentManager(), "dialog");
}
}
The code of the Dialog Fragment:
public class SampleDialogFragment extends DialogFragment {
public static SampleDialogFragment newInstance(int title) {
SampleDialogFragment frag = new SampleDialogFragment();
Bundle args = new Bundle();
args.putInt("title", title);
frag.setArguments(args);
return frag;
}
@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
int title = getArguments().getInt("title");
return new AlertDialog.Builder(getActivity())
.setTitle(title)
.setPositiveButton("Ok",
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int whichButton) {
Log.i(getClass().getSimpleName(), "Positive click");
}
}
)
.setNegativeButton("Cancel",
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int whichButton) {
Log.i(getClass().getSimpleName(), "Negative click");
}
}
)
.create();
}
}
Solution
To try to fix this, I added inRoot(isDialog()) into the statement:
onView(withText("Ok")).inRoot(isDialog()).check(matches(isDisplayed()));
It would be work if you were using AlertDialog
, but not with DialogFragment
For this purpose the best solution is your actual workaround, I mean:
UIAutomator: UiDevice device = UiDevice.getInstance(getInstrumentation());
UiObject uiObject = device.findObject(new UiSelector().text("Ok"));
try {
uiObject.click();
} catch (UiObjectNotFoundException e) {
throw new RuntimeException("UI Object not found", e);
}
Similar post and answer would be found here: Android UI testing with Espresso on an AlertDialog inner views
Try also to ommit inRoot()
matcher and write the test as simple as possible like:
onView(withText("Ok")).check(matches(isDisplayed()));
This might be also useful: http://qathread.blogspot.com/2015/05/espresso-uiautomator-perfect-tandem.html
Answered By - piotrek1543
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.