detox 20.5.0 → 20.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/Detox-android/com/wix/detox/{20.5.0/detox-20.5.0-javadoc.jar → 20.6.0/detox-20.6.0-javadoc.jar} +0 -0
- package/Detox-android/com/wix/detox/20.6.0/detox-20.6.0-javadoc.jar.md5 +1 -0
- package/Detox-android/com/wix/detox/20.6.0/detox-20.6.0-javadoc.jar.sha1 +1 -0
- package/Detox-android/com/wix/detox/20.6.0/detox-20.6.0-javadoc.jar.sha256 +1 -0
- package/Detox-android/com/wix/detox/20.6.0/detox-20.6.0-javadoc.jar.sha512 +1 -0
- package/Detox-android/com/wix/detox/{20.5.0/detox-20.5.0-sources.jar → 20.6.0/detox-20.6.0-sources.jar} +0 -0
- package/Detox-android/com/wix/detox/20.6.0/detox-20.6.0-sources.jar.md5 +1 -0
- package/Detox-android/com/wix/detox/20.6.0/detox-20.6.0-sources.jar.sha1 +1 -0
- package/Detox-android/com/wix/detox/20.6.0/detox-20.6.0-sources.jar.sha256 +1 -0
- package/Detox-android/com/wix/detox/20.6.0/detox-20.6.0-sources.jar.sha512 +1 -0
- package/Detox-android/com/wix/detox/20.6.0/detox-20.6.0.aar +0 -0
- package/Detox-android/com/wix/detox/20.6.0/detox-20.6.0.aar.md5 +1 -0
- package/Detox-android/com/wix/detox/20.6.0/detox-20.6.0.aar.sha1 +1 -0
- package/Detox-android/com/wix/detox/20.6.0/detox-20.6.0.aar.sha256 +1 -0
- package/Detox-android/com/wix/detox/20.6.0/detox-20.6.0.aar.sha512 +1 -0
- package/Detox-android/com/wix/detox/{20.5.0/detox-20.5.0.pom → 20.6.0/detox-20.6.0.pom} +1 -1
- package/Detox-android/com/wix/detox/20.6.0/detox-20.6.0.pom.md5 +1 -0
- package/Detox-android/com/wix/detox/20.6.0/detox-20.6.0.pom.sha1 +1 -0
- package/Detox-android/com/wix/detox/20.6.0/detox-20.6.0.pom.sha256 +1 -0
- package/Detox-android/com/wix/detox/20.6.0/detox-20.6.0.pom.sha512 +1 -0
- package/Detox-android/com/wix/detox/maven-metadata.xml +4 -4
- package/Detox-android/com/wix/detox/maven-metadata.xml.md5 +1 -1
- package/Detox-android/com/wix/detox/maven-metadata.xml.sha1 +1 -1
- package/Detox-android/com/wix/detox/maven-metadata.xml.sha256 +1 -1
- package/Detox-android/com/wix/detox/maven-metadata.xml.sha512 +1 -1
- package/Detox-ios-src.tbz +0 -0
- package/Detox-ios.tbz +0 -0
- package/android/detox/src/full/java/com/wix/detox/common/UIExtensions.kt +28 -0
- package/android/detox/src/full/java/com/wix/detox/espresso/DetoxMatcher.java +11 -1
- package/android/detox/src/full/java/com/wix/detox/espresso/action/GetAttributesAction.kt +4 -3
- package/android/detox/src/full/java/com/wix/detox/espresso/matcher/ViewMatchers.kt +8 -5
- package/android/detox/src/full/java/com/wix/detox/espresso/matcher/WithAccessibilityLabelMatcher.kt +23 -0
- package/android/detox/src/full/java/com/wix/detox/reactnative/ui/UIExtensions.kt +37 -0
- package/android/detox/src/full/java/com/wix/detox/reactnative/utils/RNUtils.kt +6 -0
- package/android/detox/src/testFull/java/com/wix/detox/UTHelpers.kt +12 -0
- package/android/detox/src/testFull/java/com/wix/detox/common/UIExtensionsTest.kt +107 -0
- package/android/detox/src/testFull/java/com/wix/detox/espresso/action/GetAttributesActionTest.kt +7 -6
- package/android/detox/src/testFull/java/com/wix/detox/espresso/matcher/ViewAtIndexMatcherSpec.kt +1 -2
- package/index.d.ts +24 -21
- package/package.json +2 -2
- package/src/android/core/NativeMatcher.js +17 -0
- package/src/android/espressoapi/DetoxMatcher.js +24 -0
- package/src/android/matchers/index.js +2 -2
- package/src/android/matchers/native.js +9 -1
- package/Detox-android/com/wix/detox/20.5.0/detox-20.5.0-javadoc.jar.md5 +0 -1
- package/Detox-android/com/wix/detox/20.5.0/detox-20.5.0-javadoc.jar.sha1 +0 -1
- package/Detox-android/com/wix/detox/20.5.0/detox-20.5.0-javadoc.jar.sha256 +0 -1
- package/Detox-android/com/wix/detox/20.5.0/detox-20.5.0-javadoc.jar.sha512 +0 -1
- package/Detox-android/com/wix/detox/20.5.0/detox-20.5.0-sources.jar.md5 +0 -1
- package/Detox-android/com/wix/detox/20.5.0/detox-20.5.0-sources.jar.sha1 +0 -1
- package/Detox-android/com/wix/detox/20.5.0/detox-20.5.0-sources.jar.sha256 +0 -1
- package/Detox-android/com/wix/detox/20.5.0/detox-20.5.0-sources.jar.sha512 +0 -1
- package/Detox-android/com/wix/detox/20.5.0/detox-20.5.0.aar +0 -0
- package/Detox-android/com/wix/detox/20.5.0/detox-20.5.0.aar.md5 +0 -1
- package/Detox-android/com/wix/detox/20.5.0/detox-20.5.0.aar.sha1 +0 -1
- package/Detox-android/com/wix/detox/20.5.0/detox-20.5.0.aar.sha256 +0 -1
- package/Detox-android/com/wix/detox/20.5.0/detox-20.5.0.aar.sha512 +0 -1
- package/Detox-android/com/wix/detox/20.5.0/detox-20.5.0.pom.md5 +0 -1
- package/Detox-android/com/wix/detox/20.5.0/detox-20.5.0.pom.sha1 +0 -1
- package/Detox-android/com/wix/detox/20.5.0/detox-20.5.0.pom.sha256 +0 -1
- package/Detox-android/com/wix/detox/20.5.0/detox-20.5.0.pom.sha512 +0 -1
|
Binary file
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
c051f79d02bcc98757dd1ea06512a63b
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
bb48d0747cb607e73a01d64f5eb758ce00e376cb
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
b31397b81cdca47b2d5dc1aca7821f2691d236114064949ad8553fd81340fe02
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
6cec7c20f0d9643b98e2fa2f4740c9bb7a4b82ae3851069bb183e16ffcace8b0ceb07cf8d19316a960beb2330ea3e0a508df80cda1561242149ce3b16357d954
|
|
Binary file
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
6202d8d0f83dda9ed0c9d6962259350e
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
505b10faaca41e1b5e7f27b8829cd14aff6b5626
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
f4b81a4c2c1665975ac5be02698e288a311e3cd3c728ba9b05e72a1932f7482e
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
e355acd2730e5ca57bb7f2c092942b6dd98997645b43350fd2c80051f3f8a6840f2746cd2e8fbeae862ab4cac0fc6339b7f298e697f3bfb4124598370c4b2a54
|
|
Binary file
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
f62ab63d03ba71b4776965696f3d4a88
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
1a38f931edf9925af1d131a0e0a0822bd880dcc8
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
4145b5a8078b613e10205937ffb3da254d006fe78fbb169d8b2cedb3d02c021c
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
ab25979faccc1aa8200a637ea866a5fc59e35bf340170673a01253ae8ce479fb5b7af87167dbde2d43d5b536f3fb350b34b478bbf75f5e87d5276940283a8ab6
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
<modelVersion>4.0.0</modelVersion>
|
|
4
4
|
<groupId>com.wix</groupId>
|
|
5
5
|
<artifactId>detox</artifactId>
|
|
6
|
-
<version>20.
|
|
6
|
+
<version>20.6.0</version>
|
|
7
7
|
<packaging>aar</packaging>
|
|
8
8
|
<name>Detox</name>
|
|
9
9
|
<description>Gray box end-to-end testing and automation library for mobile apps</description>
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
120956f03efbba5c9cec898b7da52efe
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
b6c2c0740f1de17d7dc5671d096debbe7eb46dd3
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
8fdf9933acc2bcc22588bc3cffb6348ab73f8100c5212f7e607e315bce59a265
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
f3ae74b6397013d7a5af6ed08cbbd739f5e207df9463a6b6cb496bd1b9a87022f193b87207d6424f2b8b85e022836211215cd01eaa88f9adcea6515594f59e76
|
|
@@ -3,11 +3,11 @@
|
|
|
3
3
|
<groupId>com.wix</groupId>
|
|
4
4
|
<artifactId>detox</artifactId>
|
|
5
5
|
<versioning>
|
|
6
|
-
<latest>20.
|
|
7
|
-
<release>20.
|
|
6
|
+
<latest>20.6.0</latest>
|
|
7
|
+
<release>20.6.0</release>
|
|
8
8
|
<versions>
|
|
9
|
-
<version>20.
|
|
9
|
+
<version>20.6.0</version>
|
|
10
10
|
</versions>
|
|
11
|
-
<lastUpdated>
|
|
11
|
+
<lastUpdated>20230322171518</lastUpdated>
|
|
12
12
|
</versioning>
|
|
13
13
|
</metadata>
|
|
@@ -1 +1 @@
|
|
|
1
|
-
|
|
1
|
+
f72e8f5e279054eb2e8e8faab020aaab
|
|
@@ -1 +1 @@
|
|
|
1
|
-
|
|
1
|
+
4e3513e973cd69a3ce1b30d0756ba26660ae1ba6
|
|
@@ -1 +1 @@
|
|
|
1
|
-
|
|
1
|
+
319540a82e8d028d9fe417155b17c95ae4d62f0cf9f18a751a1827a27acf1802
|
|
@@ -1 +1 @@
|
|
|
1
|
-
|
|
1
|
+
92f9a95efb7117c43c5df7765e56d81d8ef34b2413ef04e6133d7a3d51ccb88bec0aa80bba83d302ebe4dee638270ec57e03b0a3fc972e8552fd94365065fd3a
|
package/Detox-ios-src.tbz
CHANGED
|
Binary file
|
package/Detox-ios.tbz
CHANGED
|
Binary file
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
package com.wix.detox.common
|
|
2
|
+
|
|
3
|
+
import android.view.View
|
|
4
|
+
import android.view.ViewGroup
|
|
5
|
+
|
|
6
|
+
fun View.forEachChild(callback: (child: View) -> Unit) {
|
|
7
|
+
if (this is ViewGroup) {
|
|
8
|
+
for (index in 0 until childCount) {
|
|
9
|
+
val child = getChildAt(index)
|
|
10
|
+
callback(child)
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* In-order traverse the view-hierarchy specified by a view, considered to be the hierarchy's root.
|
|
17
|
+
*
|
|
18
|
+
* @param view The hierarchy's root-view.
|
|
19
|
+
* @param callback A function to call per each view. Returning `false` from the callback indicates
|
|
20
|
+
* a request to refrain from traversing the sub-hierarchy associated with the current view.
|
|
21
|
+
*/
|
|
22
|
+
fun traverseViewHierarchy(view: View, callback: (view: View) -> Boolean) {
|
|
23
|
+
if (callback(view)) {
|
|
24
|
+
view.forEachChild { child ->
|
|
25
|
+
traverseViewHierarchy(child, callback)
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
}
|
|
@@ -12,15 +12,17 @@ import static androidx.test.espresso.matcher.ViewMatchers.isChecked;
|
|
|
12
12
|
import static androidx.test.espresso.matcher.ViewMatchers.isDescendantOfA;
|
|
13
13
|
import static androidx.test.espresso.matcher.ViewMatchers.isDisplayed;
|
|
14
14
|
import static androidx.test.espresso.matcher.ViewMatchers.isDisplayingAtLeast;
|
|
15
|
+
import static androidx.test.espresso.matcher.ViewMatchers.isFocused;
|
|
15
16
|
import static androidx.test.espresso.matcher.ViewMatchers.isNotChecked;
|
|
16
17
|
import static androidx.test.espresso.matcher.ViewMatchers.withContentDescription;
|
|
17
18
|
import static androidx.test.espresso.matcher.ViewMatchers.withEffectiveVisibility;
|
|
18
19
|
import static androidx.test.espresso.matcher.ViewMatchers.withTagValue;
|
|
19
20
|
import static androidx.test.espresso.matcher.ViewMatchers.withText;
|
|
20
|
-
import static androidx.test.espresso.matcher.ViewMatchers.isFocused;
|
|
21
21
|
import static com.wix.detox.espresso.matcher.ViewMatchers.isMatchingAtIndex;
|
|
22
22
|
import static com.wix.detox.espresso.matcher.ViewMatchers.isOfClassName;
|
|
23
23
|
import static com.wix.detox.espresso.matcher.ViewMatchers.toHaveSliderPosition;
|
|
24
|
+
import static com.wix.detox.espresso.matcher.ViewMatchers.withAccessibilityLabel;
|
|
25
|
+
import static com.wix.detox.espresso.matcher.ViewMatchers.withShallowAccessibilityLabel;
|
|
24
26
|
import static org.hamcrest.Matchers.allOf;
|
|
25
27
|
import static org.hamcrest.Matchers.anyOf;
|
|
26
28
|
import static org.hamcrest.Matchers.is;
|
|
@@ -43,6 +45,14 @@ public class DetoxMatcher {
|
|
|
43
45
|
return allOf(withText(text), withEffectiveVisibility(Visibility.VISIBLE));
|
|
44
46
|
}
|
|
45
47
|
|
|
48
|
+
public static Matcher<View> matcherForAccessibilityLabel(String label) {
|
|
49
|
+
return allOf(withAccessibilityLabel(label), withEffectiveVisibility(Visibility.VISIBLE));
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
public static Matcher<View> matcherForShallowAccessibilityLabel(String label) {
|
|
53
|
+
return allOf(withShallowAccessibilityLabel(label), withEffectiveVisibility(Visibility.VISIBLE));
|
|
54
|
+
}
|
|
55
|
+
|
|
46
56
|
public static Matcher<View> matcherForContentDescription(String contentDescription) {
|
|
47
57
|
return allOf(withContentDescription(contentDescription), withEffectiveVisibility(Visibility.VISIBLE));
|
|
48
58
|
}
|
|
@@ -10,6 +10,7 @@ import androidx.test.espresso.UiController
|
|
|
10
10
|
import com.google.android.material.slider.Slider
|
|
11
11
|
import com.wix.detox.espresso.ViewActionWithResult
|
|
12
12
|
import com.wix.detox.espresso.common.SliderHelper
|
|
13
|
+
import com.wix.detox.reactnative.ui.getAccessibilityLabel
|
|
13
14
|
import org.hamcrest.Matcher
|
|
14
15
|
import org.hamcrest.Matchers
|
|
15
16
|
import org.hamcrest.Matchers.allOf
|
|
@@ -47,7 +48,7 @@ private class CommonAttributes {
|
|
|
47
48
|
fun get(json: JSONObject, view: View) {
|
|
48
49
|
getId(json, view)
|
|
49
50
|
getVisibility(json, view)
|
|
50
|
-
|
|
51
|
+
getAccessibilityLabel(json, view)
|
|
51
52
|
getAlpha(json, view)
|
|
52
53
|
getElevation(json, view)
|
|
53
54
|
getHeight(json, view)
|
|
@@ -66,8 +67,8 @@ private class CommonAttributes {
|
|
|
66
67
|
json.put("visible", view.getLocalVisibleRect(Rect()))
|
|
67
68
|
}
|
|
68
69
|
|
|
69
|
-
private fun
|
|
70
|
-
view.
|
|
70
|
+
private fun getAccessibilityLabel(json: JSONObject, view: View) =
|
|
71
|
+
view.getAccessibilityLabel()?.let {
|
|
71
72
|
json.put("label", it)
|
|
72
73
|
}
|
|
73
74
|
|
|
@@ -8,17 +8,20 @@ import androidx.test.espresso.matcher.BoundedMatcher
|
|
|
8
8
|
import androidx.test.espresso.matcher.ViewMatchers
|
|
9
9
|
import androidx.test.espresso.matcher.ViewMatchers.withEffectiveVisibility
|
|
10
10
|
import com.wix.detox.espresso.common.SliderHelper
|
|
11
|
-
import org.hamcrest
|
|
12
|
-
import org.hamcrest.
|
|
13
|
-
import org.hamcrest.Matcher
|
|
14
|
-
import org.hamcrest.Matchers.allOf
|
|
15
|
-
import org.hamcrest.TypeSafeMatcher
|
|
11
|
+
import org.hamcrest.*
|
|
12
|
+
import org.hamcrest.Matchers.*
|
|
16
13
|
import kotlin.math.abs
|
|
17
14
|
|
|
18
15
|
/*
|
|
19
16
|
* An extension of [androidx.test.espresso.matcher.ViewMatchers].
|
|
20
17
|
*/
|
|
21
18
|
|
|
19
|
+
fun withAccessibilityLabel(text: String) =
|
|
20
|
+
WithAccessibilityLabelMatcher(`is`(text))
|
|
21
|
+
|
|
22
|
+
fun withShallowAccessibilityLabel(label: String): Matcher<View>
|
|
23
|
+
= anyOf(ViewMatchers.withContentDescription(label), ViewMatchers.withText(label))
|
|
24
|
+
|
|
22
25
|
fun isOfClassName(className: String): Matcher<View> {
|
|
23
26
|
try {
|
|
24
27
|
val cls = Class.forName(className)
|
package/android/detox/src/full/java/com/wix/detox/espresso/matcher/WithAccessibilityLabelMatcher.kt
ADDED
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
package com.wix.detox.espresso.matcher
|
|
2
|
+
|
|
3
|
+
import android.view.View
|
|
4
|
+
import com.wix.detox.reactnative.ui.getAccessibilityLabel
|
|
5
|
+
import org.hamcrest.Description
|
|
6
|
+
import org.hamcrest.Matcher
|
|
7
|
+
import org.hamcrest.TypeSafeDiagnosingMatcher
|
|
8
|
+
|
|
9
|
+
class WithAccessibilityLabelMatcher(private val textMatcher: Matcher<String>): TypeSafeDiagnosingMatcher<View>() {
|
|
10
|
+
override fun matchesSafely(view: View, mismatchDescription: Description): Boolean =
|
|
11
|
+
view.getAccessibilityLabel().let { contentDescription ->
|
|
12
|
+
return textMatcher.matches(contentDescription).also { matched ->
|
|
13
|
+
if (!matched) {
|
|
14
|
+
mismatchDescription.appendText("view.getAccessibilityLabel() ")
|
|
15
|
+
textMatcher.describeMismatch(contentDescription, mismatchDescription)
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
override fun describeTo(description: Description) {
|
|
21
|
+
description.appendText("view.getAccessibilityLabel() ").appendDescriptionOf(textMatcher)
|
|
22
|
+
}
|
|
23
|
+
}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
package com.wix.detox.reactnative.ui
|
|
2
|
+
|
|
3
|
+
import android.view.View
|
|
4
|
+
import android.widget.TextView
|
|
5
|
+
import com.wix.detox.common.traverseViewHierarchy
|
|
6
|
+
import com.wix.detox.reactnative.utils.isReactNativeObject
|
|
7
|
+
|
|
8
|
+
fun View.getAccessibilityLabel(
|
|
9
|
+
isReactNativeObjectFn: (Any) -> Boolean = { isReactNativeObject(it) }
|
|
10
|
+
): CharSequence? =
|
|
11
|
+
if (isReactNativeObjectFn(this)) {
|
|
12
|
+
val subLabels = collectAccessibilityLabelsFromHierarchy(this)
|
|
13
|
+
if (subLabels.isEmpty()) null else subLabels.joinToString(" ")
|
|
14
|
+
} else {
|
|
15
|
+
getRawAccessibilityLabel(this)
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
private fun collectAccessibilityLabelsFromHierarchy(
|
|
19
|
+
rootView: View,
|
|
20
|
+
subLabels: MutableList<CharSequence> = mutableListOf(),
|
|
21
|
+
): List<CharSequence> {
|
|
22
|
+
traverseViewHierarchy(rootView) { view ->
|
|
23
|
+
getRawAccessibilityLabel(view)?.let { rawLabel ->
|
|
24
|
+
subLabels.add(rawLabel)
|
|
25
|
+
false
|
|
26
|
+
} ?: true
|
|
27
|
+
|
|
28
|
+
}
|
|
29
|
+
return subLabels
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
private fun getRawAccessibilityLabel(view: View): CharSequence? =
|
|
33
|
+
if (view.contentDescription != null) {
|
|
34
|
+
view.contentDescription
|
|
35
|
+
} else if (view is TextView) {
|
|
36
|
+
view.text
|
|
37
|
+
} else null
|
|
@@ -1,8 +1,20 @@
|
|
|
1
1
|
package com.wix.detox
|
|
2
2
|
|
|
3
|
+
import android.view.View
|
|
4
|
+
import android.view.ViewGroup
|
|
5
|
+
import org.mockito.ArgumentMatchers.eq
|
|
6
|
+
import org.mockito.kotlin.whenever
|
|
3
7
|
import java.util.concurrent.ExecutorService
|
|
4
8
|
import java.util.concurrent.TimeUnit
|
|
5
9
|
|
|
6
10
|
object UTHelpers {
|
|
7
11
|
fun yieldToOtherThreads(executor: ExecutorService) = executor.awaitTermination(100L, TimeUnit.MILLISECONDS)
|
|
12
|
+
|
|
13
|
+
fun mockViewHierarchy(parent: ViewGroup, vararg children: View) {
|
|
14
|
+
whenever(parent.childCount).thenReturn(children.size)
|
|
15
|
+
|
|
16
|
+
children.forEachIndexed { index, view ->
|
|
17
|
+
whenever(parent.getChildAt(eq(index))).thenReturn(view)
|
|
18
|
+
}
|
|
19
|
+
}
|
|
8
20
|
}
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
package com.wix.detox.common
|
|
2
|
+
|
|
3
|
+
import android.view.View
|
|
4
|
+
import android.view.ViewGroup
|
|
5
|
+
import android.widget.TextView
|
|
6
|
+
import com.wix.detox.UTHelpers.mockViewHierarchy
|
|
7
|
+
import com.wix.detox.reactnative.ui.getAccessibilityLabel
|
|
8
|
+
import org.assertj.core.api.Assertions
|
|
9
|
+
import org.junit.Test
|
|
10
|
+
import org.junit.runner.RunWith
|
|
11
|
+
import org.mockito.kotlin.doReturn
|
|
12
|
+
import org.mockito.kotlin.mock
|
|
13
|
+
import org.mockito.kotlin.whenever
|
|
14
|
+
import org.robolectric.RobolectricTestRunner
|
|
15
|
+
|
|
16
|
+
@RunWith(RobolectricTestRunner::class)
|
|
17
|
+
class UIExtensionsTest {
|
|
18
|
+
private val alwaysReactNativeObjFn: (Any) -> Boolean = { true }
|
|
19
|
+
private val neverReactNativeObjFn: (Any) -> Boolean = { false }
|
|
20
|
+
|
|
21
|
+
private fun withContentDescription(value: String, v: View) { whenever(v.contentDescription).doReturn(value) }
|
|
22
|
+
private fun withText(value: String, v: TextView) { whenever(v.text).doReturn(value) }
|
|
23
|
+
|
|
24
|
+
@Test
|
|
25
|
+
fun `should return accessibility label according to content-description`() {
|
|
26
|
+
val view: View = mock()
|
|
27
|
+
|
|
28
|
+
val contentDescription = "content-description-mock"
|
|
29
|
+
withContentDescription(contentDescription, view)
|
|
30
|
+
|
|
31
|
+
val label = view.getAccessibilityLabel()
|
|
32
|
+
Assertions.assertThat(label).isEqualTo(contentDescription)
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
@Test
|
|
36
|
+
fun `should return accessibility label according to children's content-description, recursively`() {
|
|
37
|
+
val contentDescription1st = "cd.1"
|
|
38
|
+
val contentDescription2nd = "cd.2"
|
|
39
|
+
val expectedLabel = "$contentDescription1st $contentDescription2nd"
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
val parent: ViewGroup = mock()
|
|
43
|
+
val sibling1: ViewGroup = mock()
|
|
44
|
+
val sibling2: ViewGroup = mock<ViewGroup>().also {
|
|
45
|
+
withContentDescription(contentDescription2nd, it)
|
|
46
|
+
}
|
|
47
|
+
val grandchild: View = mock<View>().also {
|
|
48
|
+
withContentDescription(contentDescription1st, it)
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
mockViewHierarchy(parent, sibling1, sibling2)
|
|
52
|
+
mockViewHierarchy(sibling1, grandchild)
|
|
53
|
+
|
|
54
|
+
val label = parent.getAccessibilityLabel(alwaysReactNativeObjFn)
|
|
55
|
+
Assertions.assertThat(label).isEqualTo(expectedLabel)
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
@Test
|
|
59
|
+
fun `should return accessibility label according to children's text, on top of label`() {
|
|
60
|
+
val text = "some mocked text"
|
|
61
|
+
|
|
62
|
+
val parent: ViewGroup = mock()
|
|
63
|
+
val grandchild: TextView = mock<TextView>().also {
|
|
64
|
+
withText(text, it)
|
|
65
|
+
}
|
|
66
|
+
mockViewHierarchy(parent, grandchild)
|
|
67
|
+
|
|
68
|
+
val label = parent.getAccessibilityLabel(alwaysReactNativeObjFn)
|
|
69
|
+
Assertions.assertThat(label).isEqualTo(text)
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
@Test
|
|
73
|
+
fun `should not return accessibility label if content description not set in view nor its descendants`() {
|
|
74
|
+
val parent: ViewGroup = mock()
|
|
75
|
+
val child: View = mock()
|
|
76
|
+
|
|
77
|
+
mockViewHierarchy(parent, child)
|
|
78
|
+
|
|
79
|
+
val label = parent.getAccessibilityLabel(alwaysReactNativeObjFn)
|
|
80
|
+
Assertions.assertThat(label).isNull()
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
@Test
|
|
84
|
+
fun `should not return accessibility label based on children for non-RN views`() {
|
|
85
|
+
val childContentDescription = "content-description-mock"
|
|
86
|
+
|
|
87
|
+
val parent: ViewGroup = mock()
|
|
88
|
+
val child: View = mock<View>().also {
|
|
89
|
+
withContentDescription(childContentDescription, it)
|
|
90
|
+
}
|
|
91
|
+
mockViewHierarchy(parent, child)
|
|
92
|
+
|
|
93
|
+
val label = parent.getAccessibilityLabel(neverReactNativeObjFn)
|
|
94
|
+
Assertions.assertThat(label).isNull()
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
@Test
|
|
98
|
+
fun `should return accessibility label for non-RN views`() {
|
|
99
|
+
val view: View = mock()
|
|
100
|
+
|
|
101
|
+
val contentDescription = "content-description-mock"
|
|
102
|
+
withContentDescription(contentDescription, view)
|
|
103
|
+
|
|
104
|
+
val label = view.getAccessibilityLabel(neverReactNativeObjFn)
|
|
105
|
+
Assertions.assertThat(label).isEqualTo(contentDescription)
|
|
106
|
+
}
|
|
107
|
+
}
|
package/android/detox/src/testFull/java/com/wix/detox/espresso/action/GetAttributesActionTest.kt
CHANGED
|
@@ -6,6 +6,7 @@ import android.widget.ProgressBar
|
|
|
6
6
|
import android.widget.TextView
|
|
7
7
|
import com.facebook.react.views.slider.ReactSlider
|
|
8
8
|
import com.google.android.material.slider.Slider
|
|
9
|
+
import com.wix.detox.reactnative.ui.getAccessibilityLabel
|
|
9
10
|
import org.assertj.core.api.Assertions.assertThat
|
|
10
11
|
import org.json.JSONObject
|
|
11
12
|
import org.junit.Before
|
|
@@ -32,7 +33,7 @@ class GetAttributesActionTest {
|
|
|
32
33
|
private fun givenNoViewTag() = givenViewTag(null)
|
|
33
34
|
private fun givenVisibility(value: Int) { whenever(view.visibility).doReturn(value) }
|
|
34
35
|
private fun givenVisibilityRectAvailability(value: Boolean) { whenever(view.getLocalVisibleRect(any())).doReturn(value) }
|
|
35
|
-
private fun
|
|
36
|
+
private fun givenAccessibilityLabel(value: String) { whenever(view.getAccessibilityLabel()).doReturn(value) }
|
|
36
37
|
|
|
37
38
|
private fun perform(v: View = view): JSONObject {
|
|
38
39
|
uut.perform(null, v)
|
|
@@ -110,16 +111,16 @@ class GetAttributesActionTest {
|
|
|
110
111
|
}
|
|
111
112
|
|
|
112
113
|
@Test
|
|
113
|
-
fun `should return label according to
|
|
114
|
-
val
|
|
115
|
-
|
|
114
|
+
fun `should return label according to accessibilityLabel extension`() {
|
|
115
|
+
val accessibilityLabel = "label-mock"
|
|
116
|
+
givenAccessibilityLabel(accessibilityLabel)
|
|
116
117
|
|
|
117
118
|
val resultJson = perform()
|
|
118
|
-
assertThat(resultJson.opt("label")).isEqualTo(
|
|
119
|
+
assertThat(resultJson.opt("label")).isEqualTo(accessibilityLabel)
|
|
119
120
|
}
|
|
120
121
|
|
|
121
122
|
@Test
|
|
122
|
-
fun `should not return label if
|
|
123
|
+
fun `should not return label if accessibility label is not available`() {
|
|
123
124
|
val resultJson = perform()
|
|
124
125
|
assertThat(resultJson.opt("label")).isNull()
|
|
125
126
|
}
|
package/android/detox/src/testFull/java/com/wix/detox/espresso/matcher/ViewAtIndexMatcherSpec.kt
CHANGED
|
@@ -3,7 +3,6 @@ package com.wix.detox.espresso.matcher
|
|
|
3
3
|
import android.view.View
|
|
4
4
|
import org.hamcrest.Description
|
|
5
5
|
import org.hamcrest.Matcher
|
|
6
|
-
import org.hamcrest.Matchers
|
|
7
6
|
import org.mockito.kotlin.mock
|
|
8
7
|
import org.mockito.kotlin.verify
|
|
9
8
|
import org.mockito.kotlin.whenever
|
|
@@ -28,7 +27,7 @@ object ViewAtIndexMatcherSpec: Spek({
|
|
|
28
27
|
uut.describeTo(description)
|
|
29
28
|
verify(description).appendText("View at index #0, of those matching MATCHER(innerMatcher description)")
|
|
30
29
|
}
|
|
31
|
-
|
|
30
|
+
|
|
32
31
|
it("should append a valid description for index≥0") {
|
|
33
32
|
val uut = ViewAtIndexMatcher(7, innerMatcher)
|
|
34
33
|
uut.describeTo(description)
|
package/index.d.ts
CHANGED
|
@@ -626,9 +626,8 @@ declare global {
|
|
|
626
626
|
|
|
627
627
|
interface Device {
|
|
628
628
|
/**
|
|
629
|
-
* Holds the environment-unique ID of the device
|
|
629
|
+
* Holds the environment-unique ID of the device, namely, the adb ID on Android (e.g. emulator-5554) and the Mac-global simulator UDID on iOS -
|
|
630
630
|
* as used by simctl (e.g. AAAAAAAA-BBBB-CCCC-DDDD-EEEEEEEEEEEE).
|
|
631
|
-
*
|
|
632
631
|
*/
|
|
633
632
|
id: string;
|
|
634
633
|
/**
|
|
@@ -1122,39 +1121,39 @@ declare global {
|
|
|
1122
1121
|
* expectation with a `not` expects the view's visible area to be smaller than N%.
|
|
1123
1122
|
* @param pct optional integer ranging from 1 to 100, indicating how much percent of the view should be
|
|
1124
1123
|
* visible to the user to be accepted.
|
|
1125
|
-
* @example await expect(element(by.id('
|
|
1124
|
+
* @example await expect(element(by.id('mainTitle'))).toBeVisible(35);
|
|
1126
1125
|
*/
|
|
1127
1126
|
toBeVisible(pct?: number): R;
|
|
1128
1127
|
|
|
1129
1128
|
/**
|
|
1130
1129
|
* Negate the expectation.
|
|
1131
|
-
* @example await expect(element(by.id('
|
|
1130
|
+
* @example await expect(element(by.id('cancelButton'))).not.toBeVisible();
|
|
1132
1131
|
*/
|
|
1133
1132
|
not: this;
|
|
1134
1133
|
|
|
1135
1134
|
/**
|
|
1136
1135
|
* Expect the view to not be visible.
|
|
1137
|
-
* @example await expect(element(by.id('
|
|
1136
|
+
* @example await expect(element(by.id('cancelButton'))).toBeNotVisible();
|
|
1138
1137
|
* @deprecated Use `.not.toBeVisible()` instead.
|
|
1139
1138
|
*/
|
|
1140
1139
|
toBeNotVisible(): R;
|
|
1141
1140
|
|
|
1142
1141
|
/**
|
|
1143
1142
|
* Expect the view to exist in the UI hierarchy.
|
|
1144
|
-
* @example await expect(element(by.id('
|
|
1143
|
+
* @example await expect(element(by.id('okButton'))).toExist();
|
|
1145
1144
|
*/
|
|
1146
1145
|
toExist(): R;
|
|
1147
1146
|
|
|
1148
1147
|
/**
|
|
1149
1148
|
* Expect the view to not exist in the UI hierarchy.
|
|
1150
|
-
* @example await expect(element(by.id('
|
|
1149
|
+
* @example await expect(element(by.id('cancelButton'))).toNotExist();
|
|
1151
1150
|
* @deprecated Use `.not.toExist()` instead.
|
|
1152
1151
|
*/
|
|
1153
1152
|
toNotExist(): R;
|
|
1154
1153
|
|
|
1155
1154
|
/**
|
|
1156
1155
|
* Expect the view to be focused.
|
|
1157
|
-
* @example await expect(element(by.id('
|
|
1156
|
+
* @example await expect(element(by.id('emailInput'))).toBeFocused();
|
|
1158
1157
|
*/
|
|
1159
1158
|
toBeFocused(): R;
|
|
1160
1159
|
|
|
@@ -1168,21 +1167,23 @@ declare global {
|
|
|
1168
1167
|
/**
|
|
1169
1168
|
* In React Native apps, expect UI component of type <Text> to have text.
|
|
1170
1169
|
* In native iOS apps, expect UI elements of type UIButton, UILabel, UITextField or UITextViewIn to have inputText with text.
|
|
1171
|
-
* @example await expect(element(by.id('
|
|
1170
|
+
* @example await expect(element(by.id('mainTitle'))).toHaveText('Welcome back!);
|
|
1172
1171
|
*/
|
|
1173
1172
|
toHaveText(text: string): R;
|
|
1174
1173
|
|
|
1175
1174
|
/**
|
|
1176
|
-
*
|
|
1177
|
-
*
|
|
1178
|
-
*
|
|
1175
|
+
* Expects a specific accessibilityLabel, as specified via the `accessibilityLabel` prop in React Native.
|
|
1176
|
+
* On the native side (in both React Native and pure-native apps), that is equivalent to `accessibilityLabel`
|
|
1177
|
+
* on iOS and contentDescription on Android. Refer to Detox's documentation in order to learn about caveats
|
|
1178
|
+
* with accessibility-labels in React Native apps.
|
|
1179
|
+
* @example await expect(element(by.id('submitButton'))).toHaveLabel('Submit');
|
|
1179
1180
|
*/
|
|
1180
1181
|
toHaveLabel(label: string): R;
|
|
1181
1182
|
|
|
1182
1183
|
/**
|
|
1183
1184
|
* In React Native apps, expect UI component to have testID with that id.
|
|
1184
1185
|
* In native iOS apps, expect UI element to have accessibilityIdentifier with that id.
|
|
1185
|
-
* @example await expect(element(by.text('
|
|
1186
|
+
* @example await expect(element(by.text('Submit'))).toHaveId('submitButton');
|
|
1186
1187
|
*/
|
|
1187
1188
|
toHaveId(id: string): R;
|
|
1188
1189
|
|
|
@@ -1195,7 +1196,7 @@ declare global {
|
|
|
1195
1196
|
|
|
1196
1197
|
/**
|
|
1197
1198
|
* Expect components like a Switch to have a value ('0' for off, '1' for on).
|
|
1198
|
-
* @example await expect(element(by.id('
|
|
1199
|
+
* @example await expect(element(by.id('temperatureDial'))).toHaveValue('25');
|
|
1199
1200
|
*/
|
|
1200
1201
|
toHaveValue(value: any): R;
|
|
1201
1202
|
|
|
@@ -1212,7 +1213,7 @@ declare global {
|
|
|
1212
1213
|
/**
|
|
1213
1214
|
* This API polls using the given expectation continuously until the expectation is met. Use manual synchronization with waitFor only as a last resort.
|
|
1214
1215
|
* NOTE: Every waitFor call must set a timeout using withTimeout(). Calling waitFor without setting a timeout will do nothing.
|
|
1215
|
-
* @example await waitFor(element(by.id('
|
|
1216
|
+
* @example await waitFor(element(by.id('bigButton'))).toExist().withTimeout(2000);
|
|
1216
1217
|
*/
|
|
1217
1218
|
(element: NativeElement): Expect<WaitFor>;
|
|
1218
1219
|
}
|
|
@@ -1220,13 +1221,13 @@ declare global {
|
|
|
1220
1221
|
interface WaitFor {
|
|
1221
1222
|
/**
|
|
1222
1223
|
* Waits for the condition to be met until the specified time (millis) have elapsed.
|
|
1223
|
-
* @example await waitFor(element(by.id('
|
|
1224
|
+
* @example await waitFor(element(by.id('bigButton'))).toExist().withTimeout(2000);
|
|
1224
1225
|
*/
|
|
1225
1226
|
withTimeout(millis: number): Promise<void>;
|
|
1226
1227
|
|
|
1227
1228
|
/**
|
|
1228
1229
|
* Performs the action repeatedly on the element until an expectation is met
|
|
1229
|
-
* @example await waitFor(element(by.text('
|
|
1230
|
+
* @example await waitFor(element(by.text('Item #5'))).toBeVisible().whileElement(by.id('itemsList')).scroll(50, 'down');
|
|
1230
1231
|
*/
|
|
1231
1232
|
whileElement(by: NativeMatcher): NativeElement & WaitFor;
|
|
1232
1233
|
|
|
@@ -1438,7 +1439,7 @@ declare global {
|
|
|
1438
1439
|
interface WebExpect<R = Promise<void>> {
|
|
1439
1440
|
/**
|
|
1440
1441
|
* Negate the expectation.
|
|
1441
|
-
* @example await expect(web.element(by.web.id('
|
|
1442
|
+
* @example await expect(web.element(by.web.id('sessionTimeout'))).not.toExist();
|
|
1442
1443
|
*/
|
|
1443
1444
|
not: this;
|
|
1444
1445
|
|
|
@@ -1446,13 +1447,13 @@ declare global {
|
|
|
1446
1447
|
* Expect the element content to have the `text` supplied
|
|
1447
1448
|
* @param text expected to be on the element content
|
|
1448
1449
|
* @example
|
|
1449
|
-
* await expect(web.element(by.web.id('
|
|
1450
|
+
* await expect(web.element(by.web.id('checkoutButton'))).toHaveText('Proceed to check out');
|
|
1450
1451
|
*/
|
|
1451
1452
|
toHaveText(text: string): R;
|
|
1452
1453
|
|
|
1453
1454
|
/**
|
|
1454
1455
|
* Expect the view to exist in the webview DOM tree.
|
|
1455
|
-
* @example await expect(web.element(by.web.id('
|
|
1456
|
+
* @example await expect(web.element(by.web.id('submitButton'))).toExist();
|
|
1456
1457
|
*/
|
|
1457
1458
|
toExist(): R;
|
|
1458
1459
|
}
|
|
@@ -1651,7 +1652,9 @@ declare global {
|
|
|
1651
1652
|
*/
|
|
1652
1653
|
text?: string;
|
|
1653
1654
|
/**
|
|
1654
|
-
* The label of the element.
|
|
1655
|
+
* The label of the element. Largely matches accessibilityLabel for ios, and contentDescription for android.
|
|
1656
|
+
* Refer to Detox's documentation (`toHaveLabel()` subsection) in order to learn about caveats associated with
|
|
1657
|
+
* this property in React Native apps.
|
|
1655
1658
|
*/
|
|
1656
1659
|
label?: string;
|
|
1657
1660
|
/**
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "detox",
|
|
3
3
|
"description": "E2E tests and automation for mobile",
|
|
4
|
-
"version": "20.
|
|
4
|
+
"version": "20.6.0",
|
|
5
5
|
"bin": {
|
|
6
6
|
"detox": "local-cli/cli.js"
|
|
7
7
|
},
|
|
@@ -200,5 +200,5 @@
|
|
|
200
200
|
}
|
|
201
201
|
}
|
|
202
202
|
},
|
|
203
|
-
"gitHead": "
|
|
203
|
+
"gitHead": "03e23e76b54f1e7de70495e0ec8a8db45872b0e6"
|
|
204
204
|
}
|
|
@@ -1,27 +1,44 @@
|
|
|
1
|
+
const { inspect } = require('util');
|
|
2
|
+
|
|
3
|
+
const { DetoxRuntimeError } = require('../../errors');
|
|
1
4
|
const invoke = require('../../invoke');
|
|
2
5
|
const DetoxMatcherApi = require('../espressoapi/DetoxMatcher');
|
|
3
6
|
|
|
4
7
|
class NativeMatcher {
|
|
8
|
+
static _assertMatcher(matcher) {
|
|
9
|
+
if (!(matcher instanceof NativeMatcher)) {
|
|
10
|
+
throw new DetoxRuntimeError({ message: `Expected a matcher, got: ${inspect(matcher)}` });
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
|
|
5
14
|
constructor(call) {
|
|
6
15
|
this._call = call || null;
|
|
7
16
|
}
|
|
8
17
|
|
|
9
18
|
withAncestor(matcher) {
|
|
19
|
+
NativeMatcher._assertMatcher(matcher);
|
|
20
|
+
|
|
10
21
|
const call = invoke.callDirectly(DetoxMatcherApi.matcherWithAncestor(this, matcher));
|
|
11
22
|
return new NativeMatcher(call);
|
|
12
23
|
}
|
|
13
24
|
|
|
14
25
|
withDescendant(matcher) {
|
|
26
|
+
NativeMatcher._assertMatcher(matcher);
|
|
27
|
+
|
|
15
28
|
const call = invoke.callDirectly(DetoxMatcherApi.matcherWithDescendant(this, matcher));
|
|
16
29
|
return new NativeMatcher(call);
|
|
17
30
|
}
|
|
18
31
|
|
|
19
32
|
and(matcher) {
|
|
33
|
+
NativeMatcher._assertMatcher(matcher);
|
|
34
|
+
|
|
20
35
|
const call = invoke.callDirectly(DetoxMatcherApi.matcherForAnd(this, matcher));
|
|
21
36
|
return new NativeMatcher(call);
|
|
22
37
|
}
|
|
23
38
|
|
|
24
39
|
or(matcher) {
|
|
40
|
+
NativeMatcher._assertMatcher(matcher);
|
|
41
|
+
|
|
25
42
|
const call = invoke.callDirectly(DetoxMatcherApi.matcherForOr(this, matcher));
|
|
26
43
|
return new NativeMatcher(call);
|
|
27
44
|
}
|
|
@@ -26,6 +26,30 @@ class DetoxMatcher {
|
|
|
26
26
|
};
|
|
27
27
|
}
|
|
28
28
|
|
|
29
|
+
static matcherForAccessibilityLabel(label) {
|
|
30
|
+
if (typeof label !== "string") throw new Error("label should be a string, but got " + (label + (" (" + (typeof label + ")"))));
|
|
31
|
+
return {
|
|
32
|
+
target: {
|
|
33
|
+
type: "Class",
|
|
34
|
+
value: "com.wix.detox.espresso.DetoxMatcher"
|
|
35
|
+
},
|
|
36
|
+
method: "matcherForAccessibilityLabel",
|
|
37
|
+
args: [label]
|
|
38
|
+
};
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
static matcherForShallowAccessibilityLabel(label) {
|
|
42
|
+
if (typeof label !== "string") throw new Error("label should be a string, but got " + (label + (" (" + (typeof label + ")"))));
|
|
43
|
+
return {
|
|
44
|
+
target: {
|
|
45
|
+
type: "Class",
|
|
46
|
+
value: "com.wix.detox.espresso.DetoxMatcher"
|
|
47
|
+
},
|
|
48
|
+
method: "matcherForShallowAccessibilityLabel",
|
|
49
|
+
args: [label]
|
|
50
|
+
};
|
|
51
|
+
}
|
|
52
|
+
|
|
29
53
|
static matcherForContentDescription(contentDescription) {
|
|
30
54
|
if (typeof contentDescription !== "string") throw new Error("contentDescription should be a string, but got " + (contentDescription + (" (" + (typeof contentDescription + ")"))));
|
|
31
55
|
return {
|
|
@@ -2,9 +2,9 @@ const native = require('./native');
|
|
|
2
2
|
const web = require('./web');
|
|
3
3
|
|
|
4
4
|
module.exports = {
|
|
5
|
-
accessibilityLabel: (value) => new native.LabelMatcher(value),
|
|
6
5
|
id: (value) => new native.IdMatcher(value),
|
|
7
|
-
label: (value) => new native.
|
|
6
|
+
label: (value) => new native.ShallowLabelMatcher(value),
|
|
7
|
+
accessibilityLabel: (value) => new native.ShallowLabelMatcher(value),
|
|
8
8
|
text: (value) => new native.TextMatcher(value),
|
|
9
9
|
traits: (value) => new native.TraitsMatcher(value),
|
|
10
10
|
type: (value) => new native.TypeMatcher(value),
|
|
@@ -6,7 +6,14 @@ const DetoxMatcherApi = require('../espressoapi/DetoxMatcher');
|
|
|
6
6
|
class LabelMatcher extends NativeMatcher {
|
|
7
7
|
constructor(value) {
|
|
8
8
|
super();
|
|
9
|
-
this._call = invoke.callDirectly(DetoxMatcherApi.
|
|
9
|
+
this._call = invoke.callDirectly(DetoxMatcherApi.matcherForAccessibilityLabel(value));
|
|
10
|
+
}
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
class ShallowLabelMatcher extends NativeMatcher {
|
|
14
|
+
constructor(value) {
|
|
15
|
+
super();
|
|
16
|
+
this._call = invoke.callDirectly(DetoxMatcherApi.matcherForShallowAccessibilityLabel(value));
|
|
10
17
|
}
|
|
11
18
|
}
|
|
12
19
|
|
|
@@ -90,6 +97,7 @@ class SliderPositionMatcher extends NativeMatcher {
|
|
|
90
97
|
|
|
91
98
|
module.exports = {
|
|
92
99
|
LabelMatcher,
|
|
100
|
+
ShallowLabelMatcher,
|
|
93
101
|
IdMatcher,
|
|
94
102
|
TypeMatcher,
|
|
95
103
|
TraitsMatcher,
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
312ca2e6d26a005375c7d31f7a489b60
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
80debe0a3a1ed317173f56f92cbfd1f108f3fb6c
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
ceeb582236c99040fb116be37c6eb97c67ecdf91f8cdd1d5dade614a3180375c
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
08dcd64b4e65c486a7fe0d4a59b23e4b9ffc037b4afad03db9cb820b97867e22693d929b7e896f41c11c8a4e3e0d0dbbc11799a69f438d46aeeb8ebb8b157056
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
643850c6dad298f22d9ce657af17dd5c
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
e483f7ab88c2b2d5882d1c825155856c61ba059f
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
2ee1a851c254668619e44df167d0b1d86bd63edb9414a239f1fcea380c39a077
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
3446a90564f2af11a6b6221f114ccd8786044080e222ed698fef6a92d706faed154fdaa976c0dca162db58976170a60b7bc05d5e931a1b1bbf02ff8292d0c47c
|
|
Binary file
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
e8ad50ff5afce32b3cb728f837917c3a
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
8f1738000005765fd1d4746e5f2d85c766dd591f
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
da1efa26b94b52cdbb831470e5753e0982bbe5ec1c861f8965a7347199e67b8b
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
9940e5dd655923d057b095817edc22c952105b1518ff02f1316cfd50be45999127e8410eb9b22e95d155517f455a484b3a52f9533f6f40e3f1e9efbf49a5eaa9
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
e6f8b937b6573484515f78adcc830096
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
59e4b461ba168a526c1c629fb29ded508472e732
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
b455e110295c40221b1620cfe6ffc905fc9623b36a5f38fabf52316def1f9749
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
766004a843b60ee7b385f26324762d8f18d35064324fb7ab5c24e59816869745401dafbfc3517ff55948527fd0411a2b9382b3f29de8aa6756e61df58a3c416c
|