Wait for ViewPager to be idle in instrumented tests

This fixes the flakiness issues with the intro tests
This commit is contained in:
Alexander Bakker 2022-06-06 18:01:10 +02:00
parent 5226def653
commit 043b17909c

View file

@ -13,10 +13,13 @@ import static junit.framework.TestCase.assertNull;
import static junit.framework.TestCase.assertTrue;
import static org.hamcrest.Matchers.not;
import androidx.test.espresso.IdlingRegistry;
import androidx.test.espresso.IdlingResource;
import androidx.test.espresso.ViewInteraction;
import androidx.test.ext.junit.rules.ActivityScenarioRule;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import androidx.test.filters.LargeTest;
import androidx.viewpager2.widget.ViewPager2;
import com.beemdevelopment.aegis.rules.ScreenshotTestRule;
import com.beemdevelopment.aegis.ui.IntroActivity;
@ -25,6 +28,8 @@ import com.beemdevelopment.aegis.vault.slots.BiometricSlot;
import com.beemdevelopment.aegis.vault.slots.PasswordSlot;
import com.beemdevelopment.aegis.vault.slots.SlotList;
import org.junit.After;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.RuleChain;
@ -39,9 +44,24 @@ import dagger.hilt.android.testing.HiltAndroidTest;
public class IntroTest extends AegisTest {
private final ActivityScenarioRule<IntroActivity> _activityRule = new ActivityScenarioRule<>(IntroActivity.class);
private ViewPager2IdlingResource _viewPager2IdlingResource;
@Rule
public final TestRule testRule = RuleChain.outerRule(_activityRule).around(new ScreenshotTestRule());
@Before
public void setUp() {
_activityRule.getScenario().onActivity(activity -> {
_viewPager2IdlingResource = new ViewPager2IdlingResource(activity.findViewById(R.id.pager), "viewPagerIdlingResource");
IdlingRegistry.getInstance().register(_viewPager2IdlingResource);
});
}
@After
public void tearDown() {
IdlingRegistry.getInstance().unregister(_viewPager2IdlingResource);
}
@Test
public void doIntro_None() {
ViewInteraction next = onView(withId(R.id.btnNext));
@ -56,7 +76,6 @@ public class IntroTest extends AegisTest {
next.perform(click());
prev.check(matches(not(isDisplayed())));
next.perform(click());
next.perform(click());
VaultRepository vault = _vaultManager.getVault();
assertFalse(vault.isEncryptionEnabled());
@ -93,4 +112,39 @@ public class IntroTest extends AegisTest {
assertTrue(slots.has(PasswordSlot.class));
assertFalse(slots.has(BiometricSlot.class));
}
// Source: https://stackoverflow.com/a/32763454/12972657
private static class ViewPager2IdlingResource implements IdlingResource {
private final String _resName;
private boolean _isIdle = true;
private IdlingResource.ResourceCallback _resourceCallback = null;
public ViewPager2IdlingResource(ViewPager2 viewPager, String resName) {
viewPager.registerOnPageChangeCallback(new ViewPager2.OnPageChangeCallback() {
@Override
public void onPageScrollStateChanged(int state) {
_isIdle = (state == ViewPager2.SCROLL_STATE_IDLE || state == ViewPager2.SCROLL_STATE_DRAGGING);
if (_isIdle && _resourceCallback != null) {
_resourceCallback.onTransitionToIdle();
}
}
});
_resName = resName;
}
@Override
public String getName() {
return _resName;
}
@Override
public boolean isIdleNow() {
return _isIdle;
}
@Override
public void registerIdleTransitionCallback(IdlingResource.ResourceCallback resourceCallback) {
_resourceCallback = resourceCallback;
}
}
}