detox 20.9.1 → 20.11.0
Sign up to get free protection for your applications and to get access to all the features.
- package/.eslintignore +2 -0
- package/.eslintrc.js +1 -40
- package/Detox-android/com/wix/detox/{20.9.1/detox-20.9.1-javadoc.jar → 20.11.0/detox-20.11.0-javadoc.jar} +0 -0
- package/Detox-android/com/wix/detox/20.11.0/detox-20.11.0-javadoc.jar.md5 +1 -0
- package/Detox-android/com/wix/detox/20.11.0/detox-20.11.0-javadoc.jar.sha1 +1 -0
- package/Detox-android/com/wix/detox/20.11.0/detox-20.11.0-javadoc.jar.sha256 +1 -0
- package/Detox-android/com/wix/detox/20.11.0/detox-20.11.0-javadoc.jar.sha512 +1 -0
- package/Detox-android/com/wix/detox/{20.9.1/detox-20.9.1-sources.jar → 20.11.0/detox-20.11.0-sources.jar} +0 -0
- package/Detox-android/com/wix/detox/20.11.0/detox-20.11.0-sources.jar.md5 +1 -0
- package/Detox-android/com/wix/detox/20.11.0/detox-20.11.0-sources.jar.sha1 +1 -0
- package/Detox-android/com/wix/detox/20.11.0/detox-20.11.0-sources.jar.sha256 +1 -0
- package/Detox-android/com/wix/detox/20.11.0/detox-20.11.0-sources.jar.sha512 +1 -0
- package/Detox-android/com/wix/detox/20.11.0/detox-20.11.0.aar +0 -0
- package/Detox-android/com/wix/detox/20.11.0/detox-20.11.0.aar.md5 +1 -0
- package/Detox-android/com/wix/detox/20.11.0/detox-20.11.0.aar.sha1 +1 -0
- package/Detox-android/com/wix/detox/20.11.0/detox-20.11.0.aar.sha256 +1 -0
- package/Detox-android/com/wix/detox/20.11.0/detox-20.11.0.aar.sha512 +1 -0
- package/Detox-android/com/wix/detox/{20.9.1/detox-20.9.1.pom → 20.11.0/detox-20.11.0.pom} +1 -1
- package/Detox-android/com/wix/detox/20.11.0/detox-20.11.0.pom.md5 +1 -0
- package/Detox-android/com/wix/detox/20.11.0/detox-20.11.0.pom.sha1 +1 -0
- package/Detox-android/com/wix/detox/20.11.0/detox-20.11.0.pom.sha256 +1 -0
- package/Detox-android/com/wix/detox/20.11.0/detox-20.11.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/build.gradle +20 -10
- package/android/detox/build.gradle +11 -4
- package/android/detox/src/full/java/com/wix/detox/espresso/DetoxMatcher.java +12 -12
- package/android/detox/src/full/java/com/wix/detox/espresso/common/SliderHelper.kt +2 -2
- package/android/detox/src/full/java/com/wix/detox/espresso/matcher/RegexMatcher.kt +56 -0
- package/android/detox/src/full/java/com/wix/detox/espresso/matcher/ViewMatchers.kt +16 -4
- package/android/detox/src/testFull/java/com/wix/detox/espresso/matcher/RegexMatcherTest.kt +52 -0
- package/android/gradle/wrapper/gradle-wrapper.properties +1 -1
- package/android/rninfo.gradle +25 -0
- package/android/settings.gradle +2 -1
- package/index.d.ts +10 -5
- package/local-cli/startCommand/AppStartCommand.js +4 -1
- package/package.json +14 -10
- package/src/android/espressoapi/DetoxMatcher.js +24 -8
- package/src/android/matchers/native.js +9 -4
- package/src/ios/expectTwo.js +8 -7
- package/src/utils/isRegExp.js +7 -0
- package/Detox-android/com/wix/detox/20.9.1/detox-20.9.1-javadoc.jar.md5 +0 -1
- package/Detox-android/com/wix/detox/20.9.1/detox-20.9.1-javadoc.jar.sha1 +0 -1
- package/Detox-android/com/wix/detox/20.9.1/detox-20.9.1-javadoc.jar.sha256 +0 -1
- package/Detox-android/com/wix/detox/20.9.1/detox-20.9.1-javadoc.jar.sha512 +0 -1
- package/Detox-android/com/wix/detox/20.9.1/detox-20.9.1-sources.jar.md5 +0 -1
- package/Detox-android/com/wix/detox/20.9.1/detox-20.9.1-sources.jar.sha1 +0 -1
- package/Detox-android/com/wix/detox/20.9.1/detox-20.9.1-sources.jar.sha256 +0 -1
- package/Detox-android/com/wix/detox/20.9.1/detox-20.9.1-sources.jar.sha512 +0 -1
- package/Detox-android/com/wix/detox/20.9.1/detox-20.9.1.aar +0 -0
- package/Detox-android/com/wix/detox/20.9.1/detox-20.9.1.aar.md5 +0 -1
- package/Detox-android/com/wix/detox/20.9.1/detox-20.9.1.aar.sha1 +0 -1
- package/Detox-android/com/wix/detox/20.9.1/detox-20.9.1.aar.sha256 +0 -1
- package/Detox-android/com/wix/detox/20.9.1/detox-20.9.1.aar.sha512 +0 -1
- package/Detox-android/com/wix/detox/20.9.1/detox-20.9.1.pom.md5 +0 -1
- package/Detox-android/com/wix/detox/20.9.1/detox-20.9.1.pom.sha1 +0 -1
- package/Detox-android/com/wix/detox/20.9.1/detox-20.9.1.pom.sha256 +0 -1
- package/Detox-android/com/wix/detox/20.9.1/detox-20.9.1.pom.sha512 +0 -1
package/.eslintignore
CHANGED
package/.eslintrc.js
CHANGED
@@ -4,7 +4,7 @@ module.exports = {
|
|
4
4
|
'eslint:recommended',
|
5
5
|
'plugin:import/recommended',
|
6
6
|
'plugin:node/recommended',
|
7
|
-
'plugin:
|
7
|
+
'plugin:ecmascript-compat/recommended'
|
8
8
|
],
|
9
9
|
parser: '@typescript-eslint/parser',
|
10
10
|
plugins: [
|
@@ -73,45 +73,6 @@ module.exports = {
|
|
73
73
|
allowWarningComments: false,
|
74
74
|
}
|
75
75
|
],
|
76
|
-
// TODO: enable some of unicorn rules
|
77
|
-
'unicorn/better-regex': 'off',
|
78
|
-
'unicorn/catch-error-name': 'off',
|
79
|
-
'unicorn/consistent-destructuring': 'off',
|
80
|
-
'unicorn/consistent-function-scoping': 'off',
|
81
|
-
'unicorn/empty-brace-spaces': 'off',
|
82
|
-
'unicorn/error-message': 'off',
|
83
|
-
'unicorn/explicit-length-check': 'off',
|
84
|
-
'unicorn/filename-case': 'off',
|
85
|
-
'unicorn/import-style': 'off',
|
86
|
-
'unicorn/new-for-builtins': 'off',
|
87
|
-
'unicorn/no-abusive-eslint-disable': 'off',
|
88
|
-
'unicorn/no-array-callback-reference': 'off',
|
89
|
-
'unicorn/no-array-for-each': 'off',
|
90
|
-
'unicorn/no-array-reduce': 'off',
|
91
|
-
'unicorn/no-await-expression-member': 'off',
|
92
|
-
'unicorn/no-lonely-if': 'off',
|
93
|
-
'unicorn/no-nested-ternary': 'off',
|
94
|
-
'unicorn/no-new-array': 'off',
|
95
|
-
'unicorn/no-null': 'off',
|
96
|
-
'unicorn/no-object-as-default-parameter': 'off',
|
97
|
-
'unicorn/no-useless-undefined': 'off',
|
98
|
-
'unicorn/number-literal-case': 'off',
|
99
|
-
'unicorn/numeric-separators-style': 'off',
|
100
|
-
'unicorn/prefer-add-event-listener': 'off',
|
101
|
-
'unicorn/prefer-array-some': 'off',
|
102
|
-
'unicorn/prefer-array-flat': 'off',
|
103
|
-
'unicorn/prefer-includes': 'off',
|
104
|
-
'unicorn/prefer-module': 'off',
|
105
|
-
'unicorn/prefer-number-properties': 'off',
|
106
|
-
'unicorn/prefer-object-from-entries': 'off',
|
107
|
-
'unicorn/prefer-optional-catch-binding': 'off',
|
108
|
-
'unicorn/prefer-regexp-test': 'off',
|
109
|
-
'unicorn/prefer-spread': 'off',
|
110
|
-
'unicorn/prefer-string-slice': 'off',
|
111
|
-
'unicorn/prefer-string-starts-ends-with': 'off',
|
112
|
-
'unicorn/prefer-string-trim-start-end': 'off',
|
113
|
-
'unicorn/prefer-ternary': 'off',
|
114
|
-
'unicorn/prevent-abbreviations': 'off',
|
115
76
|
},
|
116
77
|
|
117
78
|
overrides: [
|
Binary file
|
@@ -0,0 +1 @@
|
|
1
|
+
f0cf6ad0def43fbab5ba6fae7b4e5441
|
@@ -0,0 +1 @@
|
|
1
|
+
48b29f67227c7b45844172ffdc0b25c7e5bd4f05
|
@@ -0,0 +1 @@
|
|
1
|
+
0dbfb89e22024b3c3f45e0941a9fd3421d6a4f4041b76f8f54edd4259a9092a8
|
@@ -0,0 +1 @@
|
|
1
|
+
a1a2706b699d0c9217252c287a3d82b679bb206423ebbee820a261cd5925970426596f99a16fdcd8d37107185c3d5ec80628dd48309d0c31c89a00a37f7bf292
|
Binary file
|
@@ -0,0 +1 @@
|
|
1
|
+
3579eb8ea896facf3fd7e2be627cdc03
|
@@ -0,0 +1 @@
|
|
1
|
+
1fb720e2b0f0da39406134aabcdafec756f9cbe5
|
@@ -0,0 +1 @@
|
|
1
|
+
f1c18496d23e09cffc96ef1b3bcbf349b1ae0a020ed5a6707b64bf22e30d9180
|
@@ -0,0 +1 @@
|
|
1
|
+
ebfcaef97fb6aa02bbda14d12a26eaac823620766c7e3b84eee7fa0115edb17463ea59ac689d07ffc97e84d2dbdbbd7db3014fdd976d0b2dd207c6278494f523
|
Binary file
|
@@ -0,0 +1 @@
|
|
1
|
+
518f621bfc037203c5ddd30c3f62c8ad
|
@@ -0,0 +1 @@
|
|
1
|
+
65065fce4ddace8e95d235b60cf5a27f93e1162b
|
@@ -0,0 +1 @@
|
|
1
|
+
cd516e30305ad672e7ed0e8b4f77e992482c9a2979ce92d88a074dc45524cbe9
|
@@ -0,0 +1 @@
|
|
1
|
+
00ff273c46cb32923f574fd00189459e9dff6d4782ac561f30583c9610427e270450783485aece4e9ebeb52c12bd3eec1560521d5a0535965dd278c7b44f3848
|
@@ -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.11.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
|
+
72868177d685cfd9912ca8fe3c08da3a
|
@@ -0,0 +1 @@
|
|
1
|
+
ad0ed20f218ec25f055f5c668c9b6dcd875069bf
|
@@ -0,0 +1 @@
|
|
1
|
+
b1c48d9cf1df54b6cbe27c45a4c8834162b04a783601a3d4b030fd3ac12e723e
|
@@ -0,0 +1 @@
|
|
1
|
+
c68e22610d04ad949b65cffe6305e30bab93ca1a10d53d0cd3ded77dee8f64d7d14f1b250cbdde553a06a4fe5b50738af7ae363b5f7ad836f816f48ca845d189
|
@@ -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.11.0</latest>
|
7
|
+
<release>20.11.0</release>
|
8
8
|
<versions>
|
9
|
-
<version>20.
|
9
|
+
<version>20.11.0</version>
|
10
10
|
</versions>
|
11
|
-
<lastUpdated>
|
11
|
+
<lastUpdated>20230704204300</lastUpdated>
|
12
12
|
</versioning>
|
13
13
|
</metadata>
|
@@ -1 +1 @@
|
|
1
|
-
|
1
|
+
e930da2d4686f5b8bbe2fe5638fab155
|
@@ -1 +1 @@
|
|
1
|
-
|
1
|
+
7ec428486d1d978a16101aedc506e79483ccf63a
|
@@ -1 +1 @@
|
|
1
|
-
|
1
|
+
469a65278a6ed368df597dfb505c150591e4ab587b190dbee2bb12c50b41a6ef
|
@@ -1 +1 @@
|
|
1
|
-
|
1
|
+
dfc9bd1f96626dee848008639fc467b70d4653f57761c30cff16f41550d1f2a79dcd9aefd64c7313b8672c503e1a12dc360b1742faba6e2946878f6b2f8bbaac
|
package/Detox-ios-src.tbz
CHANGED
Binary file
|
package/Detox-ios.tbz
CHANGED
Binary file
|
package/android/build.gradle
CHANGED
@@ -1,11 +1,13 @@
|
|
1
1
|
buildscript {
|
2
|
+
apply from: './rninfo.gradle'
|
3
|
+
|
2
4
|
ext {
|
3
5
|
isOfficialDetoxLib = true
|
4
|
-
kotlinVersion = '1.
|
6
|
+
kotlinVersion = '1.8.22'
|
5
7
|
dokkaVersion = '1.6.0'
|
6
|
-
buildToolsVersion = '
|
7
|
-
compileSdkVersion =
|
8
|
-
targetSdkVersion =
|
8
|
+
buildToolsVersion = '33.0.0'
|
9
|
+
compileSdkVersion = 33
|
10
|
+
targetSdkVersion = 33
|
9
11
|
minSdkVersion = 21
|
10
12
|
|
11
13
|
if (System.properties['os.arch'] == "aarch64") {
|
@@ -19,11 +21,14 @@ buildscript {
|
|
19
21
|
ext.detoxKotlinVersion = ext.kotlinVersion
|
20
22
|
|
21
23
|
repositories {
|
22
|
-
mavenCentral()
|
23
24
|
google()
|
25
|
+
mavenCentral()
|
24
26
|
}
|
25
27
|
dependencies {
|
26
|
-
|
28
|
+
if (!rnInfo.isRN71OrNewer) {
|
29
|
+
classpath "com.facebook.react:react-native-gradle-plugin"
|
30
|
+
}
|
31
|
+
classpath 'com.android.tools.build:gradle:7.3.1'
|
27
32
|
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlinVersion"
|
28
33
|
classpath "org.jetbrains.dokka:dokka-gradle-plugin:$dokkaVersion"
|
29
34
|
|
@@ -34,11 +39,16 @@ buildscript {
|
|
34
39
|
|
35
40
|
allprojects {
|
36
41
|
repositories {
|
37
|
-
mavenLocal()
|
38
|
-
mavenCentral()
|
39
42
|
google()
|
40
|
-
|
41
|
-
|
43
|
+
mavenCentral()
|
44
|
+
mavenLocal()
|
45
|
+
|
46
|
+
// In RN's below 71, the native code comes from within node_modules/ rather
|
47
|
+
// than from maven-central.
|
48
|
+
if (!rnInfo.isRN71OrNewer) {
|
49
|
+
maven {
|
50
|
+
url "$projectDir/../../node_modules/react-native/android"
|
51
|
+
}
|
42
52
|
}
|
43
53
|
}
|
44
54
|
}
|
@@ -1,5 +1,6 @@
|
|
1
1
|
apply plugin: 'com.android.library'
|
2
2
|
apply plugin: 'kotlin-android'
|
3
|
+
apply from: '../rninfo.gradle'
|
3
4
|
|
4
5
|
def _kotlinMinVersion = '1.2.0'
|
5
6
|
def _materialMinVersion = '1.2.1'
|
@@ -12,6 +13,13 @@ def _minSdkVersion = _ext.has('minSdkVersion') ? _ext.minSdkVersion : 21
|
|
12
13
|
def _kotlinVersion = _ext.has('detoxKotlinVersion') ? _ext.detoxKotlinVersion : _kotlinMinVersion
|
13
14
|
def _kotlinStdlib = _ext.has('detoxKotlinStdlib') ? _ext.detoxKotlinStdlib : 'kotlin-stdlib-jdk8'
|
14
15
|
|
16
|
+
// RN native code comes from either maven-central (in which case, need the *exact* version),
|
17
|
+
// or otherwise from node_modules/, where the version is already aligned, by definition.
|
18
|
+
// noinspection GradleDynamicVersion
|
19
|
+
def _rnNativeArtifact = rnInfo.isRN71OrHigher
|
20
|
+
? "com.facebook.react:react-android:${rnInfo.version}"
|
21
|
+
: 'com.facebook.react:react-native:+'
|
22
|
+
|
15
23
|
android {
|
16
24
|
compileSdkVersion _compileSdkVersion
|
17
25
|
buildToolsVersion _buildToolsVersion
|
@@ -78,8 +86,8 @@ android {
|
|
78
86
|
// Fundamental deps.
|
79
87
|
dependencies {
|
80
88
|
implementation "org.jetbrains.kotlin:$_kotlinStdlib:$_kotlinMinVersion"
|
81
|
-
|
82
|
-
compileOnly
|
89
|
+
|
90
|
+
compileOnly "${_rnNativeArtifact}"
|
83
91
|
}
|
84
92
|
|
85
93
|
// androidx.test deps.
|
@@ -131,8 +139,7 @@ dependencies {
|
|
131
139
|
|
132
140
|
// Unit-testing deps.
|
133
141
|
dependencies {
|
134
|
-
|
135
|
-
testImplementation 'com.facebook.react:react-native:+'
|
142
|
+
testImplementation "${_rnNativeArtifact}"
|
136
143
|
testImplementation 'org.json:json:20140107'
|
137
144
|
|
138
145
|
// https://github.com/spekframework/spek/issues/232#issuecomment-610732158
|
@@ -14,10 +14,10 @@ import static androidx.test.espresso.matcher.ViewMatchers.isDisplayed;
|
|
14
14
|
import static androidx.test.espresso.matcher.ViewMatchers.isDisplayingAtLeast;
|
15
15
|
import static androidx.test.espresso.matcher.ViewMatchers.isFocused;
|
16
16
|
import static androidx.test.espresso.matcher.ViewMatchers.isNotChecked;
|
17
|
-
import static androidx.test.espresso.matcher.ViewMatchers.withContentDescription;
|
18
17
|
import static androidx.test.espresso.matcher.ViewMatchers.withEffectiveVisibility;
|
19
|
-
import static
|
20
|
-
import static
|
18
|
+
import static com.wix.detox.espresso.matcher.ViewMatchers.withTagValue;
|
19
|
+
import static com.wix.detox.espresso.matcher.ViewMatchers.withContentDescription;
|
20
|
+
import static com.wix.detox.espresso.matcher.ViewMatchers.withText;
|
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;
|
@@ -40,25 +40,25 @@ public class DetoxMatcher {
|
|
40
40
|
// static class
|
41
41
|
}
|
42
42
|
|
43
|
-
public static Matcher<View> matcherForText(String text) {
|
43
|
+
public static Matcher<View> matcherForText(String text, boolean isRegex) {
|
44
44
|
// return anyOf(withText(text), withContentDescription(text));
|
45
|
-
return allOf(withText(text), withEffectiveVisibility(Visibility.VISIBLE));
|
45
|
+
return allOf(withText(text, isRegex), withEffectiveVisibility(Visibility.VISIBLE));
|
46
46
|
}
|
47
47
|
|
48
|
-
public static Matcher<View> matcherForAccessibilityLabel(String label) {
|
49
|
-
return allOf(withAccessibilityLabel(label), withEffectiveVisibility(Visibility.VISIBLE));
|
48
|
+
public static Matcher<View> matcherForAccessibilityLabel(String label, boolean isRegex) {
|
49
|
+
return allOf(withAccessibilityLabel(label, isRegex), withEffectiveVisibility(Visibility.VISIBLE));
|
50
50
|
}
|
51
51
|
|
52
|
-
public static Matcher<View> matcherForShallowAccessibilityLabel(String label) {
|
53
|
-
return allOf(withShallowAccessibilityLabel(label), withEffectiveVisibility(Visibility.VISIBLE));
|
52
|
+
public static Matcher<View> matcherForShallowAccessibilityLabel(String label, boolean isRegex) {
|
53
|
+
return allOf(withShallowAccessibilityLabel(label, isRegex), withEffectiveVisibility(Visibility.VISIBLE));
|
54
54
|
}
|
55
55
|
|
56
56
|
public static Matcher<View> matcherForContentDescription(String contentDescription) {
|
57
|
-
return allOf(withContentDescription(contentDescription), withEffectiveVisibility(Visibility.VISIBLE));
|
57
|
+
return allOf(withContentDescription(contentDescription, false), withEffectiveVisibility(Visibility.VISIBLE));
|
58
58
|
}
|
59
59
|
|
60
|
-
public static Matcher<View> matcherForTestId(String testId) {
|
61
|
-
return allOf(withTagValue(
|
60
|
+
public static Matcher<View> matcherForTestId(String testId, boolean isRegex) {
|
61
|
+
return allOf(withTagValue(testId, isRegex), withEffectiveVisibility(Visibility.VISIBLE));
|
62
62
|
}
|
63
63
|
|
64
64
|
public static Matcher<View> matcherForToggleable(boolean value) {
|
@@ -4,9 +4,9 @@ import android.view.View
|
|
4
4
|
import androidx.appcompat.widget.AppCompatSeekBar
|
5
5
|
import com.facebook.react.bridge.JavaOnlyMap
|
6
6
|
import com.facebook.react.uimanager.ReactStylesDiffMap
|
7
|
-
import com.facebook.react.views.slider.ReactSlider
|
8
7
|
import com.wix.detox.common.DetoxErrors.DetoxIllegalStateException
|
9
8
|
import com.wix.detox.espresso.action.common.ReflectUtils
|
9
|
+
import com.facebook.react.views.slider.ReactSlider
|
10
10
|
import org.joor.Reflect
|
11
11
|
|
12
12
|
private const val CLASS_REACT_SLIDER_LEGACY = "com.facebook.react.views.slider.ReactSlider"
|
@@ -58,7 +58,7 @@ abstract class SliderHelper(protected val slider: AppCompatSeekBar) {
|
|
58
58
|
}
|
59
59
|
}
|
60
60
|
|
61
|
-
private class LegacySliderHelper(slider:
|
61
|
+
private class LegacySliderHelper(slider: ReactSlider): SliderHelper(slider) {
|
62
62
|
override fun setProgressJS(valueJS: Double) {
|
63
63
|
val reactSliderManager = com.facebook.react.views.slider.ReactSliderManager()
|
64
64
|
reactSliderManager.updateProperties(slider as ReactSlider, buildStyles("value", valueJS))
|
@@ -0,0 +1,56 @@
|
|
1
|
+
package com.wix.detox.espresso.matcher
|
2
|
+
|
3
|
+
import org.hamcrest.Description
|
4
|
+
import org.hamcrest.TypeSafeMatcher
|
5
|
+
|
6
|
+
class RegexMatcher<T>(private val jsRegex: String) : TypeSafeMatcher<T>() {
|
7
|
+
override fun matchesSafely(item: T): Boolean {
|
8
|
+
val stringItem = item.toString()
|
9
|
+
return stringItem.matchesJSRegex(jsRegex)
|
10
|
+
}
|
11
|
+
|
12
|
+
override fun describeTo(description: Description) {
|
13
|
+
description.appendText("should match the pattern: $jsRegex")
|
14
|
+
}
|
15
|
+
}
|
16
|
+
|
17
|
+
// Returns whether the whole string matches the given `jsRegex`.
|
18
|
+
// JS flags has the format of `/<pattern>/<flags>`.
|
19
|
+
// Flags can be either:
|
20
|
+
// - i: With this flag the search is case-insensitive: no difference between A and a (see the example below).
|
21
|
+
// - s: Enables “dotall” mode, that allows a dot . to match newline character \n (covered in the chapter Character classes).
|
22
|
+
// - m: Multiline mode (covered in the chapter Multiline mode of anchors ^ $, flag "m").
|
23
|
+
// Other flags (e.g. g,u,s) are not supported as they do not have equivalents in Kotlin.
|
24
|
+
//
|
25
|
+
// - See: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Regular_Expressions
|
26
|
+
fun String.matchesJSRegex(jsRegex: String): Boolean {
|
27
|
+
val flagsChars = getRegexFlags(jsRegex)
|
28
|
+
val options = getRegexOptions(flagsChars)
|
29
|
+
val pattern = getRegexPattern(jsRegex)
|
30
|
+
return Regex(pattern, options).matches(this)
|
31
|
+
}
|
32
|
+
|
33
|
+
private fun getRegexFlags(jsRegex: String): CharSequence {
|
34
|
+
return jsRegex.substringAfterLast("/")
|
35
|
+
}
|
36
|
+
|
37
|
+
private fun getRegexPattern(jsRegex: String): String {
|
38
|
+
val pattern = jsRegex.substringAfter("/")
|
39
|
+
return pattern.substringBeforeLast("/")
|
40
|
+
}
|
41
|
+
|
42
|
+
private fun getRegexOptions(flagsChars: CharSequence): MutableSet<RegexOption> {
|
43
|
+
val options = mutableSetOf<RegexOption>()
|
44
|
+
|
45
|
+
if (flagsChars.contains('i', ignoreCase = true)) {
|
46
|
+
options.add(RegexOption.IGNORE_CASE)
|
47
|
+
}
|
48
|
+
if (flagsChars.contains('s', ignoreCase = true)) {
|
49
|
+
options.add(RegexOption.DOT_MATCHES_ALL)
|
50
|
+
}
|
51
|
+
if (flagsChars.contains('m', ignoreCase = true)) {
|
52
|
+
options.add(RegexOption.MULTILINE)
|
53
|
+
}
|
54
|
+
|
55
|
+
return options
|
56
|
+
}
|
@@ -11,16 +11,28 @@ import com.wix.detox.espresso.common.SliderHelper
|
|
11
11
|
import org.hamcrest.*
|
12
12
|
import org.hamcrest.Matchers.*
|
13
13
|
import kotlin.math.abs
|
14
|
+
import org.hamcrest.CoreMatchers.`is`
|
14
15
|
|
15
16
|
/*
|
16
17
|
* An extension of [androidx.test.espresso.matcher.ViewMatchers].
|
17
18
|
*/
|
19
|
+
fun <T> getRelevantMatcher(value: T, isRegex: Boolean): Matcher<T> =
|
20
|
+
if (isRegex) RegexMatcher(value.toString()) else `is`(value)
|
18
21
|
|
19
|
-
fun withAccessibilityLabel(text: String) =
|
20
|
-
WithAccessibilityLabelMatcher(
|
22
|
+
fun withAccessibilityLabel(text: String, isRegex: Boolean): Matcher<View> =
|
23
|
+
WithAccessibilityLabelMatcher(getRelevantMatcher(text, isRegex))
|
21
24
|
|
22
|
-
fun withShallowAccessibilityLabel(label: String): Matcher<View>
|
23
|
-
|
25
|
+
fun withShallowAccessibilityLabel(label: String, isRegex: Boolean): Matcher<View> =
|
26
|
+
anyOf(withContentDescription(label, isRegex), withText(label, isRegex))
|
27
|
+
|
28
|
+
fun withText(text: String, isRegex: Boolean): Matcher<View> =
|
29
|
+
ViewMatchers.withText(getRelevantMatcher(text, isRegex))
|
30
|
+
|
31
|
+
fun withContentDescription(label: String, isRegex: Boolean): Matcher<View> =
|
32
|
+
ViewMatchers.withContentDescription(getRelevantMatcher(label, isRegex))
|
33
|
+
|
34
|
+
fun withTagValue(testId: String, isRegex: Boolean): Matcher<View> =
|
35
|
+
ViewMatchers.withTagValue(getRelevantMatcher<Any>(testId, isRegex))
|
24
36
|
|
25
37
|
fun isOfClassName(className: String): Matcher<View> {
|
26
38
|
try {
|
@@ -0,0 +1,52 @@
|
|
1
|
+
package com.wix.detox.espresso.matcher
|
2
|
+
|
3
|
+
import org.junit.Test
|
4
|
+
import kotlin.test.assertFalse
|
5
|
+
import kotlin.test.assertTrue
|
6
|
+
import org.junit.runner.RunWith
|
7
|
+
import org.robolectric.RobolectricTestRunner
|
8
|
+
|
9
|
+
@RunWith(RobolectricTestRunner::class)
|
10
|
+
class RegexMatcherTest {
|
11
|
+
@Test
|
12
|
+
fun `should work with string matching regex`() {
|
13
|
+
val input = "Hello, world!"
|
14
|
+
val regex = "/[A-Z][a-z]+, world!/"
|
15
|
+
assertTrue(input.matchesJSRegex(regex))
|
16
|
+
}
|
17
|
+
|
18
|
+
@Test
|
19
|
+
fun `should work with string not matching regex`() {
|
20
|
+
val input = "Hello, world!"
|
21
|
+
val regex = "/[A-Z]+, world!/"
|
22
|
+
assertFalse(input.matchesJSRegex(regex))
|
23
|
+
}
|
24
|
+
|
25
|
+
@Test
|
26
|
+
fun `should work with the 'i' flag`() {
|
27
|
+
val input = "Hello, world!"
|
28
|
+
val regex = "/[A-Z]+, woRlD!/i"
|
29
|
+
assertTrue(input.matchesJSRegex(regex))
|
30
|
+
}
|
31
|
+
|
32
|
+
@Test
|
33
|
+
fun `should work with the 's' flag`() {
|
34
|
+
val input = "Hello,\nworld!"
|
35
|
+
val regex = "/Hello,\\sworld!/s"
|
36
|
+
assertTrue(input.matchesJSRegex(regex))
|
37
|
+
}
|
38
|
+
|
39
|
+
@Test
|
40
|
+
fun `should work with the 'm' flag`() {
|
41
|
+
val input = "Hello,\nworld!"
|
42
|
+
val regex = "/^Hello,\\s.*!$/m"
|
43
|
+
assertTrue(input.matchesJSRegex(regex))
|
44
|
+
}
|
45
|
+
|
46
|
+
@Test
|
47
|
+
fun `should work with multiple flags, ignore casing`() {
|
48
|
+
val input = "Hello,\nworld!"
|
49
|
+
val regex = "/^heLLo,\\swOrld!/ISM"
|
50
|
+
assertTrue(input.matchesJSRegex(regex))
|
51
|
+
}
|
52
|
+
}
|
@@ -3,5 +3,5 @@ distributionBase=GRADLE_USER_HOME
|
|
3
3
|
distributionPath=wrapper/dists
|
4
4
|
zipStoreBase=GRADLE_USER_HOME
|
5
5
|
zipStorePath=wrapper/dists
|
6
|
-
distributionUrl=https\://services.gradle.org/distributions/gradle-7.
|
6
|
+
distributionUrl=https\://services.gradle.org/distributions/gradle-7.6.1-all.zip
|
7
7
|
|
@@ -0,0 +1,25 @@
|
|
1
|
+
import groovy.json.JsonSlurper
|
2
|
+
|
3
|
+
def rnVersion = getRNVersion()
|
4
|
+
def rnMajorVer = getMajorVersion(rnVersion)
|
5
|
+
println "[$project] RNInfo: detected React Native version: $rnVersion (major=$rnMajorVer)"
|
6
|
+
|
7
|
+
project.ext.rnInfo = [
|
8
|
+
version: rnVersion,
|
9
|
+
majorVersion: rnMajorVer,
|
10
|
+
isRN69OrHigher: rnMajorVer >= 69,
|
11
|
+
isRN70OrHigher: rnMajorVer >= 70,
|
12
|
+
isRN71OrHigher: rnMajorVer >= 71,
|
13
|
+
]
|
14
|
+
|
15
|
+
private static def getRNVersion() {
|
16
|
+
def jsonSlurper = new JsonSlurper()
|
17
|
+
Map<String, Object> packageJSON = jsonSlurper.parse(new File('../node_modules/react-native/package.json'))
|
18
|
+
String rnVersion = packageJSON.get('version')
|
19
|
+
return rnVersion
|
20
|
+
}
|
21
|
+
|
22
|
+
private static def getMajorVersion(semanticVersion) {
|
23
|
+
Integer rnVersionMajor = semanticVersion.split('\\.')[1].toInteger()
|
24
|
+
return rnVersionMajor
|
25
|
+
}
|
package/android/settings.gradle
CHANGED
@@ -1 +1,2 @@
|
|
1
|
-
include ':detox'
|
1
|
+
include ':detox'
|
2
|
+
includeBuild('../node_modules/react-native-gradle-plugin')
|
package/index.d.ts
CHANGED
@@ -971,20 +971,25 @@ declare global {
|
|
971
971
|
* <TouchableOpacity testID={'tap_me'}>
|
972
972
|
* // Then match with by.id:
|
973
973
|
* await element(by.id('tap_me'));
|
974
|
+
* await element(by.id(/^tap_[a-z]+$/));
|
974
975
|
*/
|
975
|
-
id(id: string): NativeMatcher;
|
976
|
+
id(id: string | RegExp): NativeMatcher;
|
976
977
|
|
977
978
|
/**
|
978
979
|
* Find an element by text, useful for text fields, buttons.
|
979
|
-
* @example
|
980
|
+
* @example
|
981
|
+
* await element(by.text('Tap Me'));
|
982
|
+
* await element(by.text(/^Tap .*$/));
|
980
983
|
*/
|
981
|
-
text(text: string): NativeMatcher;
|
984
|
+
text(text: string | RegExp): NativeMatcher;
|
982
985
|
|
983
986
|
/**
|
984
987
|
* Find an element by accessibilityLabel on iOS, or by contentDescription on Android.
|
985
|
-
* @example
|
988
|
+
* @example
|
989
|
+
* await element(by.label('Welcome'));
|
990
|
+
* await element(by.label(/[a-z]+/i));
|
986
991
|
*/
|
987
|
-
label(label: string): NativeMatcher;
|
992
|
+
label(label: string | RegExp): NativeMatcher;
|
988
993
|
|
989
994
|
/**
|
990
995
|
* Find an element by native view type.
|
@@ -36,7 +36,10 @@ class AppStartCommand {
|
|
36
36
|
}
|
37
37
|
};
|
38
38
|
|
39
|
-
this._cpHandle = execa.command(cmd, {
|
39
|
+
this._cpHandle = execa.command(cmd, {
|
40
|
+
stdio: ['ignore', 'inherit', 'inherit'],
|
41
|
+
shell: true
|
42
|
+
});
|
40
43
|
this._cpHandle.on('error', onError);
|
41
44
|
this._cpHandle.on('exit', (code, signal) => {
|
42
45
|
const reason = code == null ? `signal ${signal}` : `code ${code}`;
|
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.11.0",
|
5
5
|
"bin": {
|
6
6
|
"detox": "local-cli/cli.js"
|
7
7
|
},
|
@@ -41,19 +41,20 @@
|
|
41
41
|
"@types/node": "^14.18.33",
|
42
42
|
"@types/node-ipc": "^9.2.0",
|
43
43
|
"@types/ws": "^7.4.0",
|
44
|
-
"@typescript-eslint/eslint-plugin": "^5.
|
45
|
-
"@typescript-eslint/parser": "^5.
|
44
|
+
"@typescript-eslint/eslint-plugin": "^5.59.8",
|
45
|
+
"@typescript-eslint/parser": "^5.59.8",
|
46
46
|
"cross-env": "^7.0.3",
|
47
|
-
"eslint": "^8.
|
48
|
-
"eslint-plugin-
|
49
|
-
"eslint-plugin-
|
47
|
+
"eslint": "^8.41.0",
|
48
|
+
"eslint-plugin-ecmascript-compat": "^3.0.0",
|
49
|
+
"eslint-plugin-import": "^2.27.5",
|
50
|
+
"eslint-plugin-no-only-tests": "^3.1.0",
|
50
51
|
"eslint-plugin-node": "^11.1.0",
|
51
|
-
"eslint-plugin-unicorn": "^
|
52
|
+
"eslint-plugin-unicorn": "^47.0.0",
|
52
53
|
"jest": "^28.1.3",
|
53
54
|
"jest-allure2-reporter": "^1.2.1",
|
54
55
|
"mockdate": "^2.0.1",
|
55
|
-
"prettier": "
|
56
|
-
"react-native": "0.
|
56
|
+
"prettier": "^2.4.1",
|
57
|
+
"react-native": "0.71.10",
|
57
58
|
"react-native-codegen": "^0.0.8",
|
58
59
|
"typescript": "^4.5.2",
|
59
60
|
"wtfnode": "^0.9.1"
|
@@ -202,5 +203,8 @@
|
|
202
203
|
}
|
203
204
|
}
|
204
205
|
},
|
205
|
-
"
|
206
|
+
"browserslist": [
|
207
|
+
"node 14"
|
208
|
+
],
|
209
|
+
"gitHead": "e132a02242f1a4ebcf1775ba4ceb782d5b1a855c"
|
206
210
|
}
|
@@ -14,39 +14,51 @@ function sanitize_matcher(matcher) {
|
|
14
14
|
return originalMatcher.type ? originalMatcher.value : originalMatcher;
|
15
15
|
}
|
16
16
|
class DetoxMatcher {
|
17
|
-
static matcherForText(text) {
|
17
|
+
static matcherForText(text, isRegex) {
|
18
18
|
if (typeof text !== "string") throw new Error("text should be a string, but got " + (text + (" (" + (typeof text + ")"))));
|
19
|
+
if (typeof isRegex !== "boolean") throw new Error("isRegex should be a boolean, but got " + (isRegex + (" (" + (typeof isRegex + ")"))));
|
19
20
|
return {
|
20
21
|
target: {
|
21
22
|
type: "Class",
|
22
23
|
value: "com.wix.detox.espresso.DetoxMatcher"
|
23
24
|
},
|
24
25
|
method: "matcherForText",
|
25
|
-
args: [text
|
26
|
+
args: [text, {
|
27
|
+
type: "boolean",
|
28
|
+
value: isRegex
|
29
|
+
}]
|
26
30
|
};
|
27
31
|
}
|
28
32
|
|
29
|
-
static matcherForAccessibilityLabel(label) {
|
33
|
+
static matcherForAccessibilityLabel(label, isRegex) {
|
30
34
|
if (typeof label !== "string") throw new Error("label should be a string, but got " + (label + (" (" + (typeof label + ")"))));
|
35
|
+
if (typeof isRegex !== "boolean") throw new Error("isRegex should be a boolean, but got " + (isRegex + (" (" + (typeof isRegex + ")"))));
|
31
36
|
return {
|
32
37
|
target: {
|
33
38
|
type: "Class",
|
34
39
|
value: "com.wix.detox.espresso.DetoxMatcher"
|
35
40
|
},
|
36
41
|
method: "matcherForAccessibilityLabel",
|
37
|
-
args: [label
|
42
|
+
args: [label, {
|
43
|
+
type: "boolean",
|
44
|
+
value: isRegex
|
45
|
+
}]
|
38
46
|
};
|
39
47
|
}
|
40
48
|
|
41
|
-
static matcherForShallowAccessibilityLabel(label) {
|
49
|
+
static matcherForShallowAccessibilityLabel(label, isRegex) {
|
42
50
|
if (typeof label !== "string") throw new Error("label should be a string, but got " + (label + (" (" + (typeof label + ")"))));
|
51
|
+
if (typeof isRegex !== "boolean") throw new Error("isRegex should be a boolean, but got " + (isRegex + (" (" + (typeof isRegex + ")"))));
|
43
52
|
return {
|
44
53
|
target: {
|
45
54
|
type: "Class",
|
46
55
|
value: "com.wix.detox.espresso.DetoxMatcher"
|
47
56
|
},
|
48
57
|
method: "matcherForShallowAccessibilityLabel",
|
49
|
-
args: [label
|
58
|
+
args: [label, {
|
59
|
+
type: "boolean",
|
60
|
+
value: isRegex
|
61
|
+
}]
|
50
62
|
};
|
51
63
|
}
|
52
64
|
|
@@ -62,15 +74,19 @@ class DetoxMatcher {
|
|
62
74
|
};
|
63
75
|
}
|
64
76
|
|
65
|
-
static matcherForTestId(testId) {
|
77
|
+
static matcherForTestId(testId, isRegex) {
|
66
78
|
if (typeof testId !== "string") throw new Error("testId should be a string, but got " + (testId + (" (" + (typeof testId + ")"))));
|
79
|
+
if (typeof isRegex !== "boolean") throw new Error("isRegex should be a boolean, but got " + (isRegex + (" (" + (typeof isRegex + ")"))));
|
67
80
|
return {
|
68
81
|
target: {
|
69
82
|
type: "Class",
|
70
83
|
value: "com.wix.detox.espresso.DetoxMatcher"
|
71
84
|
},
|
72
85
|
method: "matcherForTestId",
|
73
|
-
args: [testId
|
86
|
+
args: [testId, {
|
87
|
+
type: "boolean",
|
88
|
+
value: isRegex
|
89
|
+
}]
|
74
90
|
};
|
75
91
|
}
|
76
92
|
|
@@ -1,26 +1,30 @@
|
|
1
1
|
const DetoxRuntimeError = require('../../errors/DetoxRuntimeError');
|
2
2
|
const invoke = require('../../invoke');
|
3
|
+
const { isRegExp } = require('../../utils/isRegExp');
|
3
4
|
const { NativeMatcher } = require('../core/NativeMatcher');
|
4
5
|
const DetoxMatcherApi = require('../espressoapi/DetoxMatcher');
|
5
6
|
|
6
7
|
class LabelMatcher extends NativeMatcher {
|
7
8
|
constructor(value) {
|
8
9
|
super();
|
9
|
-
|
10
|
+
const isRegex = isRegExp(value);
|
11
|
+
this._call = invoke.callDirectly(DetoxMatcherApi.matcherForAccessibilityLabel(isRegex ? value.toString() : value, isRegex));
|
10
12
|
}
|
11
13
|
}
|
12
14
|
|
13
15
|
class ShallowLabelMatcher extends NativeMatcher {
|
14
16
|
constructor(value) {
|
15
17
|
super();
|
16
|
-
|
18
|
+
const isRegex = isRegExp(value);
|
19
|
+
this._call = invoke.callDirectly(DetoxMatcherApi.matcherForShallowAccessibilityLabel(isRegex ? value.toString() : value, isRegex));
|
17
20
|
}
|
18
21
|
}
|
19
22
|
|
20
23
|
class IdMatcher extends NativeMatcher {
|
21
24
|
constructor(value) {
|
22
25
|
super();
|
23
|
-
|
26
|
+
const isRegex = isRegExp(value);
|
27
|
+
this._call = invoke.callDirectly(DetoxMatcherApi.matcherForTestId(isRegex ? value.toString() : value, isRegex));
|
24
28
|
}
|
25
29
|
}
|
26
30
|
|
@@ -53,7 +57,8 @@ class ExistsMatcher extends NativeMatcher {
|
|
53
57
|
class TextMatcher extends NativeMatcher {
|
54
58
|
constructor(value) {
|
55
59
|
super();
|
56
|
-
|
60
|
+
const isRegex = isRegExp(value);
|
61
|
+
this._call = invoke.callDirectly(DetoxMatcherApi.matcherForText(isRegex ? value.toString() : value, isRegex));
|
57
62
|
}
|
58
63
|
}
|
59
64
|
|
package/src/ios/expectTwo.js
CHANGED
@@ -9,6 +9,7 @@ const tempfile = require('tempfile');
|
|
9
9
|
const { assertEnum, assertNormalized } = require('../utils/assertArgument');
|
10
10
|
const { removeMilliseconds } = require('../utils/dateUtils');
|
11
11
|
const { actionDescription, expectDescription } = require('../utils/invocationTraceDescriptions');
|
12
|
+
const { isRegExp } = require('../utils/isRegExp');
|
12
13
|
const log = require('../utils/logger').child({ cat: 'ws-client, ws' });
|
13
14
|
const traceInvocationCall = require('../utils/traceInvocationCall').bind(null, log);
|
14
15
|
|
@@ -231,7 +232,7 @@ class Element {
|
|
231
232
|
|
232
233
|
performAccessibilityAction(actionName) {
|
233
234
|
if (typeof actionName !== 'string') throw new Error('actionName should be a string, but got ' + (actionName + (' (' + (typeof actionName + ')'))));
|
234
|
-
|
235
|
+
|
235
236
|
const traceDescription = actionDescription.performAccessibilityAction(actionName);
|
236
237
|
return this.withAction('accessibilityAction', traceDescription, actionName);
|
237
238
|
}
|
@@ -409,14 +410,14 @@ class Matcher {
|
|
409
410
|
}
|
410
411
|
|
411
412
|
label(label) {
|
412
|
-
if (typeof label !== 'string') throw new Error('label should be a string, but got ' + (label + (' (' + (typeof label + ')'))));
|
413
|
-
this.predicate = { type: 'label', value: label };
|
413
|
+
if (typeof label !== 'string' && !isRegExp(label)) throw new Error('label should be a string or regex, but got ' + (label + (' (' + (typeof label + ')'))));
|
414
|
+
this.predicate = { type: 'label', value: label.toString(), isRegex: isRegExp(label) };
|
414
415
|
return this;
|
415
416
|
}
|
416
417
|
|
417
418
|
id(id) {
|
418
|
-
if (typeof id !== 'string') throw new Error('id should be a string, but got ' + (id + (' (' + (typeof id + ')'))));
|
419
|
-
this.predicate = { type: 'id', value: id };
|
419
|
+
if (typeof id !== 'string' && !isRegExp(id)) throw new Error('id should be a string or regex, but got ' + (id + (' (' + (typeof id + ')'))));
|
420
|
+
this.predicate = { type: 'id', value: id.toString(), isRegex: isRegExp(id) };
|
420
421
|
return this;
|
421
422
|
}
|
422
423
|
|
@@ -439,8 +440,8 @@ class Matcher {
|
|
439
440
|
}
|
440
441
|
|
441
442
|
text(text) {
|
442
|
-
if (typeof text !== 'string') throw new Error(
|
443
|
-
this.predicate = { type: 'text', value: text };
|
443
|
+
if (typeof text !== 'string' && !isRegExp(text)) throw new Error(`text should be a string or regex, but got ` + (text + (' (' + (typeof text + ')'))));
|
444
|
+
this.predicate = { type: 'text', value: text.toString(), isRegex: isRegExp(text) };
|
444
445
|
return this;
|
445
446
|
}
|
446
447
|
|
@@ -1 +0,0 @@
|
|
1
|
-
e135691ef3c16000236576219ead8095
|
@@ -1 +0,0 @@
|
|
1
|
-
2ae996dffa140d6ef33003e472c5396bcf1fed97
|
@@ -1 +0,0 @@
|
|
1
|
-
489299047e3a1a1a10102b834874b119d5373263c8df9d010dd3696af0ca3cb5
|
@@ -1 +0,0 @@
|
|
1
|
-
e5d017cb7ea0f9707dca69c80012edcd1320436c72a1bf922bcddf7526c885ba1a16e3bcbfc32122235ac2f122f2d40890f45b46d69eafb6d4bd612097a634c6
|
@@ -1 +0,0 @@
|
|
1
|
-
75020f38aa6029c7692b7a014159143f
|
@@ -1 +0,0 @@
|
|
1
|
-
d0695ef9339d69af09a14e77c495339e5ff00700
|
@@ -1 +0,0 @@
|
|
1
|
-
de56a9ce5199b6954621b9ab71b065882f50a50f7e723f78540bed54a17225fb
|
@@ -1 +0,0 @@
|
|
1
|
-
80684cd2db41f4c70e9a5795578b7eb7f528b39af836deec99a08e3ad38cf49c1e37bec6b98c8aedf0fdb03a6ca881b136149121639016dffe402f666152ca7b
|
Binary file
|
@@ -1 +0,0 @@
|
|
1
|
-
e89d3204dcda439e4deb0df61603394a
|
@@ -1 +0,0 @@
|
|
1
|
-
eda5c226e954731b3dbd16becbab72f66888d5ce
|
@@ -1 +0,0 @@
|
|
1
|
-
4da9ab41881efc27c7268bff2bfbb7092d9dbdf6de8f43787b4df649f0291bff
|
@@ -1 +0,0 @@
|
|
1
|
-
c63bf901eb0327ca3791b419f99dd67060a9b48a816da5c71e7e660e60fed607347ef8f76710969e9497054cc4f99add8db19f47b7e780ee3e6413df6d75e195
|
@@ -1 +0,0 @@
|
|
1
|
-
c40ce1eb663c728fcb4997417bd2bad2
|
@@ -1 +0,0 @@
|
|
1
|
-
32a60d3d786cd018febcd30ae1a09a30772e1112
|
@@ -1 +0,0 @@
|
|
1
|
-
de63c952930025cf608b8079311242c75647b0daa0f8ed18d4a5bf10f013f9c3
|
@@ -1 +0,0 @@
|
|
1
|
-
5a7090284861016e6589c5ddb404f8075ee1926ebfec73ce993e0f41048163e3b27876fe10c43f9c3f9dc80c842841eeb0d1b842737b87afba29334369e839c7
|