Could not launch intent Intent

0

Here my Espresso's tests:

import okhttp3.mockwebserver.MockResponse
import okhttp3.mockwebserver.MockWebServer
import org.junit.After
import java.util.concurrent.TimeUnit

@RunWith(AndroidJUnit4::class)
class TradersActivityTest {
    private lateinit var mockServer: MockWebServer

    @Rule
    @JvmField
    var tradersIntentTestRule = IntentsTestRule(TradersActivity::class.java, false, false)

    @Before
    fun setup() {
        mockServer = MockWebServer()
        mockServer.start(8081)
    }

    @Test
fun hasTraders_noTradersTextView_isNotDisplayed() {
    mockServer.enqueue(MockResponse()
            .setResponseCode(200)
            .setBody(FileUtil.getStringFromFile(context, ONE_TRADER_NO_WALLETS_LIST)));
    tradersIntentTestRule.launchActivity(Intent())
    onView(withId(R.id.noTradersTextView))
            .check(matches(not(isDisplayed())))
}

    @Test
    fun toolBar_height() {
        onView(withId(R.id.toolBar))
                .check(matches(withHeightResId(R.dimen.tool_bar_height)))
    }

Test hasTraders_noTradersTextView_isNotDisplayed success pass.

But test toolBar_height fail with message:

java.lang.RuntimeException: No activities found. Did you forget to launch the activity by calling getActivity() or startActivitySync or similar?
at androidx.test.espresso.base.RootViewPicker.waitForAtLeastOneActivityToBeResumed(RootViewPicker.java:169)
at androidx.test.espresso.base.RootViewPicker.get(RootViewPicker.java:83)

So I change setup method:

 @Before
    fun setup() {
        mockServer = MockWebServer()
        mockServer.start(8081)

        mockServer.enqueue(MockResponse()
                .setResponseCode(200)
                .setBody(FileUtil.getStringFromFile(context, ONE_TRADER_NO_WALLETS_LIST)));
        tradersIntentTestRule.launchActivity(Intent())

        Debug.d(TAG, "SUCCCESS_START_MOCKWEBSRVER")
    }

Now test toolBar_height pass, but hasTraders_noTradersTextView_isNotDisplayed fail with message:

java.lang.RuntimeException: Could not launch intent Intent { flg=0x10000000 com.myproject.android.ui.activity.TradersActivity } within 45 seconds. Perhaps the main thread has not gone idle within a reasonable amount of time? There could be an animation or something constantly repainting the screen. Or the activity is doing network calls on creation? See the threaddump logs. For your reference the last time the event queue was idle before your activity launch request was 1556373134135 and now the last time the queue went idle was: 1556373143180. If these numbers are the same your activity might be hogging the event queue.
at androidx.test.runner.MonitoringInstrumentation.startActivitySync(MonitoringInstrumentation.java:459)

P.S. I need to start activity in test hasTraders_noTradersTextView_isNotDisplayed because it's a specific test. But I wan't to start activity in test toolBar_height

android
android-espresso
ui-testing
asked on Stack Overflow Apr 27, 2019 by Alex

1 Answer

0

In my UI automated tests, I have this classes:

public class UiTestHelper {

    public static Matcher<View> childAtPosition(
            final Matcher<View> parentMatcher, final int position) {

        return new TypeSafeMatcher<View>() {
            @Override
            public void describeTo(Description description) {
                description.appendText("Child at position " + position + " in parent ");
                parentMatcher.describeTo(description);
            }

            @Override
            public boolean matchesSafely(View view) {
                ViewParent parent = view.getParent();
                return parent instanceof ViewGroup && parentMatcher.matches(parent)
                        && view.equals(((ViewGroup) parent).getChildAt(position));
            }
        };
    }

    public static void clickOn(View view) {
        waitUntilVisible(view);
        onView(withId(view.getId())).perform(click());
    }

    public static void waitUntilVisible(View view) {
        ViewVisibilityIdlingResource idlingResource = new ViewVisibilityIdlingResource(view, VISIBLE);
        IdlingRegistry.getInstance().register(idlingResource);
    }

    public static void unregisterAllIdlingResources() {
        IdlingRegistry idlingRegistry = IdlingRegistry.getInstance();
        for (IdlingResource resource: idlingRegistry.getResources()) {
            idlingRegistry.unregister(resource);
        }
    }
}

and

public class ViewVisibilityIdlingResource implements IdlingResource {

    private final View view;
    private final int expectedVisibility;
    private boolean idle;
    private ResourceCallback resourceCallback;

    public ViewVisibilityIdlingResource(final View view, final int expectedVisibility) {
        this.view = view;
        this.expectedVisibility = expectedVisibility;
        this.idle = false;
        this.resourceCallback = null;
    }

    @Override
    public final String getName() {
        return ViewVisibilityIdlingResource.class.getSimpleName();
    }

    @Override
    public final boolean isIdleNow() {
        idle = idle || (view.getVisibility() == expectedVisibility && view.getWidth() > 0 && view.getHeight() > 0);

        if (idle) {
            if (resourceCallback != null) {
                resourceCallback.onTransitionToIdle();
            }
        }

        return idle;
    }

    @Override
    public void registerIdleTransitionCallback(ResourceCallback resourceCallback) {
        this.resourceCallback = resourceCallback;
    }

}

Then when I want to check that a view is there I call

UiTestHelper.waitUntilVisible(view);
answered on Stack Overflow Apr 27, 2019 by kingston

User contributions licensed under CC BY-SA 3.0