@@ -60,7 +60,6 @@ private DrawerActions() {
60
60
}
61
61
62
62
private abstract static class DrawerAction implements ViewAction {
63
-
64
63
@ Override
65
64
public final Matcher <View > getConstraints () {
66
65
return isAssignableFrom (DrawerLayout .class );
@@ -84,7 +83,6 @@ public final void perform(UiController uiController, View view) {
84
83
drawer .addDrawerListener (idlingListener );
85
84
IdlingRegistry .getInstance ().register (idlingListener );
86
85
}
87
-
88
86
performAction (uiController , drawer );
89
87
uiController .loopMainThreadUntilIdle ();
90
88
@@ -194,17 +192,81 @@ protected Matcher<View> checkAction() {
194
192
}
195
193
196
194
@ Override
197
- protected void performAction (UiController uiController , DrawerLayout view ) {
198
- view .closeDrawer (gravity );
195
+ public void performAction (UiController uiController , DrawerLayout drawer ) {
196
+ IdlingDrawerClosedListener closeListener = new IdlingDrawerClosedListener ();
197
+ drawer .addDrawerListener (closeListener );
198
+ drawer .closeDrawer (gravity );
199
199
uiController .loopMainThreadUntilIdle ();
200
- // If still open wait some more...
201
- if (view .isDrawerVisible (gravity )) {
202
- uiController .loopMainThreadForAtLeast (300 );
203
- }
200
+ // Need to wait extra time after it closes to reduce flakiness.
201
+ uiController .loopMainThreadForAtLeast (300 );
202
+ drawer .removeDrawerListener (closeListener );
203
+ }
204
+ };
205
+ }
206
+
207
+ /**
208
+ * Creates an action that will wait for the drawer to close. Use this in cases where the closing
209
+ * of the drawer is implicit, such as selecting an item in the drawer. No operation if the drawer
210
+ * is closed. This uses an idling resource to wait for close, so it will fail if it does not close
211
+ * within the idling resource timeout.
212
+ */
213
+ public static ViewAction waitForClose () {
214
+ return new DrawerAction () {
215
+ @ Override
216
+ public String getDescription () {
217
+ return "waiting for drawer to close" ;
218
+ }
219
+
220
+ @ Override
221
+ protected Matcher <View > checkAction () {
222
+ return isOpen ();
223
+ }
224
+
225
+ @ Override
226
+ public void performAction (UiController uiController , DrawerLayout drawer ) {
227
+ // Add a listener that waits for the drawer to be closed, wait for it to idle,
228
+ // and then remove the listener immediately.
229
+ IdlingDrawerClosedListener closeListener = new IdlingDrawerClosedListener ();
230
+ drawer .addDrawerListener (closeListener );
231
+ uiController .loopMainThreadUntilIdle ();
232
+ drawer .removeDrawerListener (closeListener );
204
233
}
205
234
};
206
235
}
207
236
237
+ /** Drawer listener that functions as an {@link IdlingResource} for Espresso. */
238
+ private static final class IdlingDrawerClosedListener extends SimpleDrawerListener
239
+ implements IdlingResource {
240
+
241
+ private final int id = nextId .getAndIncrement ();
242
+
243
+ private ResourceCallback callback ;
244
+ private boolean isClosed = false ;
245
+
246
+ @ Override
247
+ public void onDrawerClosed (View view ) {
248
+ isClosed = true ;
249
+ if (callback != null ) {
250
+ callback .onTransitionToIdle ();
251
+ }
252
+ }
253
+
254
+ @ Override
255
+ public String getName () {
256
+ return "IdlingDrawerListener::" + id ;
257
+ }
258
+
259
+ @ Override
260
+ public boolean isIdleNow () {
261
+ return isClosed ;
262
+ }
263
+
264
+ @ Override
265
+ public void registerIdleTransitionCallback (ResourceCallback callback ) {
266
+ this .callback = callback ;
267
+ }
268
+ }
269
+
208
270
/** Drawer listener that functions as an {@link IdlingResource} for Espresso. */
209
271
private static final class IdlingDrawerListener extends SimpleDrawerListener
210
272
implements IdlingResource {
0 commit comments