Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,10 @@

import org.hamcrest.Matcher;

import androidx.test.espresso.NoMatchingViewException;
import androidx.test.espresso.ViewAction;
import androidx.test.espresso.ViewInteraction;
import androidx.test.espresso.matcher.RootMatchers;

import static androidx.test.espresso.Espresso.onView;
import static androidx.test.espresso.assertion.ViewAssertions.doesNotExist;
Expand All @@ -32,9 +34,14 @@ private DetoxAssertion() {

/**
* Asserts the given matcher for the provided view interaction.
* Falls back to dialog root if the assertion fails in the default root.
*/
public static ViewInteraction assertMatcher(ViewInteraction viewInteraction, Matcher<View> viewMatcher) {
return viewInteraction.check(matches(viewMatcher));
try {
return viewInteraction.check(matches(viewMatcher));
} catch (NoMatchingViewException e) {
return viewInteraction.inRoot(RootMatchers.isDialog()).check(matches(viewMatcher));
}
}

/**
Expand All @@ -60,6 +67,7 @@ public static ViewInteraction assertNotExists(ViewInteraction viewInteraction) {

/**
* Waits until the provided matcher matches the view interaction or a timeout occurs.
* Tries both the default root and dialog root on each iteration.
*/
public static void waitForAssertMatcher(final ViewInteraction viewInteraction, final Matcher<View> viewMatcher, double timeoutSeconds) {
final long startTime = System.nanoTime();
Expand All @@ -77,7 +85,21 @@ public static void waitForAssertMatcher(final ViewInteraction viewInteraction, f
viewInteraction.check(matches(viewMatcher));
break;
} catch (AssertionFailedError err) {
UiAutomatorHelper.espressoSync(20);
// Try dialog root as fallback
try {
viewInteraction.inRoot(RootMatchers.isDialog()).check(matches(viewMatcher));
break;
} catch (Exception dialogErr) {
UiAutomatorHelper.espressoSync(20);
}
} catch (NoMatchingViewException e) {
// Try dialog root as fallback
try {
viewInteraction.inRoot(RootMatchers.isDialog()).check(matches(viewMatcher));
break;
} catch (Exception dialogErr) {
UiAutomatorHelper.espressoSync(20);
}
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,9 @@ import com.wix.detox.espresso.errors.DetoxNoMatchingViewException

import android.view.View
import androidx.test.espresso.Espresso.onView
import androidx.test.espresso.NoMatchingViewException
import androidx.test.espresso.ViewAction
import androidx.test.espresso.matcher.RootMatchers
import org.hamcrest.Matcher

class MultipleViewsActionPerformer(
Expand All @@ -20,7 +22,12 @@ class MultipleViewsActionPerformer(
val indexedMatcher = DetoxMatcher.matcherForAtIndex(index, matcher)

try {
onView(indexedMatcher).perform(action)
try {
onView(indexedMatcher).perform(action)
} catch (e: NoMatchingViewException) {
// Fallback: try dialog root (e.g. React Native Modal)
onView(indexedMatcher).inRoot(RootMatchers.isDialog()).perform(action)
}

(action as? ViewActionWithResult<*>)?.getResult()?.let { results.add(it) }

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,19 @@ import android.view.View
import androidx.test.espresso.Espresso.onView
import androidx.test.espresso.NoMatchingViewException
import androidx.test.espresso.ViewAction
import androidx.test.espresso.matcher.RootMatchers
import org.hamcrest.Matcher

class SingleViewActionPerformer(
private val action: ViewAction
) : ViewActionPerformer {
override fun performOn(matcher: Matcher<View>): Any? {
onView(matcher).perform(action)
try {
onView(matcher).perform(action)
} catch (e: NoMatchingViewException) {
// Fallback: try dialog root (e.g. React Native Modal)
onView(matcher).inRoot(RootMatchers.isDialog()).perform(action)
}

return (action as? ViewActionWithResult<*>)?.getResult()
}
Expand Down