detox 19.11.0 → 19.12.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/{19.11.0/detox-19.11.0-javadoc.jar → 19.12.0/detox-19.12.0-javadoc.jar} +0 -0
- package/Detox-android/com/wix/detox/19.12.0/detox-19.12.0-javadoc.jar.md5 +1 -0
- package/Detox-android/com/wix/detox/19.12.0/detox-19.12.0-javadoc.jar.sha1 +1 -0
- package/Detox-android/com/wix/detox/19.12.0/detox-19.12.0-javadoc.jar.sha256 +1 -0
- package/Detox-android/com/wix/detox/19.12.0/detox-19.12.0-javadoc.jar.sha512 +1 -0
- package/Detox-android/com/wix/detox/{19.11.0/detox-19.11.0-sources.jar → 19.12.0/detox-19.12.0-sources.jar} +0 -0
- package/Detox-android/com/wix/detox/19.12.0/detox-19.12.0-sources.jar.md5 +1 -0
- package/Detox-android/com/wix/detox/19.12.0/detox-19.12.0-sources.jar.sha1 +1 -0
- package/Detox-android/com/wix/detox/19.12.0/detox-19.12.0-sources.jar.sha256 +1 -0
- package/Detox-android/com/wix/detox/19.12.0/detox-19.12.0-sources.jar.sha512 +1 -0
- package/Detox-android/com/wix/detox/19.12.0/detox-19.12.0.aar +0 -0
- package/Detox-android/com/wix/detox/19.12.0/detox-19.12.0.aar.md5 +1 -0
- package/Detox-android/com/wix/detox/19.12.0/detox-19.12.0.aar.sha1 +1 -0
- package/Detox-android/com/wix/detox/19.12.0/detox-19.12.0.aar.sha256 +1 -0
- package/Detox-android/com/wix/detox/19.12.0/detox-19.12.0.aar.sha512 +1 -0
- package/Detox-android/com/wix/detox/{19.11.0/detox-19.11.0.pom → 19.12.0/detox-19.12.0.pom} +1 -7
- package/Detox-android/com/wix/detox/19.12.0/detox-19.12.0.pom.md5 +1 -0
- package/Detox-android/com/wix/detox/19.12.0/detox-19.12.0.pom.sha1 +1 -0
- package/Detox-android/com/wix/detox/19.12.0/detox-19.12.0.pom.sha256 +1 -0
- package/Detox-android/com/wix/detox/19.12.0/detox-19.12.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 +12 -6
- package/android/detox/build.gradle +13 -9
- package/android/detox/publishing.gradle +27 -27
- package/android/detox/src/full/java/com/wix/detox/reactnative/idlingresources/timers/DelegatedIdleInterrogationStrategy.kt +7 -27
- package/android/detox/src/full/java/com/wix/detox/reactnative/idlingresources/timers/IdleInterrogationStrategy.kt +1 -11
- package/android/detox/src/testFull/java/com/wix/detox/espresso/action/DetoxMultiTapSpec.kt +4 -3
- package/android/detox/src/testFull/java/com/wix/detox/reactnative/idlingresources/timers/DelegatedIdleInterrogationStrategySpec.kt +3 -11
- package/package.json +3 -3
- package/Detox-android/com/wix/detox/19.11.0/detox-19.11.0-javadoc.jar.md5 +0 -1
- package/Detox-android/com/wix/detox/19.11.0/detox-19.11.0-javadoc.jar.sha1 +0 -1
- package/Detox-android/com/wix/detox/19.11.0/detox-19.11.0-javadoc.jar.sha256 +0 -1
- package/Detox-android/com/wix/detox/19.11.0/detox-19.11.0-javadoc.jar.sha512 +0 -1
- package/Detox-android/com/wix/detox/19.11.0/detox-19.11.0-sources.jar.md5 +0 -1
- package/Detox-android/com/wix/detox/19.11.0/detox-19.11.0-sources.jar.sha1 +0 -1
- package/Detox-android/com/wix/detox/19.11.0/detox-19.11.0-sources.jar.sha256 +0 -1
- package/Detox-android/com/wix/detox/19.11.0/detox-19.11.0-sources.jar.sha512 +0 -1
- package/Detox-android/com/wix/detox/19.11.0/detox-19.11.0.aar +0 -0
- package/Detox-android/com/wix/detox/19.11.0/detox-19.11.0.aar.md5 +0 -1
- package/Detox-android/com/wix/detox/19.11.0/detox-19.11.0.aar.sha1 +0 -1
- package/Detox-android/com/wix/detox/19.11.0/detox-19.11.0.aar.sha256 +0 -1
- package/Detox-android/com/wix/detox/19.11.0/detox-19.11.0.aar.sha512 +0 -1
- package/Detox-android/com/wix/detox/19.11.0/detox-19.11.0.pom.md5 +0 -1
- package/Detox-android/com/wix/detox/19.11.0/detox-19.11.0.pom.sha1 +0 -1
- package/Detox-android/com/wix/detox/19.11.0/detox-19.11.0.pom.sha256 +0 -1
- package/Detox-android/com/wix/detox/19.11.0/detox-19.11.0.pom.sha512 +0 -1
- package/android/detox/src/full/java/com/wix/detox/reactnative/idlingresources/timers/DefaultIdleInterrogationStrategy.kt +0 -84
- package/android/detox/src/testFull/java/com/wix/detox/reactnative/idlingresources/timers/DefaultIdleInterrogationStrategySpec.kt +0 -115
|
Binary file
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
f84e1c8d0dc7f05b0b97f26da4c271b7
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
77dd4aa38015165ec5ff660cd3b2530fe55ffadb
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
324d59565bfdbb7739dd24ed9430530cfdea8624d9e159d7492f6fa57646b50d
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
97d1c74d88c467e02e286030e8dc58d4a814e5b428c7253208a4ac1dd176a5bba42d35542efc1a5282a0f5327fc56de2a270e3ef2ca5278877f7ceb81d550bdf
|
|
Binary file
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
9ef1a57a44222796853a08468abba095
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
2b51f2d2610d6b74ce75218d9ba54e8e88cfdf77
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
b9bfbc1d103753fb71fd7a588e23bf793dd9d37df408d363927515d773ac25d0
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
c009b73fa1c740ee44b1f656bdc82f70afd4767ec19811ab42d9bab8e785efd97c3a3ea038a8b6f17a2cd0d644e11b94d93ceb388e43d64a439fb5a932fe8051
|
|
Binary file
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
840608881795a8fe3b8071b1778b8b75
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
4bae18e710d72a1a1967e265c3cca3288e924378
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
6ccacc5a233d56565432fe936e32115295fbcea1a0ec4d2b24f14bb03cba93cb
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
eaa34421705dd31450fb17820cf4de2f715228e49369ab63e9dffe364b644dd4a734fb2204812153b727443753e10752188f00a42dfaf44420af25e562a46bc8
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
<modelVersion>4.0.0</modelVersion>
|
|
4
4
|
<groupId>com.wix</groupId>
|
|
5
5
|
<artifactId>detox</artifactId>
|
|
6
|
-
<version>19.
|
|
6
|
+
<version>19.12.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>
|
|
@@ -60,12 +60,6 @@
|
|
|
60
60
|
<version>2.2.0</version>
|
|
61
61
|
<scope>compile</scope>
|
|
62
62
|
</dependency>
|
|
63
|
-
<dependency>
|
|
64
|
-
<groupId>org.jetbrains.kotlin</groupId>
|
|
65
|
-
<artifactId>kotlin-android-extensions-runtime</artifactId>
|
|
66
|
-
<version>1.3.72</version>
|
|
67
|
-
<scope>runtime</scope>
|
|
68
|
-
</dependency>
|
|
69
63
|
<dependency>
|
|
70
64
|
<groupId>org.jetbrains.kotlin</groupId>
|
|
71
65
|
<artifactId>kotlin-stdlib-jdk8</artifactId>
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
85a79b6b58d8600a55f553fd2414124d
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
f8b523f1f83d68b9587c1de76a4c5035545e3fcb
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
70e0ec352d4aa452e4460691b2b07ce289158b5da13154dfb02a1a874f0c98ab
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
918f8b7107915661777fbd660b7b7cfea20d0efab00bdd8a74d612cbfd03aee3da0d37a1f0bebfd637acc2029677d5929c8d7a9af4814fa7ea5030103d128fd5
|
|
@@ -3,11 +3,11 @@
|
|
|
3
3
|
<groupId>com.wix</groupId>
|
|
4
4
|
<artifactId>detox</artifactId>
|
|
5
5
|
<versioning>
|
|
6
|
-
<latest>19.
|
|
7
|
-
<release>19.
|
|
6
|
+
<latest>19.12.0</latest>
|
|
7
|
+
<release>19.12.0</release>
|
|
8
8
|
<versions>
|
|
9
|
-
<version>19.
|
|
9
|
+
<version>19.12.0</version>
|
|
10
10
|
</versions>
|
|
11
|
-
<lastUpdated>
|
|
11
|
+
<lastUpdated>20220907111125</lastUpdated>
|
|
12
12
|
</versioning>
|
|
13
13
|
</metadata>
|
|
@@ -1 +1 @@
|
|
|
1
|
-
|
|
1
|
+
180d61e0f1862c462804dcc2ec4640c3
|
|
@@ -1 +1 @@
|
|
|
1
|
-
|
|
1
|
+
5e78e56fd179fcfb62a1f22e61012086b16ad365
|
|
@@ -1 +1 @@
|
|
|
1
|
-
|
|
1
|
+
a1053920cdb735ac4948b55767543408862bf3e265c5d4ef1f2f335c07e8498b
|
|
@@ -1 +1 @@
|
|
|
1
|
-
|
|
1
|
+
f3ae43dd0a94e71b31a69d6bdaa1f6bded123da37bf6ce2e06085d157cd3d2647b756557ee14e7c0982f3a108fe8ea7aeddbff76db67886f900254599780acb1
|
package/Detox-ios-src.tbz
CHANGED
|
Binary file
|
package/Detox-ios.tbz
CHANGED
|
Binary file
|
package/android/build.gradle
CHANGED
|
@@ -1,12 +1,20 @@
|
|
|
1
1
|
buildscript {
|
|
2
2
|
ext {
|
|
3
3
|
isOfficialDetoxLib = true
|
|
4
|
-
kotlinVersion = '1.
|
|
4
|
+
kotlinVersion = '1.6.10' // Aligned with RN .69's version bump
|
|
5
5
|
dokkaVersion = '1.6.0'
|
|
6
6
|
buildToolsVersion = '31.0.0'
|
|
7
7
|
compileSdkVersion = 31
|
|
8
8
|
targetSdkVersion = 31
|
|
9
9
|
minSdkVersion = 21
|
|
10
|
+
|
|
11
|
+
if (System.properties['os.arch'] == "aarch64") {
|
|
12
|
+
// For M1 Users we need to use the NDK 24 which added support for aarch64
|
|
13
|
+
ndkVersion = "24.0.8215888"
|
|
14
|
+
} else {
|
|
15
|
+
// Otherwise we default to the side-by-side NDK version from AGP.
|
|
16
|
+
ndkVersion = "21.4.7075529"
|
|
17
|
+
}
|
|
10
18
|
}
|
|
11
19
|
ext.detoxKotlinVersion = ext.kotlinVersion
|
|
12
20
|
|
|
@@ -15,14 +23,12 @@ buildscript {
|
|
|
15
23
|
google()
|
|
16
24
|
}
|
|
17
25
|
dependencies {
|
|
18
|
-
classpath 'com.android.tools.build:gradle:7.
|
|
26
|
+
classpath 'com.android.tools.build:gradle:7.1.1'
|
|
19
27
|
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlinVersion"
|
|
20
28
|
classpath "org.jetbrains.dokka:dokka-gradle-plugin:$dokkaVersion"
|
|
21
29
|
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
classpath 'de.mannodermaus.gradle.plugins:android-junit5:1.7.1.1'
|
|
25
|
-
}
|
|
30
|
+
// Needed by Spek (https://spekframework.org/setup-android)
|
|
31
|
+
classpath 'de.mannodermaus.gradle.plugins:android-junit5:1.7.1.1'
|
|
26
32
|
}
|
|
27
33
|
}
|
|
28
34
|
|
|
@@ -1,13 +1,15 @@
|
|
|
1
1
|
apply plugin: 'com.android.library'
|
|
2
2
|
apply plugin: 'kotlin-android'
|
|
3
|
-
|
|
3
|
+
|
|
4
|
+
def _kotlinMinVersion = '1.2.0'
|
|
5
|
+
def _materialMinVersion = '1.2.1'
|
|
4
6
|
|
|
5
7
|
def _ext = rootProject.ext
|
|
6
8
|
def _compileSdkVersion = _ext.has('compileSdkVersion') ? _ext.compileSdkVersion : 31
|
|
7
9
|
def _targetSdkVersion = _ext.has('targetSdkVersion') ? _ext.targetSdkVersion : 31
|
|
8
|
-
def _buildToolsVersion = _ext.has('buildToolsVersion') ? _ext.buildToolsVersion :
|
|
10
|
+
def _buildToolsVersion = _ext.has('buildToolsVersion') ? _ext.buildToolsVersion : '31.0.0'
|
|
9
11
|
def _minSdkVersion = _ext.has('minSdkVersion') ? _ext.minSdkVersion : 21
|
|
10
|
-
def _kotlinVersion = _ext.has('detoxKotlinVersion') ? _ext.detoxKotlinVersion :
|
|
12
|
+
def _kotlinVersion = _ext.has('detoxKotlinVersion') ? _ext.detoxKotlinVersion : _kotlinMinVersion
|
|
11
13
|
def _kotlinStdlib = _ext.has('detoxKotlinStdlib') ? _ext.detoxKotlinStdlib : 'kotlin-stdlib-jdk8'
|
|
12
14
|
|
|
13
15
|
android {
|
|
@@ -75,7 +77,8 @@ android {
|
|
|
75
77
|
|
|
76
78
|
// Fundamental deps.
|
|
77
79
|
dependencies {
|
|
78
|
-
implementation "org.jetbrains.kotlin:$_kotlinStdlib:$
|
|
80
|
+
implementation "org.jetbrains.kotlin:$_kotlinStdlib:$_kotlinMinVersion"
|
|
81
|
+
//noinspection GradleDynamicVersion
|
|
79
82
|
compileOnly 'com.facebook.react:react-native:+'
|
|
80
83
|
}
|
|
81
84
|
|
|
@@ -108,7 +111,7 @@ dependencies {
|
|
|
108
111
|
|
|
109
112
|
// Third-party/extension deps.
|
|
110
113
|
dependencies {
|
|
111
|
-
implementation(
|
|
114
|
+
implementation("com.google.android.material:material:$_materialMinVersion") {
|
|
112
115
|
because 'Material components are mentioned explicitly (e.g. Slider in get-attributes handler)'
|
|
113
116
|
}
|
|
114
117
|
implementation('org.apache.commons:commons-lang3:3.7') {
|
|
@@ -121,11 +124,11 @@ dependencies {
|
|
|
121
124
|
|
|
122
125
|
// Unit-testing deps.
|
|
123
126
|
dependencies {
|
|
127
|
+
//noinspection GradleDynamicVersion
|
|
124
128
|
testImplementation 'com.facebook.react:react-native:+'
|
|
125
129
|
testImplementation 'org.json:json:20140107'
|
|
126
130
|
|
|
127
131
|
// https://github.com/spekframework/spek/issues/232#issuecomment-610732158
|
|
128
|
-
// testImplementation 'junit:junit:4.13.2'
|
|
129
132
|
testRuntimeOnly 'org.junit.vintage:junit-vintage-engine:5.6.0'
|
|
130
133
|
|
|
131
134
|
testImplementation 'org.assertj:assertj-core:3.16.1'
|
|
@@ -136,9 +139,9 @@ dependencies {
|
|
|
136
139
|
}
|
|
137
140
|
|
|
138
141
|
// Spek (https://spekframework.org/setup-android)
|
|
139
|
-
if (
|
|
140
|
-
|
|
141
|
-
|
|
142
|
+
if (rootProject.hasProperty('isOfficialDetoxLib') ||
|
|
143
|
+
rootProject.hasProperty('isOfficialDetoxApp')) {
|
|
144
|
+
|
|
142
145
|
apply plugin: 'de.mannodermaus.android-junit5'
|
|
143
146
|
|
|
144
147
|
android {
|
|
@@ -164,3 +167,4 @@ if (!rootProject.hasProperty('suppressUnitTests') &&
|
|
|
164
167
|
if (rootProject.hasProperty('isOfficialDetoxLib')) {
|
|
165
168
|
apply from: './publishing.gradle'
|
|
166
169
|
}
|
|
170
|
+
|
|
@@ -18,6 +18,7 @@ def DEVELOPERS = [
|
|
|
18
18
|
String _versionName = System.getProperty('version')
|
|
19
19
|
String _flavour = System.getProperty('buildFlavour', PUB_FLAVOUR_FULL_DETOX)
|
|
20
20
|
Boolean _forceLocal = System.getProperty('forceLocal', 'false').toBoolean()
|
|
21
|
+
Boolean _forceSign = System.getProperty('forceSign', 'false').toBoolean()
|
|
21
22
|
|
|
22
23
|
String _mavenRepoUrl
|
|
23
24
|
Map _mavenCredentials
|
|
@@ -28,7 +29,7 @@ def _selectedVariant
|
|
|
28
29
|
def initLocalPublishing = {
|
|
29
30
|
_mavenRepoUrl = TARGET_LOCAL_DIR
|
|
30
31
|
_mavenCredentials = null
|
|
31
|
-
_shouldSignArtifacts =
|
|
32
|
+
_shouldSignArtifacts = _forceSign
|
|
32
33
|
}
|
|
33
34
|
|
|
34
35
|
def initMavenPublishing = {
|
|
@@ -71,10 +72,8 @@ def shouldPublishVariant = {
|
|
|
71
72
|
}
|
|
72
73
|
|
|
73
74
|
def declareArchive = { target ->
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
archives target
|
|
77
|
-
}
|
|
75
|
+
project.artifacts {
|
|
76
|
+
archives target
|
|
78
77
|
}
|
|
79
78
|
}
|
|
80
79
|
|
|
@@ -103,12 +102,12 @@ tasks.named("dokkaJavadoc") {
|
|
|
103
102
|
}
|
|
104
103
|
}
|
|
105
104
|
}
|
|
106
|
-
// Side note / TODO:
|
|
107
|
-
// Dokka outputs R and BuildConfig; currently, there's nothing to do about it, as issues such as
|
|
108
|
-
// this on - https://github.com/Kotlin/dokka/issues/419 are still open :-/
|
|
109
|
-
// We might want to revisit this in the future -- see if they've decided to export a custom classes
|
|
110
|
-
// suppression config var or something.
|
|
111
105
|
|
|
106
|
+
// Side note / TODO (revisit because dokka's 419 issue has been resolved, since):
|
|
107
|
+
// Dokka outputs R and BuildConfig; currently, there's nothing to do about it, as issues such as
|
|
108
|
+
// this on - https://github.com/Kotlin/dokka/issues/419 are still open :-/
|
|
109
|
+
// We might want to revisit this in the future -- see if they've decided to export a custom classes
|
|
110
|
+
// suppression config var or something.
|
|
112
111
|
task dokkaDocJar(type: Jar, dependsOn: dokkaJavadoc) {
|
|
113
112
|
from "$buildDir/dokkaDoc"
|
|
114
113
|
classifier = 'javadoc'
|
|
@@ -143,7 +142,7 @@ project.afterEvaluate {
|
|
|
143
142
|
android {
|
|
144
143
|
libraryVariants.all { variant ->
|
|
145
144
|
String variantName = variant.name.capitalize()
|
|
146
|
-
if (task.name == "publishMaven${variantName}AarPublicationToMavenRepository") {
|
|
145
|
+
if (task.name == "publishMaven${variantName}AarPublicationToMavenRepository".toString()) {
|
|
147
146
|
task.dependsOn "assemble${variantName}"
|
|
148
147
|
task.dependsOn project.tasks.signArchives
|
|
149
148
|
task.doFirst {
|
|
@@ -245,22 +244,23 @@ publishing {
|
|
|
245
244
|
}
|
|
246
245
|
}
|
|
247
246
|
|
|
248
|
-
// Register all artifacts we've previously registered as archives (i.e. .jar.asc's, .aar.asc's) as
|
|
249
|
-
// Note: this relies on preregistering the equivalent generator-tasks as archive artifacts
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
247
|
+
// Register all artifacts we've previously registered as signed archives (i.e. .jar.asc's, .aar.asc's) as publish-artifacts.
|
|
248
|
+
// Note: this relies on preregistering the equivalent generator-tasks as archive artifacts inside a project.artifacts { ... } clause.
|
|
249
|
+
if (_shouldSignArtifacts) {
|
|
250
|
+
project.tasks.signArchives.signatureFiles.each {
|
|
251
|
+
artifact(it) {
|
|
252
|
+
def matcherSrcDocs = (it.file =~ /-(sources|javadoc)\.jar\.asc$/)
|
|
253
|
+
def matcherAAR = (it.file =~ /\.aar\.asc$/)
|
|
254
|
+
if (matcherSrcDocs.find()) {
|
|
255
|
+
classifier = matcherSrcDocs.group(1)
|
|
256
|
+
extension = 'jar.asc'
|
|
257
|
+
} else if (matcherAAR.find()) {
|
|
258
|
+
classifier = null
|
|
259
|
+
extension = 'aar.asc'
|
|
260
|
+
} else {
|
|
261
|
+
classifier = null
|
|
262
|
+
extension = null
|
|
263
|
+
}
|
|
264
264
|
}
|
|
265
265
|
}
|
|
266
266
|
}
|
|
@@ -1,43 +1,23 @@
|
|
|
1
|
+
|
|
1
2
|
package com.wix.detox.reactnative.idlingresources.timers
|
|
2
3
|
|
|
3
|
-
import com.facebook.react.bridge.NativeModule
|
|
4
4
|
import com.facebook.react.bridge.ReactContext
|
|
5
|
-
import com.
|
|
6
|
-
import com.wix.detox.reactnative.helpers.RNHelpers
|
|
7
|
-
import org.joor.Reflect
|
|
5
|
+
import com.facebook.react.modules.core.TimingModule
|
|
8
6
|
|
|
9
7
|
private const val BUSY_WINDOW_THRESHOLD = 1500L
|
|
10
8
|
|
|
11
|
-
private class RN62TimingModuleReflected(private val timingModule: NativeModule) {
|
|
12
|
-
fun hasActiveTimers(): Boolean = Reflect.on(timingModule).call("hasActiveTimersInRange", BUSY_WINDOW_THRESHOLD).get()
|
|
13
|
-
}
|
|
14
|
-
|
|
15
9
|
/**
|
|
16
10
|
* Delegates the interrogation to the native module itself, added
|
|
17
11
|
* [here](https://github.com/facebook/react-native/pull/27539) in the context
|
|
18
12
|
* of RN v0.62 (followed by a previous refactor and rename of the class).
|
|
19
13
|
*/
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
should) remove any usage of reflection here.
|
|
23
|
-
That includes the unit test's stub being used for that reason in particular.
|
|
24
|
-
""")
|
|
25
|
-
class DelegatedIdleInterrogationStrategy(timingModule: NativeModule): IdleInterrogationStrategy {
|
|
26
|
-
private val timingModuleReflected = RN62TimingModuleReflected(timingModule)
|
|
27
|
-
|
|
28
|
-
override fun isIdleNow(): Boolean = !timingModuleReflected.hasActiveTimers()
|
|
14
|
+
class DelegatedIdleInterrogationStrategy(private val timingModule: TimingModule): IdleInterrogationStrategy {
|
|
15
|
+
override fun isIdleNow(): Boolean = !timingModule.hasActiveTimersInRange(BUSY_WINDOW_THRESHOLD)
|
|
29
16
|
|
|
30
17
|
companion object {
|
|
31
|
-
fun
|
|
32
|
-
val
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
return try {
|
|
36
|
-
module.javaClass.getDeclaredMethod("hasActiveTimersInRange", Long::class.java)
|
|
37
|
-
DelegatedIdleInterrogationStrategy(module)
|
|
38
|
-
} catch (ex: Exception) {
|
|
39
|
-
null
|
|
40
|
-
}
|
|
18
|
+
fun create(reactContext: ReactContext): DelegatedIdleInterrogationStrategy {
|
|
19
|
+
val timingModule = reactContext.getNativeModule(TimingModule::class.java)!!
|
|
20
|
+
return DelegatedIdleInterrogationStrategy(timingModule)
|
|
41
21
|
}
|
|
42
22
|
}
|
|
43
23
|
}
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
package com.wix.detox.reactnative.idlingresources.timers
|
|
2
2
|
|
|
3
|
-
import android.util.Log
|
|
4
3
|
import com.facebook.react.bridge.ReactContext
|
|
5
4
|
import com.wix.detox.common.UIThread
|
|
6
5
|
import java.util.concurrent.Callable
|
|
@@ -13,14 +12,5 @@ fun getInterrogationStrategy(reactContext: ReactContext): IdleInterrogationStrat
|
|
|
13
12
|
// Getting a native-module (inside) also initializes it if needed. That has to run on a
|
|
14
13
|
// looper thread, and the easiest to make sure that happens is to use the main thread.
|
|
15
14
|
UIThread.runSync(Callable {
|
|
16
|
-
DelegatedIdleInterrogationStrategy.
|
|
17
|
-
return@Callable it
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
DefaultIdleInterrogationStrategy.createIfSupported(reactContext)?.let {
|
|
21
|
-
return@Callable it
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
Log.e(TimersIdlingResource.LOG_TAG, "Failed to determine proper implementation-strategy for timers idling resource")
|
|
25
|
-
null
|
|
15
|
+
return@Callable DelegatedIdleInterrogationStrategy.create(reactContext)
|
|
26
16
|
})
|
|
@@ -11,6 +11,7 @@ import org.assertj.core.api.Assertions.assertThat
|
|
|
11
11
|
import org.mockito.kotlin.*
|
|
12
12
|
import org.spekframework.spek2.Spek
|
|
13
13
|
import org.spekframework.spek2.style.specification.describe
|
|
14
|
+
import java.lang.NullPointerException
|
|
14
15
|
import kotlin.test.assertFailsWith
|
|
15
16
|
|
|
16
17
|
object DetoxMultiTapSpec: Spek({
|
|
@@ -136,17 +137,17 @@ object DetoxMultiTapSpec: Spek({
|
|
|
136
137
|
}
|
|
137
138
|
|
|
138
139
|
it("should throw if no UI-controller provided") {
|
|
139
|
-
assertFailsWith(
|
|
140
|
+
assertFailsWith(NullPointerException::class) {
|
|
140
141
|
uut(1).sendTap(null, coordinates, precision, -1, -1)
|
|
141
142
|
}
|
|
142
143
|
}
|
|
143
144
|
|
|
144
145
|
it("should throw if no coordinates / precision are provided") {
|
|
145
|
-
assertFailsWith(
|
|
146
|
+
assertFailsWith(NullPointerException::class) {
|
|
146
147
|
uut(1).sendTap(uiController, null, precision, -1, -1)
|
|
147
148
|
}
|
|
148
149
|
|
|
149
|
-
assertFailsWith(
|
|
150
|
+
assertFailsWith(NullPointerException::class) {
|
|
150
151
|
uut(1).sendTap(uiController, coordinates, null, -1, -1)
|
|
151
152
|
}
|
|
152
153
|
}
|
|
@@ -5,22 +5,14 @@ import org.assertj.core.api.Assertions.assertThat
|
|
|
5
5
|
import org.mockito.kotlin.*
|
|
6
6
|
import org.spekframework.spek2.Spek
|
|
7
7
|
import org.spekframework.spek2.style.specification.describe
|
|
8
|
+
import com.facebook.react.modules.core.TimingModule
|
|
8
9
|
|
|
9
10
|
private const val BUSY_INTERVAL_MS = 1500L
|
|
10
11
|
|
|
11
|
-
abstract class TimingModuleStub: NativeModule {
|
|
12
|
-
abstract fun hasActiveTimersInRange(rangeMs: Long): Boolean
|
|
13
|
-
|
|
14
|
-
override fun onCatalystInstanceDestroy() {}
|
|
15
|
-
override fun getName(): String = "TimersNativeModuleStub"
|
|
16
|
-
override fun canOverrideExistingModule() = false
|
|
17
|
-
override fun initialize() {}
|
|
18
|
-
}
|
|
19
|
-
|
|
20
12
|
object DelegatedIdleInterrogationStrategySpec : Spek({
|
|
21
|
-
describe("
|
|
13
|
+
describe("Timers idle-interrogation strategy") {
|
|
22
14
|
|
|
23
|
-
lateinit var timingModule:
|
|
15
|
+
lateinit var timingModule: TimingModule
|
|
24
16
|
|
|
25
17
|
beforeEachTest {
|
|
26
18
|
timingModule = mock()
|
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": "19.
|
|
4
|
+
"version": "19.12.0",
|
|
5
5
|
"bin": {
|
|
6
6
|
"detox": "local-cli/cli.js"
|
|
7
7
|
},
|
|
@@ -47,7 +47,7 @@
|
|
|
47
47
|
"mocha": ">=6.0.0",
|
|
48
48
|
"mockdate": "^2.0.1",
|
|
49
49
|
"prettier": "1.7.0",
|
|
50
|
-
"react-native": "0.
|
|
50
|
+
"react-native": "0.69.5",
|
|
51
51
|
"react-native-codegen": "^0.0.8",
|
|
52
52
|
"typescript": "^4.5.2",
|
|
53
53
|
"wtfnode": "^0.9.1"
|
|
@@ -177,5 +177,5 @@
|
|
|
177
177
|
}
|
|
178
178
|
}
|
|
179
179
|
},
|
|
180
|
-
"gitHead": "
|
|
180
|
+
"gitHead": "c283efc9a8db72304b73ca054ccaa8acb6b3284c"
|
|
181
181
|
}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
9aba5676c7298fb259def31abb2391c2
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
8489941696f685e4d9ee0f2695e524a9ee882ff7
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
5c074864be82defddfe6f03d23f1023718773a6caf867fd6de97306167b96c10
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
fc404aa3532e1bf13a1e12871b9a4d6c27575cacdfae5b76179308f321091b67d60f5a81e74bd0b3d6304a7930c3a9f79d15015fda37d4cdc5cb849274eb4b6b
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
c607efb999d878b919150d3c868094fe
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
18641f7574235c6ec8c81ea52b75442ce919f213
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
0e23270810340a40547ede0002fb741353646db1878d5825f67a2212a13d3d41
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
440caa1e9ede22144e4f55d2c2c034c13e4b336f9f387f0fa0811bd651612c0bef7981c1b1ae826ab78519185c930a9287a6c6f3c76a554184282fdf8684a344
|
|
Binary file
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
88fff568e621751c02f293579cce453a
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
9398e3ea8573a634ddc61abf4f6b21d9e17ba728
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
ae00e739f49017b43024ff3a508e03dafa7f002b406a746f43f742fa6c21cd15
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
0239c96c8027c9274b6823bfadd5ddea7ca0803db694f53ee30d0d39b8ce5c4dd8d72f4e7d0af089db5d722fecf629e81b62759b5dc4cc434be86910b9b37f5d
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
2300f079161364c78e01d8c27334ac7f
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
1031ee5586ac864c9b0cbcaa5876dfbc07325f1f
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
25d21ff3daef4e4da80808464fc808efbd4d0fa75f5e88ce9376fb1d85a922d8
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
c1fae4e858403138b44db05d47128f74c1ac8b14a9f55dcae90ef90800040507bb8bdd97af6c64d26811ddcdf14be1a341531e4c8a4fab0323f500167b4d3499
|
|
@@ -1,84 +0,0 @@
|
|
|
1
|
-
@file:RNDropSupportTodo(62, "Remove all of this; Use DelegatedIdleInterrogationStrategy, instead.")
|
|
2
|
-
|
|
3
|
-
package com.wix.detox.reactnative.idlingresources.timers
|
|
4
|
-
|
|
5
|
-
import com.facebook.react.bridge.ReactContext
|
|
6
|
-
import com.wix.detox.common.RNDropSupportTodo
|
|
7
|
-
import com.wix.detox.reactnative.helpers.RNHelpers
|
|
8
|
-
import org.joor.Reflect
|
|
9
|
-
import java.util.*
|
|
10
|
-
|
|
11
|
-
private const val BUSY_WINDOW_THRESHOLD = 1500
|
|
12
|
-
|
|
13
|
-
private class TimerReflected(timer: Any) {
|
|
14
|
-
private var reflected = Reflect.on(timer)
|
|
15
|
-
|
|
16
|
-
val isRepeating: Boolean
|
|
17
|
-
get() = reflected.field("mRepeat").get()
|
|
18
|
-
val interval: Int
|
|
19
|
-
get() = reflected.field("mInterval").get()
|
|
20
|
-
val targetTime: Long
|
|
21
|
-
get() = reflected.field("mTargetTime").get()
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
private class TimingModuleReflected(private val timingModule: Any) {
|
|
25
|
-
val timersQueue: PriorityQueue<Any>
|
|
26
|
-
get() = Reflect.on(timingModule).field("mTimers").get()
|
|
27
|
-
val timersLock: Any
|
|
28
|
-
get() = Reflect.on(timingModule).field("mTimerGuard").get()
|
|
29
|
-
|
|
30
|
-
operator fun component1() = timersQueue
|
|
31
|
-
operator fun component2() = timersLock
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
class DefaultIdleInterrogationStrategy
|
|
35
|
-
internal constructor(private val timersModule: Any)
|
|
36
|
-
: IdleInterrogationStrategy {
|
|
37
|
-
|
|
38
|
-
override fun isIdleNow(): Boolean {
|
|
39
|
-
val (timersQueue, timersLock) = TimingModuleReflected(timersModule)
|
|
40
|
-
synchronized(timersLock) {
|
|
41
|
-
val nextTimer = timersQueue.peek()
|
|
42
|
-
nextTimer?.let {
|
|
43
|
-
return !isTimerInBusyWindow(it) && !hasBusyTimers(timersQueue)
|
|
44
|
-
}
|
|
45
|
-
return true
|
|
46
|
-
}
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
private fun isTimerInBusyWindow(timer: Any): Boolean {
|
|
50
|
-
val timerReflected = TimerReflected(timer)
|
|
51
|
-
return when {
|
|
52
|
-
timerReflected.isRepeating -> false
|
|
53
|
-
timerReflected.interval > BUSY_WINDOW_THRESHOLD -> false
|
|
54
|
-
else -> true
|
|
55
|
-
}
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
private fun hasBusyTimers(timersQueue: PriorityQueue<Any>): Boolean {
|
|
59
|
-
timersQueue.forEach {
|
|
60
|
-
if (isTimerInBusyWindow(it)) {
|
|
61
|
-
return true
|
|
62
|
-
}
|
|
63
|
-
}
|
|
64
|
-
return false
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
companion object {
|
|
68
|
-
fun createIfSupported(reactContext: ReactContext): DefaultIdleInterrogationStrategy? {
|
|
69
|
-
// RN = 0.62.0:
|
|
70
|
-
// Should have been handled by DelegatedIdleInterrogationStrategy.createIfSupported() but seems the new TimingModule class
|
|
71
|
-
// was released without the awaited-for "hasActiveTimersInRange()" method.
|
|
72
|
-
try {
|
|
73
|
-
val timingModule = RNHelpers.getNativeModule(reactContext, "com.facebook.react.modules.core.TimingModule")
|
|
74
|
-
val timersManager = Reflect.on(timingModule).get<Any>("mJavaTimerManager")
|
|
75
|
-
return DefaultIdleInterrogationStrategy(timersManager)
|
|
76
|
-
} catch (ex: Exception) {
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
// RN < 0.62
|
|
80
|
-
val timingModule = RNHelpers.getNativeModule(reactContext, "com.facebook.react.modules.core.Timing") ?: return null
|
|
81
|
-
return DefaultIdleInterrogationStrategy(timingModule)
|
|
82
|
-
}
|
|
83
|
-
}
|
|
84
|
-
}
|
|
@@ -1,115 +0,0 @@
|
|
|
1
|
-
package com.wix.detox.reactnative.idlingresources.timers
|
|
2
|
-
|
|
3
|
-
import com.facebook.react.bridge.NativeModule
|
|
4
|
-
import com.wix.detox.UTHelpers
|
|
5
|
-
import org.assertj.core.api.Assertions
|
|
6
|
-
import org.spekframework.spek2.Spek
|
|
7
|
-
import org.spekframework.spek2.style.specification.describe
|
|
8
|
-
import java.util.*
|
|
9
|
-
import java.util.concurrent.Executors
|
|
10
|
-
|
|
11
|
-
private const val BUSY_INTERVAL_MS = 1500
|
|
12
|
-
private const val MEANINGFUL_TIMER_INTERVAL = BUSY_INTERVAL_MS
|
|
13
|
-
|
|
14
|
-
data class TimerStub(
|
|
15
|
-
private var mCallbackID: Int,
|
|
16
|
-
private var mTargetTime: Long,
|
|
17
|
-
private var mInterval: Int,
|
|
18
|
-
private var mRepeat: Boolean)
|
|
19
|
-
|
|
20
|
-
class TimersNativeModuleStub : NativeModule {
|
|
21
|
-
val mTimers: PriorityQueue<Any> = PriorityQueue(2) { _, _ -> 0}
|
|
22
|
-
val mTimerGuard = "Lock-Mock"
|
|
23
|
-
|
|
24
|
-
override fun onCatalystInstanceDestroy() {}
|
|
25
|
-
override fun invalidate() {}
|
|
26
|
-
|
|
27
|
-
override fun getName(): String = "TimersNativeModuleStub"
|
|
28
|
-
override fun canOverrideExistingModule() = false
|
|
29
|
-
override fun initialize() {}
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
private fun now() = System.nanoTime() / 1000000L
|
|
33
|
-
private fun aTimer(targetTime: Long, interval: Int, isRepeating: Boolean): TimerStub {
|
|
34
|
-
return TimerStub(-1, targetTime, interval, isRepeating)
|
|
35
|
-
}
|
|
36
|
-
private fun aTimer(interval: Int, isRepeating: Boolean) = aTimer(now() + interval + 10, interval, isRepeating)
|
|
37
|
-
private fun aOneShotTimer(interval: Int) = aTimer(interval, false)
|
|
38
|
-
private fun aRepeatingTimer(interval: Int) = aTimer(interval, true)
|
|
39
|
-
private fun anOverdueTimer() = aTimer(now() - 100, 123, false)
|
|
40
|
-
|
|
41
|
-
object DefaultIdleInterrogationStrategySpec: Spek({
|
|
42
|
-
describe("Default timers idle-interrogation strategy") {
|
|
43
|
-
|
|
44
|
-
lateinit var timersNativeModule: TimersNativeModuleStub
|
|
45
|
-
|
|
46
|
-
beforeEachTest {
|
|
47
|
-
timersNativeModule = TimersNativeModuleStub()
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
fun givenTimer(timer: Any) {
|
|
51
|
-
timersNativeModule.mTimers.add(timer)
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
fun uut() = DefaultIdleInterrogationStrategy(timersNativeModule)
|
|
55
|
-
|
|
56
|
-
it("should be idle if there are no timers in queue") {
|
|
57
|
-
Assertions.assertThat(uut().isIdleNow()).isTrue()
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
it("should be busy if there's a meaningful pending timer") {
|
|
61
|
-
givenTimer(aOneShotTimer(MEANINGFUL_TIMER_INTERVAL))
|
|
62
|
-
Assertions.assertThat(uut().isIdleNow()).isFalse()
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
it("should be idle if pending timer is too far away (ie not meaningful)") {
|
|
66
|
-
givenTimer(aOneShotTimer(BUSY_INTERVAL_MS + 1))
|
|
67
|
-
Assertions.assertThat(uut().isIdleNow()).isTrue()
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
it("should be idle if the only timer is a repeating one") {
|
|
71
|
-
givenTimer(aRepeatingTimer(MEANINGFUL_TIMER_INTERVAL))
|
|
72
|
-
Assertions.assertThat(uut().isIdleNow()).isTrue()
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
it("should be busy if a meaningful pending timer lies beyond a repeating one") {
|
|
76
|
-
givenTimer(aRepeatingTimer(BUSY_INTERVAL_MS / 10))
|
|
77
|
-
givenTimer(aOneShotTimer(BUSY_INTERVAL_MS))
|
|
78
|
-
Assertions.assertThat(uut().isIdleNow()).isFalse()
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
/**
|
|
82
|
-
* Note: Reversed logic due to this issue: https://github.com/wix/Detox/issues/1171 !!!
|
|
83
|
-
*
|
|
84
|
-
* Apparently at times (rare) this caused Espresso to think we're idle too soon, rendering
|
|
85
|
-
* it never to query any idling resource again even after the timer effectively expires...
|
|
86
|
-
*/
|
|
87
|
-
it("should be *busy* even if all timers are overdue") {
|
|
88
|
-
givenTimer(anOverdueTimer())
|
|
89
|
-
givenTimer(anOverdueTimer())
|
|
90
|
-
Assertions.assertThat(uut().isIdleNow()).isFalse()
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
it("should be busy if has a meaningful pending timer set beyond an overdue timer") {
|
|
94
|
-
givenTimer(anOverdueTimer())
|
|
95
|
-
givenTimer(aOneShotTimer(MEANINGFUL_TIMER_INTERVAL))
|
|
96
|
-
Assertions.assertThat(uut().isIdleNow()).isFalse()
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
it("should yield to other threads using the timers module") {
|
|
100
|
-
val executor = Executors.newSingleThreadExecutor()
|
|
101
|
-
var isIdle: Boolean? = null
|
|
102
|
-
|
|
103
|
-
synchronized(timersNativeModule.mTimerGuard) {
|
|
104
|
-
executor.submit {
|
|
105
|
-
isIdle = uut().isIdleNow()
|
|
106
|
-
}
|
|
107
|
-
UTHelpers.yieldToOtherThreads(executor)
|
|
108
|
-
Assertions.assertThat(isIdle).isNull()
|
|
109
|
-
}
|
|
110
|
-
UTHelpers.yieldToOtherThreads(executor)
|
|
111
|
-
Assertions.assertThat(isIdle).isNotNull()
|
|
112
|
-
executor.shutdownNow()
|
|
113
|
-
}
|
|
114
|
-
}
|
|
115
|
-
})
|