android - Espresso waiting for textview -
i have service connecting socket.io server. simple app sends message , gets echoed client. have test follows:
@test public void checksendmessage() { final string testmessage = "here test message"; onview(withid(r.id.textentry)).perform(typetext(testmessage), closesoftkeyboard()); onview(withid(r.id.send)).perform(click()); onview(withid(r.id.messages)).check(matches(withtext(containsstring(testmessage)))); }
i have server running on local network, , in scenario runs , passes. however, if add 3 second delay in server, test fails. want wait x seconds , check if contains text.
i have seen similar questions people answering use idlingresource. not sure how integrate app. guess have implement isidlenow function. using service connects com.koushikdutta.async.http.socketio.socketioclient;
it doesn't ever go idle though, sits there listening on socket. not waiting finish, want keep checking view x seconds see if message arrived. how might this?
i have solved writing custom idlingresource checks view assertion on every isidlenow , times out per code below:
@test public void checksendmessage() { final string testmessage = "here test message"; onview(withid(r.id.textentry)).perform(typetext(testmessage), closesoftkeyboard()); onview(withid(r.id.send)).perform(click()); waitfor(onview(withid(r.id.messages)), matches(withtext(containsstring(testmessage))), 5000); } private void waitfor(viewinteraction viewinteraction, viewassertion viewassertion, long timeout) { pollingtimeoutidler idler = new pollingtimeoutidler(viewinteraction, viewassertion, timeout); espresso.registeridlingresources(idler); viewinteraction.check(viewassertion); espresso.unregisteridlingresources(idler); } private class pollingtimeoutidler implements idlingresource { private final viewassertion mviewassertion; private final long mtimeout; private final long mstarttime; private resourcecallback mcallback; private volatile view mtestview; public pollingtimeoutidler(viewinteraction viewinteraction, viewassertion viewassertion, long timeout) { mviewassertion = viewassertion; mtimeout = timeout; mstarttime = system.currenttimemillis(); viewinteraction.check(new viewassertion() { @override public void check(view view, nomatchingviewexception noviewfoundexception) { mtestview = view; } }); } @override public string getname() { return getclass().getsimplename(); } @override public boolean isidlenow() { long elapsed = system.currenttimemillis() - mstarttime; boolean timedout = elapsed >= mtimeout; boolean idle = testview() || timedout; if(idle) { mcallback.ontransitiontoidle(); } return idle; } private boolean testview() { if(mtestview != null) { try { mviewassertion.check(mtestview, null); return true; } catch(assertionfailederror ex) { return false; } } else { return false; } } @override public void registeridletransitioncallback(resourcecallback callback) { mcallback = callback; } }
it works surely there better way? feels super hacky , espresso should provide me. fact doesn't leads me believe thinking wrong way test. there better way test same behaviour?
Comments
Post a Comment