detox 20.25.6 → 20.26.2
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.25.6/detox-20.25.6-sources.jar → 20.26.2/detox-20.26.2-sources.jar} +0 -0
- package/Detox-android/com/wix/detox/20.26.2/detox-20.26.2-sources.jar.md5 +1 -0
- package/Detox-android/com/wix/detox/20.26.2/detox-20.26.2-sources.jar.sha1 +1 -0
- package/Detox-android/com/wix/detox/20.26.2/detox-20.26.2-sources.jar.sha256 +1 -0
- package/Detox-android/com/wix/detox/20.26.2/detox-20.26.2-sources.jar.sha512 +1 -0
- package/Detox-android/com/wix/detox/20.26.2/detox-20.26.2.aar +0 -0
- package/Detox-android/com/wix/detox/20.26.2/detox-20.26.2.aar.md5 +1 -0
- package/Detox-android/com/wix/detox/20.26.2/detox-20.26.2.aar.sha1 +1 -0
- package/Detox-android/com/wix/detox/20.26.2/detox-20.26.2.aar.sha256 +1 -0
- package/Detox-android/com/wix/detox/20.26.2/detox-20.26.2.aar.sha512 +1 -0
- package/Detox-android/com/wix/detox/{20.25.6/detox-20.25.6.pom → 20.26.2/detox-20.26.2.pom} +12 -12
- package/Detox-android/com/wix/detox/20.26.2/detox-20.26.2.pom.md5 +1 -0
- package/Detox-android/com/wix/detox/20.26.2/detox-20.26.2.pom.sha1 +1 -0
- package/Detox-android/com/wix/detox/20.26.2/detox-20.26.2.pom.sha256 +1 -0
- package/Detox-android/com/wix/detox/20.26.2/detox-20.26.2.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-android/com/wix/detox-legacy/{20.25.6/detox-legacy-20.25.6-sources.jar → 20.26.2/detox-legacy-20.26.2-sources.jar} +0 -0
- package/Detox-android/com/wix/detox-legacy/20.26.2/detox-legacy-20.26.2-sources.jar.md5 +1 -0
- package/Detox-android/com/wix/detox-legacy/20.26.2/detox-legacy-20.26.2-sources.jar.sha1 +1 -0
- package/Detox-android/com/wix/detox-legacy/20.26.2/detox-legacy-20.26.2-sources.jar.sha256 +1 -0
- package/Detox-android/com/wix/detox-legacy/20.26.2/detox-legacy-20.26.2-sources.jar.sha512 +1 -0
- package/Detox-android/com/wix/detox-legacy/20.26.2/detox-legacy-20.26.2.aar +0 -0
- package/Detox-android/com/wix/detox-legacy/20.26.2/detox-legacy-20.26.2.aar.md5 +1 -0
- package/Detox-android/com/wix/detox-legacy/20.26.2/detox-legacy-20.26.2.aar.sha1 +1 -0
- package/Detox-android/com/wix/detox-legacy/20.26.2/detox-legacy-20.26.2.aar.sha256 +1 -0
- package/Detox-android/com/wix/detox-legacy/20.26.2/detox-legacy-20.26.2.aar.sha512 +1 -0
- package/Detox-android/com/wix/detox-legacy/{20.25.6/detox-legacy-20.25.6.pom → 20.26.2/detox-legacy-20.26.2.pom} +12 -12
- package/Detox-android/com/wix/detox-legacy/20.26.2/detox-legacy-20.26.2.pom.md5 +1 -0
- package/Detox-android/com/wix/detox-legacy/20.26.2/detox-legacy-20.26.2.pom.sha1 +1 -0
- package/Detox-android/com/wix/detox-legacy/20.26.2/detox-legacy-20.26.2.pom.sha256 +1 -0
- package/Detox-android/com/wix/detox-legacy/20.26.2/detox-legacy-20.26.2.pom.sha512 +1 -0
- package/Detox-android/com/wix/detox-legacy/maven-metadata.xml +4 -4
- package/Detox-android/com/wix/detox-legacy/maven-metadata.xml.md5 +1 -1
- package/Detox-android/com/wix/detox-legacy/maven-metadata.xml.sha1 +1 -1
- package/Detox-android/com/wix/detox-legacy/maven-metadata.xml.sha256 +1 -1
- package/Detox-android/com/wix/detox-legacy/maven-metadata.xml.sha512 +1 -1
- package/Detox-ios-framework.tbz +0 -0
- package/Detox-ios-src.tbz +0 -0
- package/Detox-ios-xcuitest.tbz +0 -0
- package/android/detox/build.gradle +7 -8
- package/android/detox/proguard-rules-app.pro +3 -0
- package/android/detox/src/full/java/com/wix/detox/Detox.java +5 -0
- package/android/detox/src/full/java/com/wix/detox/espresso/assertion/ViewAssertions.java +6 -8
- package/android/detox/src/full/java/com/wix/detox/espresso/hierarchy/RootViewsHelper.kt +51 -0
- package/android/detox/src/full/java/com/wix/detox/espresso/hierarchy/ViewHierarchyGenerator.kt +128 -0
- package/detox.d.ts +12 -0
- package/package.json +3 -2
- package/src/android/espressoapi/Detox.js +15 -0
- package/src/client/Client.js +6 -0
- package/src/client/actions/actions.js +21 -1
- package/src/copilot/CopilotDriver.js +140 -0
- package/src/devices/runtime/RuntimeDevice.js +5 -0
- package/src/devices/runtime/drivers/DeviceDriverBase.js +4 -0
- package/src/devices/runtime/drivers/android/AndroidDriver.js +5 -0
- package/src/devices/runtime/drivers/ios/SimulatorDriver.js +4 -0
- package/Detox-android/com/wix/detox/20.25.6/detox-20.25.6-sources.jar.md5 +0 -1
- package/Detox-android/com/wix/detox/20.25.6/detox-20.25.6-sources.jar.sha1 +0 -1
- package/Detox-android/com/wix/detox/20.25.6/detox-20.25.6-sources.jar.sha256 +0 -1
- package/Detox-android/com/wix/detox/20.25.6/detox-20.25.6-sources.jar.sha512 +0 -1
- package/Detox-android/com/wix/detox/20.25.6/detox-20.25.6.aar +0 -0
- package/Detox-android/com/wix/detox/20.25.6/detox-20.25.6.aar.md5 +0 -1
- package/Detox-android/com/wix/detox/20.25.6/detox-20.25.6.aar.sha1 +0 -1
- package/Detox-android/com/wix/detox/20.25.6/detox-20.25.6.aar.sha256 +0 -1
- package/Detox-android/com/wix/detox/20.25.6/detox-20.25.6.aar.sha512 +0 -1
- package/Detox-android/com/wix/detox/20.25.6/detox-20.25.6.pom.md5 +0 -1
- package/Detox-android/com/wix/detox/20.25.6/detox-20.25.6.pom.sha1 +0 -1
- package/Detox-android/com/wix/detox/20.25.6/detox-20.25.6.pom.sha256 +0 -1
- package/Detox-android/com/wix/detox/20.25.6/detox-20.25.6.pom.sha512 +0 -1
- package/Detox-android/com/wix/detox-legacy/20.25.6/detox-legacy-20.25.6-sources.jar.md5 +0 -1
- package/Detox-android/com/wix/detox-legacy/20.25.6/detox-legacy-20.25.6-sources.jar.sha1 +0 -1
- package/Detox-android/com/wix/detox-legacy/20.25.6/detox-legacy-20.25.6-sources.jar.sha256 +0 -1
- package/Detox-android/com/wix/detox-legacy/20.25.6/detox-legacy-20.25.6-sources.jar.sha512 +0 -1
- package/Detox-android/com/wix/detox-legacy/20.25.6/detox-legacy-20.25.6.aar +0 -0
- package/Detox-android/com/wix/detox-legacy/20.25.6/detox-legacy-20.25.6.aar.md5 +0 -1
- package/Detox-android/com/wix/detox-legacy/20.25.6/detox-legacy-20.25.6.aar.sha1 +0 -1
- package/Detox-android/com/wix/detox-legacy/20.25.6/detox-legacy-20.25.6.aar.sha256 +0 -1
- package/Detox-android/com/wix/detox-legacy/20.25.6/detox-legacy-20.25.6.aar.sha512 +0 -1
- package/Detox-android/com/wix/detox-legacy/20.25.6/detox-legacy-20.25.6.pom.md5 +0 -1
- package/Detox-android/com/wix/detox-legacy/20.25.6/detox-legacy-20.25.6.pom.sha1 +0 -1
- package/Detox-android/com/wix/detox-legacy/20.25.6/detox-legacy-20.25.6.pom.sha256 +0 -1
- package/Detox-android/com/wix/detox-legacy/20.25.6/detox-legacy-20.25.6.pom.sha512 +0 -1
|
Binary file
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
ea98a7bac84cd877ac7a13aa5b9d3cc1
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
a67071d6d4bdcd041e91bc9f58d5d57637532cb9
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
9e325d7b0b5b8dab384773bcf96df7a44e7a76f5375b1afba2e29b9a53c60e7b
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
4ca91364a087ff16bd38d1721163b47f3d6435552605e1c2cba38138739e42bf45161458e997bc14be075b0bfa9df2ac8a311c79dc21e67216726b3f8a920db1
|
|
Binary file
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
19245568a5b1fc7e18eae4c34019b2d0
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
dfb1a4d4b6a06bbe8952fe821ab3278364fc3cf2
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
294b99bfcfc4acf89c10c76c4cfb07b61dec92d8f45a2ed137092aa766d7e215
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
546fa7e195d2c2077d9e41f2b003ead174c820ce45027752e86a366e673023cc41d09b5b5ccd3bdb693f403e6c8b65567af12208ece66e65d85937e9a65f677d
|
|
@@ -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.26.2</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>
|
|
@@ -30,22 +30,28 @@
|
|
|
30
30
|
<url>https://github.com/wix/detox</url>
|
|
31
31
|
</scm>
|
|
32
32
|
<dependencies>
|
|
33
|
+
<dependency>
|
|
34
|
+
<groupId>org.jetbrains.kotlin</groupId>
|
|
35
|
+
<artifactId>kotlin-stdlib-jdk8</artifactId>
|
|
36
|
+
<version>1.8.0</version>
|
|
37
|
+
<scope>compile</scope>
|
|
38
|
+
</dependency>
|
|
33
39
|
<dependency>
|
|
34
40
|
<groupId>androidx.test.espresso</groupId>
|
|
35
41
|
<artifactId>espresso-core</artifactId>
|
|
36
|
-
<version>3.
|
|
42
|
+
<version>3.6.1</version>
|
|
37
43
|
<scope>compile</scope>
|
|
38
44
|
</dependency>
|
|
39
45
|
<dependency>
|
|
40
46
|
<groupId>androidx.test.espresso</groupId>
|
|
41
47
|
<artifactId>espresso-web</artifactId>
|
|
42
|
-
<version>3.
|
|
48
|
+
<version>3.6.1</version>
|
|
43
49
|
<scope>compile</scope>
|
|
44
50
|
</dependency>
|
|
45
51
|
<dependency>
|
|
46
52
|
<groupId>androidx.test.espresso</groupId>
|
|
47
53
|
<artifactId>espresso-contrib</artifactId>
|
|
48
|
-
<version>3.
|
|
54
|
+
<version>3.6.1</version>
|
|
49
55
|
<scope>compile</scope>
|
|
50
56
|
<exclusions>
|
|
51
57
|
<exclusion>
|
|
@@ -63,13 +69,13 @@
|
|
|
63
69
|
<dependency>
|
|
64
70
|
<groupId>androidx.test</groupId>
|
|
65
71
|
<artifactId>rules</artifactId>
|
|
66
|
-
<version>1.
|
|
72
|
+
<version>1.6.1</version>
|
|
67
73
|
<scope>compile</scope>
|
|
68
74
|
</dependency>
|
|
69
75
|
<dependency>
|
|
70
76
|
<groupId>androidx.test.ext</groupId>
|
|
71
77
|
<artifactId>junit</artifactId>
|
|
72
|
-
<version>1.1
|
|
78
|
+
<version>1.2.1</version>
|
|
73
79
|
<scope>compile</scope>
|
|
74
80
|
</dependency>
|
|
75
81
|
<dependency>
|
|
@@ -78,12 +84,6 @@
|
|
|
78
84
|
<version>2.2.0</version>
|
|
79
85
|
<scope>compile</scope>
|
|
80
86
|
</dependency>
|
|
81
|
-
<dependency>
|
|
82
|
-
<groupId>org.jetbrains.kotlin</groupId>
|
|
83
|
-
<artifactId>kotlin-stdlib-jdk8</artifactId>
|
|
84
|
-
<version>1.2.0</version>
|
|
85
|
-
<scope>runtime</scope>
|
|
86
|
-
</dependency>
|
|
87
87
|
<dependency>
|
|
88
88
|
<groupId>org.apache.commons</groupId>
|
|
89
89
|
<artifactId>commons-lang3</artifactId>
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
f5574f4b81f29bd42c5da2cbaae85003
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
65101d817b9185e67e3d5fb396107ad252a6ade7
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
8830fd9064558962e2d7195512f9db4aae71801865f20b240a17ba4cebc21ab4
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
d026c556f62910b4728822cea8b03745bf74617c2bf3df7d97b29eb0007a1ace87a00af9aec32fa1798f0345e551ed62abd9be7e16f96b59ae56a88950ea46ce
|
|
@@ -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.26.2</latest>
|
|
7
|
+
<release>20.26.2</release>
|
|
8
8
|
<versions>
|
|
9
|
-
<version>20.
|
|
9
|
+
<version>20.26.2</version>
|
|
10
10
|
</versions>
|
|
11
|
-
<lastUpdated>
|
|
11
|
+
<lastUpdated>20240905213155</lastUpdated>
|
|
12
12
|
</versioning>
|
|
13
13
|
</metadata>
|
|
@@ -1 +1 @@
|
|
|
1
|
-
|
|
1
|
+
9e3e8a8d05fd018af3b4b1cecac85ceb
|
|
@@ -1 +1 @@
|
|
|
1
|
-
|
|
1
|
+
49a5d3258b3a4b18d55c0c803f65e9c7bb470c8e
|
|
@@ -1 +1 @@
|
|
|
1
|
-
|
|
1
|
+
f8b05715aaf9d675552325c062d5509e983560df36e2c0964bf858aac906be06
|
|
@@ -1 +1 @@
|
|
|
1
|
-
|
|
1
|
+
9f65c4a4e108884baa631feba8abcc34372ee88b3d194b4eb9f94c88162e262fd8a0ed62f4ec94162c3891ea6ca085ba737892d73709ac2ec3b32e1d1e22ae69
|
|
Binary file
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
5fe1ece0c6f59a509e44c153a67c0aad
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
af24ad68bc24fda67b522b4853d47193de81fb59
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
56e2fc034e270dd194fbfa0a8fe24e1b95fb298564cfa6a31c1b79d5eeb5f3f2
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
109252b02fbd404778467ad18d611ebbb1a442dde9dca1d8e3feb469d81a0d6aff4a5285fb3677dc219b23acc78c88a134f3f3ef5f19487b7b7d3fb06049a4c8
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
0dd6f951f83bfb1c258c09e57291b5f3
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
54212838677b6cf72c2eb964dc911a9a80cf54a7
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
c2452ceba0cb3a2a6517086d81a0e990d82ab263395a0e1166b8178769cd8a51
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
3d71f12171376fcf35b46ebc6a6cf942e0a7151a8f26287b41b6e2807f4bd8d37704aeaa89b7b0231c2286a301ebbfa3ff77a0a9cee92c02463c0085a4190085
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
<modelVersion>4.0.0</modelVersion>
|
|
4
4
|
<groupId>com.wix</groupId>
|
|
5
5
|
<artifactId>detox-legacy</artifactId>
|
|
6
|
-
<version>20.
|
|
6
|
+
<version>20.26.2</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>
|
|
@@ -30,22 +30,28 @@
|
|
|
30
30
|
<url>https://github.com/wix/detox</url>
|
|
31
31
|
</scm>
|
|
32
32
|
<dependencies>
|
|
33
|
+
<dependency>
|
|
34
|
+
<groupId>org.jetbrains.kotlin</groupId>
|
|
35
|
+
<artifactId>kotlin-stdlib-jdk8</artifactId>
|
|
36
|
+
<version>1.8.0</version>
|
|
37
|
+
<scope>compile</scope>
|
|
38
|
+
</dependency>
|
|
33
39
|
<dependency>
|
|
34
40
|
<groupId>androidx.test.espresso</groupId>
|
|
35
41
|
<artifactId>espresso-core</artifactId>
|
|
36
|
-
<version>3.
|
|
42
|
+
<version>3.6.1</version>
|
|
37
43
|
<scope>compile</scope>
|
|
38
44
|
</dependency>
|
|
39
45
|
<dependency>
|
|
40
46
|
<groupId>androidx.test.espresso</groupId>
|
|
41
47
|
<artifactId>espresso-web</artifactId>
|
|
42
|
-
<version>3.
|
|
48
|
+
<version>3.6.1</version>
|
|
43
49
|
<scope>compile</scope>
|
|
44
50
|
</dependency>
|
|
45
51
|
<dependency>
|
|
46
52
|
<groupId>androidx.test.espresso</groupId>
|
|
47
53
|
<artifactId>espresso-contrib</artifactId>
|
|
48
|
-
<version>3.
|
|
54
|
+
<version>3.6.1</version>
|
|
49
55
|
<scope>compile</scope>
|
|
50
56
|
<exclusions>
|
|
51
57
|
<exclusion>
|
|
@@ -63,13 +69,13 @@
|
|
|
63
69
|
<dependency>
|
|
64
70
|
<groupId>androidx.test</groupId>
|
|
65
71
|
<artifactId>rules</artifactId>
|
|
66
|
-
<version>1.
|
|
72
|
+
<version>1.6.1</version>
|
|
67
73
|
<scope>compile</scope>
|
|
68
74
|
</dependency>
|
|
69
75
|
<dependency>
|
|
70
76
|
<groupId>androidx.test.ext</groupId>
|
|
71
77
|
<artifactId>junit</artifactId>
|
|
72
|
-
<version>1.1
|
|
78
|
+
<version>1.2.1</version>
|
|
73
79
|
<scope>compile</scope>
|
|
74
80
|
</dependency>
|
|
75
81
|
<dependency>
|
|
@@ -78,12 +84,6 @@
|
|
|
78
84
|
<version>2.2.0</version>
|
|
79
85
|
<scope>compile</scope>
|
|
80
86
|
</dependency>
|
|
81
|
-
<dependency>
|
|
82
|
-
<groupId>org.jetbrains.kotlin</groupId>
|
|
83
|
-
<artifactId>kotlin-stdlib-jdk8</artifactId>
|
|
84
|
-
<version>1.2.0</version>
|
|
85
|
-
<scope>runtime</scope>
|
|
86
|
-
</dependency>
|
|
87
87
|
<dependency>
|
|
88
88
|
<groupId>org.apache.commons</groupId>
|
|
89
89
|
<artifactId>commons-lang3</artifactId>
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
817a01b2f72e4cc9ee814d9aa83a6898
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
5ab9e6d2bf60cc87c07b26d73ded613cc4692fe4
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
26768c504f24bc35eee880bfe2fcc6c062aac63e5eee306d2196d27c989dbc40
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
af66500c5a4d075c5d9c739439fc49bcdebe5a7b2f8d364b7e8b1f879fc0901184b928d33ed66b59f3b5d7b89050acc3b6d4e1bfd151e114561ba975c9ca6e59
|
|
@@ -3,11 +3,11 @@
|
|
|
3
3
|
<groupId>com.wix</groupId>
|
|
4
4
|
<artifactId>detox-legacy</artifactId>
|
|
5
5
|
<versioning>
|
|
6
|
-
<latest>20.
|
|
7
|
-
<release>20.
|
|
6
|
+
<latest>20.26.2</latest>
|
|
7
|
+
<release>20.26.2</release>
|
|
8
8
|
<versions>
|
|
9
|
-
<version>20.
|
|
9
|
+
<version>20.26.2</version>
|
|
10
10
|
</versions>
|
|
11
|
-
<lastUpdated>
|
|
11
|
+
<lastUpdated>20240905213242</lastUpdated>
|
|
12
12
|
</versioning>
|
|
13
13
|
</metadata>
|
|
@@ -1 +1 @@
|
|
|
1
|
-
|
|
1
|
+
7d1e75f8073d7e8507484042d83103e1
|
|
@@ -1 +1 @@
|
|
|
1
|
-
|
|
1
|
+
f106fa7fa6ca0ecff78f8b6c7094118a0266de5a
|
|
@@ -1 +1 @@
|
|
|
1
|
-
|
|
1
|
+
8d88d3608dc25dd1305f93cb629d308c3167f6e4ea232efbbc54f309288d5bba
|
|
@@ -1 +1 @@
|
|
|
1
|
-
|
|
1
|
+
ce63462b86b96e3ee62a7817f56fb3f91d30801e93c41e0a9b8e8a0300a3bae285d17c1bd7a07054bc45557f9c1b16da338dcce8ef8197c7957088c327ea4b4d
|
package/Detox-ios-framework.tbz
CHANGED
|
Binary file
|
package/Detox-ios-src.tbz
CHANGED
|
Binary file
|
package/Detox-ios-xcuitest.tbz
CHANGED
|
Binary file
|
|
@@ -2,7 +2,7 @@ apply plugin: 'com.android.library'
|
|
|
2
2
|
apply plugin: 'kotlin-android'
|
|
3
3
|
apply from: '../rninfo.gradle'
|
|
4
4
|
|
|
5
|
-
def _kotlinMinVersion = '1.
|
|
5
|
+
def _kotlinMinVersion = '1.8.0'
|
|
6
6
|
def _materialMinVersion = '1.11.0'
|
|
7
7
|
|
|
8
8
|
def _ext = rootProject.ext
|
|
@@ -111,7 +111,7 @@ android {
|
|
|
111
111
|
|
|
112
112
|
// Fundamental deps.
|
|
113
113
|
dependencies {
|
|
114
|
-
|
|
114
|
+
api "org.jetbrains.kotlin:$_kotlinStdlib:$_kotlinVersion"
|
|
115
115
|
|
|
116
116
|
compileOnly "${_rnNativeArtifact}"
|
|
117
117
|
}
|
|
@@ -123,26 +123,25 @@ dependencies {
|
|
|
123
123
|
// Versions are in-sync with the 'androidx-test-1.4.0' release/tag of the android-test github repo,
|
|
124
124
|
// used by the Detox generator. See https://github.com/android/android-test/releases/tag/androidx-test-1.4.0
|
|
125
125
|
// Important: Should remain so when generator tag is replaced!
|
|
126
|
-
api('androidx.test.espresso:espresso-core:3.
|
|
126
|
+
api('androidx.test.espresso:espresso-core:3.6.1') {
|
|
127
127
|
because 'Needed all across Detox but also makes Espresso seamlessly provided to Detox users with hybrid apps/E2E-tests.'
|
|
128
128
|
}
|
|
129
|
-
api('androidx.test.espresso:espresso-web:3.
|
|
129
|
+
api('androidx.test.espresso:espresso-web:3.6.1') {
|
|
130
130
|
because 'Web-View testing'
|
|
131
131
|
}
|
|
132
|
-
api('androidx.test.espresso:espresso-contrib:3.
|
|
132
|
+
api('androidx.test.espresso:espresso-contrib:3.6.1') {
|
|
133
133
|
because 'Android datepicker support'
|
|
134
134
|
exclude group: "org.checkerframework", module: "checker"
|
|
135
135
|
}
|
|
136
136
|
api('org.hamcrest:hamcrest:2.2') {
|
|
137
137
|
because 'See https://github.com/wix/Detox/issues/3920. Need to force hamcrest 2.2 win in battle of 2.2 vs. 1.3 (specified by Espresso).'
|
|
138
138
|
}
|
|
139
|
-
api('androidx.test:rules:1.
|
|
139
|
+
api('androidx.test:rules:1.6.1') {
|
|
140
140
|
because 'of ActivityTestRule. Needed by users *and* internally used by Detox.'
|
|
141
141
|
}
|
|
142
|
-
api('androidx.test.ext:junit:1.1
|
|
142
|
+
api('androidx.test.ext:junit:1.2.1') {
|
|
143
143
|
because 'Needed so as to seamlessly provide AndroidJUnit4 to Detox users. Depends on junit core.'
|
|
144
144
|
}
|
|
145
|
-
|
|
146
145
|
// Version is the latest; Cannot sync with the Github repo (e.g. android/android-test) because the androidx
|
|
147
146
|
// packaging version of associated classes is simply not there...
|
|
148
147
|
api('androidx.test.uiautomator:uiautomator:2.2.0') {
|
|
@@ -14,11 +14,14 @@
|
|
|
14
14
|
-keep class com.reactnativecommunity.slider.** { *; }
|
|
15
15
|
-keep class com.reactnativecommunity.asyncstorage.** { *; }
|
|
16
16
|
|
|
17
|
+
-keep class kotlin.reflect.** { *; }
|
|
18
|
+
-keep class kotlin.coroutines.CoroutineDispatcher { *; }
|
|
17
19
|
-keep class kotlin.jvm.** { *; }
|
|
18
20
|
-keep class kotlin.collections.** { *; }
|
|
19
21
|
-keep class kotlin.text.** { *; }
|
|
20
22
|
-keep class kotlin.io.** { *; }
|
|
21
23
|
-keep class okhttp3.** { *; }
|
|
24
|
+
-keep class kotlin.LazyKt { *; }
|
|
22
25
|
|
|
23
26
|
-keep class androidx.concurrent.futures.** { *; }
|
|
24
27
|
|
|
@@ -7,6 +7,7 @@ import androidx.test.platform.app.InstrumentationRegistry;
|
|
|
7
7
|
import androidx.test.rule.ActivityTestRule;
|
|
8
8
|
|
|
9
9
|
import com.wix.detox.config.DetoxConfig;
|
|
10
|
+
import com.wix.detox.espresso.hierarchy.ViewHierarchyGenerator;
|
|
10
11
|
|
|
11
12
|
/**
|
|
12
13
|
* <p>Static class.</p>
|
|
@@ -141,4 +142,8 @@ public final class Detox {
|
|
|
141
142
|
private static Context getAppContext() {
|
|
142
143
|
return InstrumentationRegistry.getInstrumentation().getTargetContext().getApplicationContext();
|
|
143
144
|
}
|
|
145
|
+
|
|
146
|
+
public static String generateViewHierarchyXml(boolean shouldInjectTestIds) {
|
|
147
|
+
return ViewHierarchyGenerator.generateXml(shouldInjectTestIds);
|
|
148
|
+
}
|
|
144
149
|
}
|
|
@@ -1,16 +1,15 @@
|
|
|
1
1
|
package com.wix.detox.espresso.assertion;
|
|
2
2
|
|
|
3
|
-
import androidx.
|
|
4
|
-
import android.view.View;
|
|
3
|
+
import static androidx.test.espresso.matcher.ViewMatchers.assertThat;
|
|
5
4
|
|
|
6
|
-
import
|
|
7
|
-
import org.hamcrest.StringDescription;
|
|
5
|
+
import android.view.View;
|
|
8
6
|
|
|
7
|
+
import androidx.annotation.NonNull;
|
|
9
8
|
import androidx.test.espresso.NoMatchingViewException;
|
|
10
9
|
import androidx.test.espresso.ViewAssertion;
|
|
11
10
|
|
|
12
|
-
import
|
|
13
|
-
import
|
|
11
|
+
import org.hamcrest.Matcher;
|
|
12
|
+
import org.hamcrest.StringDescription;
|
|
14
13
|
|
|
15
14
|
/**
|
|
16
15
|
* A custom extension of {@link androidx.test.espresso.assertion.ViewAssertions}.
|
|
@@ -24,9 +23,8 @@ public class ViewAssertions {
|
|
|
24
23
|
* which is more suitable for Detox' separated interaction-matcher architecture.
|
|
25
24
|
* See {@link MatchesViewAssertion} for more details.
|
|
26
25
|
*/
|
|
27
|
-
@SuppressWarnings("unchecked")
|
|
28
26
|
public static ViewAssertion matches(final Matcher<? super View> viewMatcher) {
|
|
29
|
-
return new MatchesViewAssertion(
|
|
27
|
+
return new MatchesViewAssertion(viewMatcher);
|
|
30
28
|
}
|
|
31
29
|
|
|
32
30
|
/**
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
package com.wix.detox.espresso.hierarchy
|
|
2
|
+
|
|
3
|
+
import android.annotation.SuppressLint
|
|
4
|
+
import android.view.View
|
|
5
|
+
import java.lang.reflect.Field
|
|
6
|
+
import java.lang.reflect.Method
|
|
7
|
+
|
|
8
|
+
object RootViewsHelper {
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Get rootviews from RootViewImpl instances that are stored in WindowManagerGlobal.
|
|
12
|
+
*/
|
|
13
|
+
fun getRootViews(): List<View?>? {
|
|
14
|
+
val rootViewsReflectedObjects = getAllViewRootObjects()
|
|
15
|
+
val rootViews = rootViewsReflectedObjects?.map {
|
|
16
|
+
// Root View is stored in the ViewRootImpl instance
|
|
17
|
+
val getViewMethod = it.javaClass.getDeclaredMethod("getView")
|
|
18
|
+
getViewMethod.isAccessible = true
|
|
19
|
+
|
|
20
|
+
// Invoke the method to get the root View
|
|
21
|
+
getViewMethod.invoke(it) as? View
|
|
22
|
+
}
|
|
23
|
+
return rootViews
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
@SuppressLint("PrivateApi", "DiscouragedPrivateApi")
|
|
27
|
+
private fun getAllViewRootObjects(): List<Any>? {
|
|
28
|
+
return try {
|
|
29
|
+
// Get the WindowManagerGlobal class
|
|
30
|
+
val windowManagerGlobalClass = Class.forName("android.view.WindowManagerGlobal")
|
|
31
|
+
|
|
32
|
+
// Get the getInstance method
|
|
33
|
+
val getInstanceMethod: Method = windowManagerGlobalClass.getDeclaredMethod("getInstance")
|
|
34
|
+
getInstanceMethod.isAccessible = true
|
|
35
|
+
|
|
36
|
+
// Get the single instance of WindowManagerGlobal
|
|
37
|
+
val windowManagerGlobal = getInstanceMethod.invoke(null)
|
|
38
|
+
|
|
39
|
+
// Get the mRoots field, which is a list of ViewRootImpl instances
|
|
40
|
+
val mRootsField: Field = windowManagerGlobalClass.getDeclaredField("mRoots")
|
|
41
|
+
mRootsField.isAccessible = true
|
|
42
|
+
|
|
43
|
+
// Return the list of ViewRootImpl instances
|
|
44
|
+
@Suppress("UNCHECKED_CAST")
|
|
45
|
+
mRootsField.get(windowManagerGlobal) as? List<Any>
|
|
46
|
+
} catch (e: Exception) {
|
|
47
|
+
e.printStackTrace()
|
|
48
|
+
null
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
}
|
package/android/detox/src/full/java/com/wix/detox/espresso/hierarchy/ViewHierarchyGenerator.kt
ADDED
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
package com.wix.detox.espresso.hierarchy
|
|
2
|
+
|
|
3
|
+
import android.util.Xml
|
|
4
|
+
import android.view.View
|
|
5
|
+
import android.view.ViewGroup
|
|
6
|
+
import android.widget.TextView
|
|
7
|
+
import com.wix.detox.reactnative.ui.getAccessibilityLabel
|
|
8
|
+
import org.xmlpull.v1.XmlSerializer
|
|
9
|
+
import java.io.StringWriter
|
|
10
|
+
|
|
11
|
+
object ViewHierarchyGenerator {
|
|
12
|
+
@JvmStatic
|
|
13
|
+
fun generateXml(shouldInjectTestIds: Boolean): String {
|
|
14
|
+
val rootViews = RootViewsHelper.getRootViews()
|
|
15
|
+
return generateXmlFromViews(rootViews, shouldInjectTestIds)
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
private fun generateXmlFromViews(rootViews: List<View?>?, shouldInjectTestIds: Boolean): String {
|
|
19
|
+
return StringWriter().use { writer ->
|
|
20
|
+
val serializer = Xml.newSerializer().apply {
|
|
21
|
+
setOutput(writer)
|
|
22
|
+
startDocument(Xml.Encoding.UTF_8.name, true)
|
|
23
|
+
setFeature("http://xmlpull.org/v1/doc/features.html#indent-output", true)
|
|
24
|
+
startTag("", "ViewHierarchy")
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
rootViews?.forEach { rootView ->
|
|
28
|
+
rootView?.let {
|
|
29
|
+
serializeViewHierarchy(it, serializer, shouldInjectTestIds, emptyList())
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
serializer.apply {
|
|
34
|
+
endTag("", "ViewHierarchy")
|
|
35
|
+
endDocument()
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
writer.toString()
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
private fun serializeViewHierarchy(
|
|
43
|
+
view: View,
|
|
44
|
+
serializer: XmlSerializer,
|
|
45
|
+
shouldInjectTestIds: Boolean,
|
|
46
|
+
indexPath: List<Int>
|
|
47
|
+
) {
|
|
48
|
+
serializer.startTag("", view.javaClass.simpleName)
|
|
49
|
+
serializeViewAttributes(view, serializer, shouldInjectTestIds, indexPath)
|
|
50
|
+
|
|
51
|
+
if (view is ViewGroup) {
|
|
52
|
+
for (i in 0 until view.childCount) {
|
|
53
|
+
serializeViewHierarchy(
|
|
54
|
+
view.getChildAt(i),
|
|
55
|
+
serializer,
|
|
56
|
+
shouldInjectTestIds,
|
|
57
|
+
indexPath + i
|
|
58
|
+
)
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
serializer.endTag("", view.javaClass.simpleName)
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
private fun serializeViewAttributes(
|
|
66
|
+
view: View,
|
|
67
|
+
serializer: XmlSerializer,
|
|
68
|
+
shouldInjectTestIds: Boolean,
|
|
69
|
+
indexPath: List<Int>
|
|
70
|
+
) {
|
|
71
|
+
val attributes = mutableMapOf(
|
|
72
|
+
"class" to view.javaClass.name,
|
|
73
|
+
"width" to view.width.toString(),
|
|
74
|
+
"height" to view.height.toString(),
|
|
75
|
+
"visibility" to view.visibilityToString(),
|
|
76
|
+
"alpha" to view.alpha.toString(),
|
|
77
|
+
"focused" to view.isFocused.toString(),
|
|
78
|
+
"value" to (view.contentDescription?.toString() ?: ""),
|
|
79
|
+
"label" to (view.getAccessibilityLabel()?.toString() ?: "")
|
|
80
|
+
)
|
|
81
|
+
|
|
82
|
+
view.id.takeIf { it != View.NO_ID }?.let {
|
|
83
|
+
attributes["id"] = try {
|
|
84
|
+
view.resources.getResourceName(it)
|
|
85
|
+
} catch (e: Exception) {
|
|
86
|
+
it.toString()
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
val location = IntArray(2).apply { view.getLocationInWindow(this) }
|
|
91
|
+
attributes["x"] = location[0].toString()
|
|
92
|
+
attributes["y"] = location[1].toString()
|
|
93
|
+
|
|
94
|
+
if (view is TextView) {
|
|
95
|
+
attributes["text"] = view.text.toString()
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
val currentTestId = view.tag?.toString() ?: ""
|
|
99
|
+
|
|
100
|
+
val injectedPrefix = "detox_temp_"
|
|
101
|
+
val isTestIdEmpty = currentTestId.isEmpty()
|
|
102
|
+
val isTestIdInjected = currentTestId.startsWith(injectedPrefix)
|
|
103
|
+
val shouldInjectNewTestId = shouldInjectTestIds && (isTestIdEmpty || isTestIdInjected)
|
|
104
|
+
|
|
105
|
+
if (shouldInjectNewTestId) {
|
|
106
|
+
val newTestId = "${injectedPrefix}${indexPath.joinToString("_")}"
|
|
107
|
+
view.tag = newTestId
|
|
108
|
+
attributes["testID"] = newTestId
|
|
109
|
+
} else {
|
|
110
|
+
attributes["testID"] = currentTestId
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
attributes
|
|
114
|
+
.filter { (_, value) ->
|
|
115
|
+
!value.isNullOrEmpty()
|
|
116
|
+
}
|
|
117
|
+
.forEach { (key, value) ->
|
|
118
|
+
serializer.attribute("", key, value)
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
private fun View.visibilityToString() = when (visibility) {
|
|
123
|
+
View.VISIBLE -> "visible"
|
|
124
|
+
View.INVISIBLE -> "invisible"
|
|
125
|
+
View.GONE -> "gone"
|
|
126
|
+
else -> "unknown"
|
|
127
|
+
}
|
|
128
|
+
}
|
package/detox.d.ts
CHANGED
|
@@ -917,6 +917,18 @@ declare global {
|
|
|
917
917
|
*/
|
|
918
918
|
captureViewHierarchy(name?: string): Promise<string>;
|
|
919
919
|
|
|
920
|
+
/**
|
|
921
|
+
* Dump the current view hierarchy of the app as an XML string.
|
|
922
|
+
* @param [shouldInjectTestIds=false] whether to inject testIDs into the view hierarchy when missing,
|
|
923
|
+
* to provide an identifiable reference for each element.
|
|
924
|
+
* @returns a string containing the XML representation of the view hierarchy.
|
|
925
|
+
* @example
|
|
926
|
+
* const viewHierarchy = await device.generateViewHierarchyXml();
|
|
927
|
+
* const viewHierarchyWithInjectedTestIds = await device.generateViewHierarchyXml(true);
|
|
928
|
+
* @note enabling shouldInjectTestIds changes the actual elements during the test run, use with caution.
|
|
929
|
+
*/
|
|
930
|
+
generateViewHierarchyXml(shouldInjectTestIds?: boolean): Promise<string>;
|
|
931
|
+
|
|
920
932
|
/**
|
|
921
933
|
* Simulate shake (iOS Only)
|
|
922
934
|
*/
|
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.26.2",
|
|
5
5
|
"bin": {
|
|
6
6
|
"detox": "local-cli/cli.js"
|
|
7
7
|
},
|
|
@@ -71,6 +71,7 @@
|
|
|
71
71
|
"caf": "^15.0.1",
|
|
72
72
|
"chalk": "^4.0.0",
|
|
73
73
|
"child-process-promise": "^2.2.0",
|
|
74
|
+
"detox-copilot": "^0.0.0",
|
|
74
75
|
"execa": "^5.1.1",
|
|
75
76
|
"find-up": "^5.0.0",
|
|
76
77
|
"fs-extra": "^11.0.0",
|
|
@@ -115,5 +116,5 @@
|
|
|
115
116
|
"browserslist": [
|
|
116
117
|
"node 14"
|
|
117
118
|
],
|
|
118
|
-
"gitHead": "
|
|
119
|
+
"gitHead": "e0a1fefeeec0382b5dc75613a2076d0f6a05e97f"
|
|
119
120
|
}
|
|
@@ -69,6 +69,21 @@ class Detox {
|
|
|
69
69
|
};
|
|
70
70
|
}
|
|
71
71
|
|
|
72
|
+
static generateViewHierarchyXml(shouldInjectTestIds) {
|
|
73
|
+
if (typeof shouldInjectTestIds !== "boolean") throw new Error("shouldInjectTestIds should be a boolean, but got " + (shouldInjectTestIds + (" (" + (typeof shouldInjectTestIds + ")"))));
|
|
74
|
+
return {
|
|
75
|
+
target: {
|
|
76
|
+
type: "Class",
|
|
77
|
+
value: "com.wix.detox.Detox"
|
|
78
|
+
},
|
|
79
|
+
method: "generateViewHierarchyXml",
|
|
80
|
+
args: [{
|
|
81
|
+
type: "boolean",
|
|
82
|
+
value: shouldInjectTestIds
|
|
83
|
+
}]
|
|
84
|
+
};
|
|
85
|
+
}
|
|
86
|
+
|
|
72
87
|
}
|
|
73
88
|
|
|
74
89
|
module.exports = Detox;
|
package/src/client/Client.js
CHANGED
|
@@ -225,6 +225,12 @@ class Client {
|
|
|
225
225
|
}));
|
|
226
226
|
}
|
|
227
227
|
|
|
228
|
+
async generateViewHierarchyXml({ shouldInjectTestIds }) {
|
|
229
|
+
return await this.sendAction(new actions.GenerateViewHierarchyXml({
|
|
230
|
+
shouldInjectTestIds
|
|
231
|
+
}));
|
|
232
|
+
}
|
|
233
|
+
|
|
228
234
|
async currentStatus() {
|
|
229
235
|
return await this.sendAction(new actions.CurrentStatus());
|
|
230
236
|
}
|
|
@@ -292,6 +292,25 @@ class SetInstrumentsRecordingState extends Action {
|
|
|
292
292
|
}
|
|
293
293
|
}
|
|
294
294
|
|
|
295
|
+
class GenerateViewHierarchyXml extends Action {
|
|
296
|
+
constructor(params) {
|
|
297
|
+
super('generateViewHierarchyXml', params);
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
get isAtomic() {
|
|
301
|
+
return false;
|
|
302
|
+
}
|
|
303
|
+
|
|
304
|
+
get timeout() {
|
|
305
|
+
return 0;
|
|
306
|
+
}
|
|
307
|
+
|
|
308
|
+
async handle(response) {
|
|
309
|
+
this.expectResponseOfType(response, 'generateViewHierarchyXmlResult');
|
|
310
|
+
return response.params.viewHierarchy;
|
|
311
|
+
}
|
|
312
|
+
}
|
|
313
|
+
|
|
295
314
|
class CaptureViewHierarchy extends Action {
|
|
296
315
|
constructor(params) {
|
|
297
316
|
super('captureViewHierarchy', params);
|
|
@@ -312,7 +331,7 @@ class CaptureViewHierarchy extends Action {
|
|
|
312
331
|
if (captureViewHierarchyError) {
|
|
313
332
|
throw new DetoxRuntimeError({
|
|
314
333
|
message: 'Failed to capture view hierarchy. Reason:\n',
|
|
315
|
-
debugInfo: captureViewHierarchyError
|
|
334
|
+
debugInfo: captureViewHierarchyError
|
|
316
335
|
});
|
|
317
336
|
}
|
|
318
337
|
|
|
@@ -336,4 +355,5 @@ module.exports = {
|
|
|
336
355
|
SetOrientation,
|
|
337
356
|
SetInstrumentsRecordingState,
|
|
338
357
|
CaptureViewHierarchy,
|
|
358
|
+
GenerateViewHierarchyXml
|
|
339
359
|
};
|
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
const { device } = require('../..');
|
|
2
|
+
|
|
3
|
+
class DetoxDriver {
|
|
4
|
+
constructor() {
|
|
5
|
+
this.availableAPI = {
|
|
6
|
+
matchers: [
|
|
7
|
+
{
|
|
8
|
+
signature: 'by.id(id: string)',
|
|
9
|
+
description: 'Matches elements by their test ID.',
|
|
10
|
+
example: "element(by.id('loginButton'))",
|
|
11
|
+
guidelines: ['Always use test-ids (accessibility identifiers) from the UI hierarchy to identify elements.']
|
|
12
|
+
},
|
|
13
|
+
{
|
|
14
|
+
signature: 'by.text(text: string)',
|
|
15
|
+
description: 'Matches elements by their text.',
|
|
16
|
+
example: "element(by.text('Login'))",
|
|
17
|
+
guidelines: ['Avoid using text matchers when possible, prefer test-ids.']
|
|
18
|
+
},
|
|
19
|
+
{
|
|
20
|
+
signature: 'by.type(type: string)',
|
|
21
|
+
description: 'Matches elements by their type.',
|
|
22
|
+
example: "element(by.type('RCTTextInput'))",
|
|
23
|
+
guidelines: ['Use type matchers as a last resort, prefer test-ids.']
|
|
24
|
+
}
|
|
25
|
+
],
|
|
26
|
+
actions: [
|
|
27
|
+
{
|
|
28
|
+
signature: 'tap(point?: Point2D)',
|
|
29
|
+
description: 'Simulates tap on an element',
|
|
30
|
+
example: "await element(by.id('loginButton')).tap();",
|
|
31
|
+
guidelines: ['Use element(by.id(\'testID\')) to locate elements.']
|
|
32
|
+
},
|
|
33
|
+
{
|
|
34
|
+
signature: 'longPress(point?: Point2D, duration?: number)',
|
|
35
|
+
description: 'Simulates long press on an element',
|
|
36
|
+
example: "await element(by.id('menuItem')).longPress();",
|
|
37
|
+
guidelines: ['If the target element is not accessible, interact with its container or the most relevant parent element.']
|
|
38
|
+
},
|
|
39
|
+
{
|
|
40
|
+
signature: 'typeText(text: string)',
|
|
41
|
+
description: 'Types text into a text field',
|
|
42
|
+
example: "await element(by.id('usernameInput')).typeText('myusername');",
|
|
43
|
+
guidelines: ['Typing can only be done on text field elements.']
|
|
44
|
+
},
|
|
45
|
+
{
|
|
46
|
+
signature: 'replaceText(text: string)',
|
|
47
|
+
description: 'Replaces text in a text field',
|
|
48
|
+
example: "await element(by.id('usernameInput')).replaceText('newusername');",
|
|
49
|
+
guidelines: ['Use this to replace existing text in a field.']
|
|
50
|
+
},
|
|
51
|
+
{
|
|
52
|
+
signature: 'clearText()',
|
|
53
|
+
description: 'Clears text from a text field',
|
|
54
|
+
example: "await element(by.id('usernameInput')).clearText();",
|
|
55
|
+
guidelines: ['Use this to clear existing text from a field.']
|
|
56
|
+
},
|
|
57
|
+
{
|
|
58
|
+
signature: 'scrollTo(edge: Direction, startPositionX?: number, startPositionY?: number)',
|
|
59
|
+
description: 'Scrolls to an edge',
|
|
60
|
+
example: "await element(by.id('scrollView')).scrollTo('bottom');",
|
|
61
|
+
guidelines: ['Scrolling must be done only on scroll-view elements.']
|
|
62
|
+
},
|
|
63
|
+
{
|
|
64
|
+
signature: 'scrollToIndex(index: Number)',
|
|
65
|
+
description: 'Scrolls to a specific index',
|
|
66
|
+
example: "await element(by.id('flatList')).scrollToIndex(5);",
|
|
67
|
+
guidelines: ['Use this for scrolling to a specific item in a list.']
|
|
68
|
+
},
|
|
69
|
+
{
|
|
70
|
+
signature: 'adjustSliderToPosition(newPosition: number)',
|
|
71
|
+
description: 'Adjusts slider to a position',
|
|
72
|
+
example: "await element(by.id('slider')).adjustSliderToPosition(0.75);",
|
|
73
|
+
guidelines: ['The position should be a number between 0 and 1.']
|
|
74
|
+
},
|
|
75
|
+
{
|
|
76
|
+
signature: 'setColumnToValue(column: number, value: string)',
|
|
77
|
+
description: 'Sets picker view column to a value (iOS only)',
|
|
78
|
+
example: "await element(by.id('datePicker')).setColumnToValue(1, '2023');",
|
|
79
|
+
guidelines: ['This is only available on iOS.']
|
|
80
|
+
},
|
|
81
|
+
{
|
|
82
|
+
signature: 'performAccessibilityAction(actionName: string)',
|
|
83
|
+
description: 'Triggers an accessibility action',
|
|
84
|
+
example: "await element(by.id('button')).performAccessibilityAction('longpress');",
|
|
85
|
+
guidelines: ['Use the provided value from the intent and do not change it.']
|
|
86
|
+
},
|
|
87
|
+
{
|
|
88
|
+
signature: 'swipe(direction: Direction, speed?: Speed, percentage?: number)',
|
|
89
|
+
description: 'Swipes in the specified direction',
|
|
90
|
+
example: "await element(by.id('card')).swipe('left', 'fast');",
|
|
91
|
+
guidelines: ['Use this for swiping gestures on elements.']
|
|
92
|
+
},
|
|
93
|
+
{
|
|
94
|
+
signature: 'pinch(scale: number, speed?: Speed, angle?: number)',
|
|
95
|
+
description: 'Performs a pinch gesture (iOS only)',
|
|
96
|
+
example: "await element(by.id('image')).pinch(0.5);",
|
|
97
|
+
guidelines: ['This is only available on iOS. Scale < 1 zooms out, scale > 1 zooms in.']
|
|
98
|
+
}
|
|
99
|
+
],
|
|
100
|
+
assertions: [
|
|
101
|
+
{
|
|
102
|
+
signature: 'toBeVisible()',
|
|
103
|
+
description: 'Asserts that the element is visible',
|
|
104
|
+
example: "await expect(element(by.id('loginButton'))).toBeVisible();",
|
|
105
|
+
guidelines: ['Use this to check if an element is visible on the screen.']
|
|
106
|
+
},
|
|
107
|
+
{
|
|
108
|
+
signature: 'toExist()',
|
|
109
|
+
description: 'Asserts that the element exists',
|
|
110
|
+
example: "await expect(element(by.id('username'))).toExist();",
|
|
111
|
+
guidelines: ['Use this to check if an element exists in the hierarchy, even if not visible.']
|
|
112
|
+
},
|
|
113
|
+
{
|
|
114
|
+
signature: 'toHaveText(text: string)',
|
|
115
|
+
description: 'Asserts that the element has the specified text',
|
|
116
|
+
example: "await expect(element(by.id('label'))).toHaveText('Hello, World!');",
|
|
117
|
+
guidelines: ['Use this to check the text content of an element.']
|
|
118
|
+
},
|
|
119
|
+
{
|
|
120
|
+
signature: 'toHaveValue(value: string)',
|
|
121
|
+
description: 'Asserts that the element has the specified value',
|
|
122
|
+
example: "await expect(element(by.id('slider'))).toHaveValue('0.5');",
|
|
123
|
+
guidelines: ['Use this to check the value of an element.']
|
|
124
|
+
}
|
|
125
|
+
]
|
|
126
|
+
};
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
async captureSnapshotImage() {
|
|
130
|
+
const fileName = `snapshot_${Date.now()}.png`;
|
|
131
|
+
await device.takeScreenshot(fileName);
|
|
132
|
+
return fileName;
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
async captureViewHierarchyString() {
|
|
136
|
+
return device.generateViewHierarchyXml();
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
module.exports = DetoxDriver;
|
|
@@ -20,6 +20,7 @@ class RuntimeDevice {
|
|
|
20
20
|
'clearKeychain',
|
|
21
21
|
'disableSynchronization',
|
|
22
22
|
'enableSynchronization',
|
|
23
|
+
'generateViewHierarchyXml',
|
|
23
24
|
'installApp',
|
|
24
25
|
'installUtilBinaries',
|
|
25
26
|
'launchApp',
|
|
@@ -195,6 +196,10 @@ class RuntimeDevice {
|
|
|
195
196
|
return this.deviceDriver.captureViewHierarchy(name);
|
|
196
197
|
}
|
|
197
198
|
|
|
199
|
+
async generateViewHierarchyXml(shouldInjectTestIds = false) {
|
|
200
|
+
return await this.deviceDriver.generateViewHierarchyXml(shouldInjectTestIds);
|
|
201
|
+
}
|
|
202
|
+
|
|
198
203
|
async sendToHome() {
|
|
199
204
|
await this.deviceDriver.sendToHome();
|
|
200
205
|
await this.deviceDriver.waitForBackground();
|
|
@@ -245,6 +245,11 @@ class AndroidDriver extends DeviceDriverBase {
|
|
|
245
245
|
await this.invocationManager.execute(call);
|
|
246
246
|
}
|
|
247
247
|
|
|
248
|
+
async generateViewHierarchyXml(shouldInjectTestIds) {
|
|
249
|
+
const hierarchy = await this.invocationManager.execute(DetoxApi.generateViewHierarchyXml(shouldInjectTestIds));
|
|
250
|
+
return hierarchy.result;
|
|
251
|
+
}
|
|
252
|
+
|
|
248
253
|
_getAppInstallPaths(_appBinaryPath, _testBinaryPath) {
|
|
249
254
|
const appBinaryPath = getAbsoluteBinaryPath(_appBinaryPath);
|
|
250
255
|
const testBinaryPath = _testBinaryPath ? getAbsoluteBinaryPath(_testBinaryPath) : this._getTestApkPath(appBinaryPath);
|
|
@@ -194,6 +194,10 @@ class SimulatorDriver extends IosDriver {
|
|
|
194
194
|
return viewHierarchyURL;
|
|
195
195
|
}
|
|
196
196
|
|
|
197
|
+
async generateViewHierarchyXml(shouldInjectTestIds) {
|
|
198
|
+
return await this.client.generateViewHierarchyXml({ shouldInjectTestIds });
|
|
199
|
+
}
|
|
200
|
+
|
|
197
201
|
async setStatusBar(flags) {
|
|
198
202
|
await this._applesimutils.statusBarOverride(this.udid, flags);
|
|
199
203
|
}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
94c7ef8a28dc964b657eea2fe3b976a0
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
b7253a70da80514f9fb458066ba45f5aeda16686
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
21b3215e69149679168a08bfa855a0089455f54ba9ab883ef1b268c001ce2216
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
a119637d941ad18e51e753ea1ee6a3cd6d068166cafb54cb0474373f48e84647875c742c4c54670af01f8d3f055c3e1907945b8811c5c1206aec0152c4186460
|
|
Binary file
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
f8f2a2bd622fadc1baf0d5be4f21622f
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
3ce2c636fb75e7758525c444e9b19f7a69ff7aa2
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
b6d5ba6221494632ff63d50785be381add4d688d167e1696d3f027d76a768042
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
0b22922e5fb5f7c8d8851661cf96982870f7a942939f5648ad4f72da1711515be0a6198fd9d789c2d45deedb0129452a6167f7068ab68b92c39d890fd2e467aa
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
48e491ac5e2166bc14b836ac291d9a10
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
874588e8c8d28d2cf1ef211ece43cb92dd4dd0ba
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
69b0bb114b00a7419670658bc0326c64dde8b2b4a4ec49c540de1f9186d8c324
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
472e53824831f47311d2848f3b6093d269f5dab58e01bded5ce08b3421e80916336d4f5001e8b9e1409b1a1e214023fc62de45d46931647aaee268af3c858947
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
208d53855f5405b6ca2ec1a57b08aa8a
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
4039b32649b959622a11f2da5640e3cd05d257da
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
1f35717c6a33f825af51b62048b2d63c8a8f9d1de927f8226af66b33f38ee0ea
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
2ffecf597779fcbe167e95d8bd43ae895f3484fe4f755624894f1be22e840242b8d6a57edb20996d36276757ea11a41c22cc892517e3a70a5f6952726b6c7032
|
|
Binary file
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
d271489c0570c8529c634b79843bc0a0
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
e0bceb0063fccfb5b5a0c173587a33720eca9d8d
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
328f2d83c0c54a3ac3e8cc0aadadd27f622c79d5c6f4490c2852ca8ef5f76b8f
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
22fe1aa0a7686ab99c4c5cb81bbf8c16e35c79039fc2dc070c9c6c14687042cd3182cc554ee0da4c48b5ec8330fa98b9887a8e7cf06f04c66f30612e919cbc2a
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
3e46d6dfb8ac381ce01685ebc04694e4
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
08e1e7773a8fb58ce4acac2310157b186767b361
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
29a7dee48d0b9f065ae740b3da5e2b5f57d208ac7ad856947f8b94db980d431a
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
ad4d04e5db6c1f7d4430107cdbf7a52c3f9da6e5b53c3111288bf328ea8c0598a9fc481681781a7119994457bc0a1ff3968b5fdf38d5d1a36e40363be4cbbbe7
|