detox 20.27.3 → 20.27.4
Sign up to get free protection for your applications and to get access to all the features.
- package/Detox-android/com/wix/detox/{20.27.3/detox-20.27.3-sources.jar → 20.27.4/detox-20.27.4-sources.jar} +0 -0
- package/Detox-android/com/wix/detox/20.27.4/detox-20.27.4-sources.jar.md5 +1 -0
- package/Detox-android/com/wix/detox/20.27.4/detox-20.27.4-sources.jar.sha1 +1 -0
- package/Detox-android/com/wix/detox/20.27.4/detox-20.27.4-sources.jar.sha256 +1 -0
- package/Detox-android/com/wix/detox/20.27.4/detox-20.27.4-sources.jar.sha512 +1 -0
- package/Detox-android/com/wix/detox/20.27.4/detox-20.27.4.aar +0 -0
- package/Detox-android/com/wix/detox/20.27.4/detox-20.27.4.aar.md5 +1 -0
- package/Detox-android/com/wix/detox/20.27.4/detox-20.27.4.aar.sha1 +1 -0
- package/Detox-android/com/wix/detox/20.27.4/detox-20.27.4.aar.sha256 +1 -0
- package/Detox-android/com/wix/detox/20.27.4/detox-20.27.4.aar.sha512 +1 -0
- package/Detox-android/com/wix/detox/{20.27.3/detox-20.27.3.pom → 20.27.4/detox-20.27.4.pom} +1 -1
- package/Detox-android/com/wix/detox/20.27.4/detox-20.27.4.pom.md5 +1 -0
- package/Detox-android/com/wix/detox/20.27.4/detox-20.27.4.pom.sha1 +1 -0
- package/Detox-android/com/wix/detox/20.27.4/detox-20.27.4.pom.sha256 +1 -0
- package/Detox-android/com/wix/detox/20.27.4/detox-20.27.4.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.27.3/detox-legacy-20.27.3-sources.jar → 20.27.4/detox-legacy-20.27.4-sources.jar} +0 -0
- package/Detox-android/com/wix/detox-legacy/20.27.4/detox-legacy-20.27.4-sources.jar.md5 +1 -0
- package/Detox-android/com/wix/detox-legacy/20.27.4/detox-legacy-20.27.4-sources.jar.sha1 +1 -0
- package/Detox-android/com/wix/detox-legacy/20.27.4/detox-legacy-20.27.4-sources.jar.sha256 +1 -0
- package/Detox-android/com/wix/detox-legacy/20.27.4/detox-legacy-20.27.4-sources.jar.sha512 +1 -0
- package/Detox-android/com/wix/detox-legacy/20.27.4/detox-legacy-20.27.4.aar +0 -0
- package/Detox-android/com/wix/detox-legacy/20.27.4/detox-legacy-20.27.4.aar.md5 +1 -0
- package/Detox-android/com/wix/detox-legacy/20.27.4/detox-legacy-20.27.4.aar.sha1 +1 -0
- package/Detox-android/com/wix/detox-legacy/20.27.4/detox-legacy-20.27.4.aar.sha256 +1 -0
- package/Detox-android/com/wix/detox-legacy/20.27.4/detox-legacy-20.27.4.aar.sha512 +1 -0
- package/Detox-android/com/wix/detox-legacy/{20.27.3/detox-legacy-20.27.3.pom → 20.27.4/detox-legacy-20.27.4.pom} +1 -1
- package/Detox-android/com/wix/detox-legacy/20.27.4/detox-legacy-20.27.4.pom.md5 +1 -0
- package/Detox-android/com/wix/detox-legacy/20.27.4/detox-legacy-20.27.4.pom.sha1 +1 -0
- package/Detox-android/com/wix/detox-legacy/20.27.4/detox-legacy-20.27.4.pom.sha256 +1 -0
- package/Detox-android/com/wix/detox-legacy/20.27.4/detox-legacy-20.27.4.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/src/full/java/com/wix/detox/espresso/hierarchy/ViewHierarchyGenerator.kt +3 -3
- package/package.json +3 -3
- package/src/copilot/detoxCopilotFrameworkDriver.js +122 -91
- package/Detox-android/com/wix/detox/20.27.3/detox-20.27.3-sources.jar.md5 +0 -1
- package/Detox-android/com/wix/detox/20.27.3/detox-20.27.3-sources.jar.sha1 +0 -1
- package/Detox-android/com/wix/detox/20.27.3/detox-20.27.3-sources.jar.sha256 +0 -1
- package/Detox-android/com/wix/detox/20.27.3/detox-20.27.3-sources.jar.sha512 +0 -1
- package/Detox-android/com/wix/detox/20.27.3/detox-20.27.3.aar +0 -0
- package/Detox-android/com/wix/detox/20.27.3/detox-20.27.3.aar.md5 +0 -1
- package/Detox-android/com/wix/detox/20.27.3/detox-20.27.3.aar.sha1 +0 -1
- package/Detox-android/com/wix/detox/20.27.3/detox-20.27.3.aar.sha256 +0 -1
- package/Detox-android/com/wix/detox/20.27.3/detox-20.27.3.aar.sha512 +0 -1
- package/Detox-android/com/wix/detox/20.27.3/detox-20.27.3.pom.md5 +0 -1
- package/Detox-android/com/wix/detox/20.27.3/detox-20.27.3.pom.sha1 +0 -1
- package/Detox-android/com/wix/detox/20.27.3/detox-20.27.3.pom.sha256 +0 -1
- package/Detox-android/com/wix/detox/20.27.3/detox-20.27.3.pom.sha512 +0 -1
- package/Detox-android/com/wix/detox-legacy/20.27.3/detox-legacy-20.27.3-sources.jar.md5 +0 -1
- package/Detox-android/com/wix/detox-legacy/20.27.3/detox-legacy-20.27.3-sources.jar.sha1 +0 -1
- package/Detox-android/com/wix/detox-legacy/20.27.3/detox-legacy-20.27.3-sources.jar.sha256 +0 -1
- package/Detox-android/com/wix/detox-legacy/20.27.3/detox-legacy-20.27.3-sources.jar.sha512 +0 -1
- package/Detox-android/com/wix/detox-legacy/20.27.3/detox-legacy-20.27.3.aar +0 -0
- package/Detox-android/com/wix/detox-legacy/20.27.3/detox-legacy-20.27.3.aar.md5 +0 -1
- package/Detox-android/com/wix/detox-legacy/20.27.3/detox-legacy-20.27.3.aar.sha1 +0 -1
- package/Detox-android/com/wix/detox-legacy/20.27.3/detox-legacy-20.27.3.aar.sha256 +0 -1
- package/Detox-android/com/wix/detox-legacy/20.27.3/detox-legacy-20.27.3.aar.sha512 +0 -1
- package/Detox-android/com/wix/detox-legacy/20.27.3/detox-legacy-20.27.3.pom.md5 +0 -1
- package/Detox-android/com/wix/detox-legacy/20.27.3/detox-legacy-20.27.3.pom.sha1 +0 -1
- package/Detox-android/com/wix/detox-legacy/20.27.3/detox-legacy-20.27.3.pom.sha256 +0 -1
- package/Detox-android/com/wix/detox-legacy/20.27.3/detox-legacy-20.27.3.pom.sha512 +0 -1
Binary file
|
@@ -0,0 +1 @@
|
|
1
|
+
9ace4a96235511950308086f1d57d806
|
@@ -0,0 +1 @@
|
|
1
|
+
22cc9e5934c1c0ba48217d81dc0a0403d6383378
|
@@ -0,0 +1 @@
|
|
1
|
+
c4f49a1754ae4e50e6a32cd8f22a51cb920e2a58b8e9da6a5d443aa6715a59f5
|
@@ -0,0 +1 @@
|
|
1
|
+
503797c9ab31332033756727a60af64c7797d51b731d88e6e841cba4c477f68ed1df2872602097587c91c5b357377007e7c9cb7e4f2b838172d1f99af52b5334
|
Binary file
|
@@ -0,0 +1 @@
|
|
1
|
+
05c87fc838b557d8c9537d4f432a9033
|
@@ -0,0 +1 @@
|
|
1
|
+
acc5c69d438baaadcfe97fa1f168e2799c3ce03a
|
@@ -0,0 +1 @@
|
|
1
|
+
9b9bb763d1adae07410c1057e4212277e5d1e3342afd286fbccd623511f86ce9
|
@@ -0,0 +1 @@
|
|
1
|
+
507cda9204d0726835db6d44cb80d23dd7fe4765c9b6387e635c1ad9cf8849e5d3d799100796106e7fcdd7fe4b4adb6aeb582aaccbf1db85639ae6b81e8b552e
|
@@ -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.27.
|
6
|
+
<version>20.27.4</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
|
+
69801cb935f0a63f247f867c28709f8d
|
@@ -0,0 +1 @@
|
|
1
|
+
9605245c61fd0ea528dd0cd2eda73ac0866ba25f
|
@@ -0,0 +1 @@
|
|
1
|
+
69e7b3363b16f075838fe56272dd13fd089b4d9b344ab4d4456a91d9444e0bbb
|
@@ -0,0 +1 @@
|
|
1
|
+
9f3223915c0899fed72f86c5781ee7c1f6f9737f0a016224582372e7b5f29ec6672fd943163717465549159f3f75a11a2ee6eca488589b97bc29775c3cbc3fe5
|
@@ -3,11 +3,11 @@
|
|
3
3
|
<groupId>com.wix</groupId>
|
4
4
|
<artifactId>detox</artifactId>
|
5
5
|
<versioning>
|
6
|
-
<latest>20.27.
|
7
|
-
<release>20.27.
|
6
|
+
<latest>20.27.4</latest>
|
7
|
+
<release>20.27.4</release>
|
8
8
|
<versions>
|
9
|
-
<version>20.27.
|
9
|
+
<version>20.27.4</version>
|
10
10
|
</versions>
|
11
|
-
<lastUpdated>
|
11
|
+
<lastUpdated>20241019191347</lastUpdated>
|
12
12
|
</versioning>
|
13
13
|
</metadata>
|
@@ -1 +1 @@
|
|
1
|
-
|
1
|
+
4e15390d4670f66357943485fa05acea
|
@@ -1 +1 @@
|
|
1
|
-
|
1
|
+
3475202451a2cb5e3534b59b14612e32df033626
|
@@ -1 +1 @@
|
|
1
|
-
|
1
|
+
d1b63410f852b05d5e00c1a0358fd61afe51474be017e2e78fef15e30cb09d44
|
@@ -1 +1 @@
|
|
1
|
-
|
1
|
+
8b1cc9ffb3d076da45ed87bbaa606ccd89be6fc53dd5e57e8f3d3be5ed09eece128d7cbe4f398606441c1f837cf07268e0a35071c90894c2bd0f5f259b8865c7
|
Binary file
|
@@ -0,0 +1 @@
|
|
1
|
+
11e61e70a680b35bc8433c99dbe93fa7
|
@@ -0,0 +1 @@
|
|
1
|
+
461391ec015ccc3107d8d1d1f4f90fdef1e89d4d
|
@@ -0,0 +1 @@
|
|
1
|
+
37d6621cb43970a45655c142a2d3f87202228010f48c9359b1608f968fc29965
|
@@ -0,0 +1 @@
|
|
1
|
+
f21f72c93ca515baebf73681a7406d25682550f537943a6f7b3933ba0bc318a3c83a243e7c7ac45372deb363a7dce7396132e101545a586c7b23ecaa6d3606e4
|
@@ -0,0 +1 @@
|
|
1
|
+
af13b71ab208d17b33c1fc7a1ef4e529
|
@@ -0,0 +1 @@
|
|
1
|
+
47dca63caffe4427b6fec3ab51e13ade0e234e6d
|
@@ -0,0 +1 @@
|
|
1
|
+
22561e652905451c48ffb378b015ae046634e2efea239e6f08875ccbd179db3e
|
@@ -0,0 +1 @@
|
|
1
|
+
46aa7c047bc8cbe7ad61270652a5bcc88955545e33c6d8338a9cc610e157d5cf6b2ecea224bacdb13cffc027d92617abecf0d1faa7eb89fb5b8c10cd7c410eb1
|
@@ -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.27.
|
6
|
+
<version>20.27.4</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
|
+
07b3035704b21925bce075aa8ceaa610
|
@@ -0,0 +1 @@
|
|
1
|
+
5369c9600c539c3142ab367ea81df17920762e86
|
@@ -0,0 +1 @@
|
|
1
|
+
675cf33b02458dfa9d2c997a5d51f70a138d6e05cc2a1794c530ded4be481f48
|
@@ -0,0 +1 @@
|
|
1
|
+
8f6bf9c98b0d80bec51af79d562411dc85ac6fb11ee7cb952f1875abd43ac73df3ffb90dc426485fe8e21dc0200b27a0ad646fbc8edc89576502690eaa817ca3
|
@@ -3,11 +3,11 @@
|
|
3
3
|
<groupId>com.wix</groupId>
|
4
4
|
<artifactId>detox-legacy</artifactId>
|
5
5
|
<versioning>
|
6
|
-
<latest>20.27.
|
7
|
-
<release>20.27.
|
6
|
+
<latest>20.27.4</latest>
|
7
|
+
<release>20.27.4</release>
|
8
8
|
<versions>
|
9
|
-
<version>20.27.
|
9
|
+
<version>20.27.4</version>
|
10
10
|
</versions>
|
11
|
-
<lastUpdated>
|
11
|
+
<lastUpdated>20241019191405</lastUpdated>
|
12
12
|
</versioning>
|
13
13
|
</metadata>
|
@@ -1 +1 @@
|
|
1
|
-
|
1
|
+
06da87cac17d41b217b1204e3baac71c
|
@@ -1 +1 @@
|
|
1
|
-
|
1
|
+
3260642fbd27ef17b3f677a27b9060f29ecddd68
|
@@ -1 +1 @@
|
|
1
|
-
|
1
|
+
7aaa8a6d2ea4aed57f4c789a4d2229070c7619b8466e959fe73d930c6d2f09c5
|
@@ -1 +1 @@
|
|
1
|
-
|
1
|
+
437e4f341f9a2a317ff3fc9c8ad606d36974f884172e105b36c2eb256d3245791fc0dabad87c8c23ea76fc9995528af1b6d6b9a5a28f389afe158b0d8318e6da
|
package/Detox-ios-framework.tbz
CHANGED
Binary file
|
package/Detox-ios-src.tbz
CHANGED
Binary file
|
package/Detox-ios-xcuitest.tbz
CHANGED
Binary file
|
package/android/detox/src/full/java/com/wix/detox/espresso/hierarchy/ViewHierarchyGenerator.kt
CHANGED
@@ -16,10 +16,10 @@ import kotlin.coroutines.resume
|
|
16
16
|
|
17
17
|
|
18
18
|
private const val GET_HTML_SCRIPT = """
|
19
|
+
(function() {
|
19
20
|
const blacklistedTags = ['script', 'style', 'head', 'meta'];
|
20
21
|
const blackListedTagsSelector = blacklistedTags.join(',');
|
21
22
|
|
22
|
-
(function() {
|
23
23
|
// Clone the entire document
|
24
24
|
var clonedDoc = document.documentElement.cloneNode(true);
|
25
25
|
|
@@ -170,9 +170,9 @@ object ViewHierarchyGenerator {
|
|
170
170
|
if (shouldInjectNewTestId) {
|
171
171
|
val newTestId = "${injectedPrefix}${indexPath.joinToString("_")}"
|
172
172
|
view.tag = newTestId
|
173
|
-
attributes["
|
173
|
+
attributes["id"] = newTestId
|
174
174
|
} else {
|
175
|
-
attributes["
|
175
|
+
attributes["id"] = currentTestId
|
176
176
|
}
|
177
177
|
|
178
178
|
attributes
|
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.27.
|
4
|
+
"version": "20.27.4",
|
5
5
|
"bin": {
|
6
6
|
"detox": "local-cli/cli.js"
|
7
7
|
},
|
@@ -71,7 +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.
|
74
|
+
"detox-copilot": "^0.0.23",
|
75
75
|
"execa": "^5.1.1",
|
76
76
|
"find-up": "^5.0.0",
|
77
77
|
"fs-extra": "^11.0.0",
|
@@ -116,5 +116,5 @@
|
|
116
116
|
"browserslist": [
|
117
117
|
"node 14"
|
118
118
|
],
|
119
|
-
"gitHead": "
|
119
|
+
"gitHead": "74a2c1426616e4e65fa830b9b98689e18a0677e3"
|
120
120
|
}
|
@@ -106,7 +106,7 @@ const detoxCopilotFrameworkDriver = {
|
|
106
106
|
],
|
107
107
|
},
|
108
108
|
{
|
109
|
-
signature: 'whileElement(element: Matcher)',
|
109
|
+
signature: 'waitFor(element: Matcher)..toBeVisible().whileElement(element: Matcher).scroll(offset: number, direction: string)',
|
110
110
|
description: 'Continuously performs an action while waiting for an expectation to be fulfilled.',
|
111
111
|
example: `
|
112
112
|
await waitFor(element(by.text('Load More')))
|
@@ -335,14 +335,20 @@ await device.launchApp({ launchArgs: { someLaunchArg: 1234 } });`,
|
|
335
335
|
example: "system.element(by.system.label('Allow')).tap();",
|
336
336
|
guidelines: [
|
337
337
|
'Can be used for iOS system alerts and permissions dialogs',
|
338
|
+
'Always use `system.element()` to interact with system dialog elements (alerts, permission requests).',
|
338
339
|
'Check the platform with `device.getPlatform()` before using, as it is iOS-specific',
|
340
|
+
'Permission alerts are part of the system UI, not the app UI. Therefore should be matched with `system.element()`.',
|
339
341
|
'System dialogs are not part of the app, so they won\'t be found in the app\'s view hierarchy. Identify the relevant system element from the snapshot.',
|
340
342
|
]
|
341
343
|
},
|
342
344
|
{
|
343
345
|
signature: 'by.system.label(label: string)',
|
344
|
-
description: 'Matches system elements by label.',
|
346
|
+
description: 'Matches system elements by their label (text).',
|
345
347
|
example: "system.element(by.system.label('Dismiss'));",
|
348
|
+
guidelines: [
|
349
|
+
'System elements will not be found in the app\'s view hierarchy. Read the text from the snapshot.',
|
350
|
+
'If no system dialog can be found, throw an error with the relevant message.',
|
351
|
+
],
|
346
352
|
},
|
347
353
|
{
|
348
354
|
signature: 'by.system.type(type: string)',
|
@@ -357,12 +363,12 @@ await device.launchApp({ launchArgs: { someLaunchArg: 1234 } });`,
|
|
357
363
|
{
|
358
364
|
signature: 'toExist()',
|
359
365
|
description: 'Asserts that the system element exists.',
|
360
|
-
example: "await system.element(by.system.label('Allow')).toExist();",
|
366
|
+
example: "await expect(system.element(by.system.label('Allow'))).toExist();",
|
361
367
|
},
|
362
368
|
{
|
363
369
|
signature: 'not',
|
364
370
|
description: 'Negates the expectation for system elements.',
|
365
|
-
example: "await system.element(by.system.label('Allow')).not.toExist();",
|
371
|
+
example: "await expect(system.element(by.system.label('Allow'))).not.toExist();",
|
366
372
|
},
|
367
373
|
],
|
368
374
|
},
|
@@ -372,99 +378,121 @@ await device.launchApp({ launchArgs: { someLaunchArg: 1234 } });`,
|
|
372
378
|
{
|
373
379
|
signature: 'web.element(matcher: Matcher)',
|
374
380
|
description: 'Selects an element within a web view. Use when there is only one web view on the screen.',
|
375
|
-
example:
|
381
|
+
example: `
|
382
|
+
await web.element(by.web.id('email')).typeText('test@example.com');
|
383
|
+
await web.element(by.web.id('password')).typeText('password123');
|
384
|
+
await web.element(by.web.id('login-button')).tap();
|
385
|
+
`,
|
376
386
|
guidelines: [
|
377
|
-
'
|
378
|
-
'
|
379
|
-
'
|
387
|
+
'The web view may take time to load; add a delay using `await new Promise(resolve => setTimeout(resolve, milliseconds));` before the first interaction. This wait should happen only once.',
|
388
|
+
'After the initial wait, you can interact with web elements without additional delays.',
|
389
|
+
'Use `by.web.id` matcher when possible for matching web elements, as it is the most reliable.',
|
390
|
+
'Web APIs can only be used with web elements (within web views). Avoid using web APIs for native elements or native APIs for web elements.',
|
380
391
|
],
|
381
392
|
},
|
382
393
|
{
|
383
|
-
signature: 'web(nativeMatcher).element(matcher: Matcher)',
|
394
|
+
signature: 'web(nativeMatcher: NativeMatcher).element(matcher: Matcher)',
|
384
395
|
description: 'Selects an element within a specific web view matched by a native matcher. Use when there are multiple web views on the screen.',
|
385
|
-
example:
|
396
|
+
example: `
|
397
|
+
// Wait for the specific web view to appear and load (only once before interacting)
|
398
|
+
await expect(element(by.id('checkout-webview'))).toBeVisible();
|
399
|
+
|
400
|
+
// Interact with elements within a specific web view
|
401
|
+
const specificWebView = web(by.id('checkout-webview'));
|
402
|
+
|
403
|
+
await specificWebView.element(by.web.id('credit-card-number')).typeText('4111111111111111');
|
404
|
+
await specificWebView.element(by.web.id('expiration-date')).typeText('12/25');
|
405
|
+
await specificWebView.element(by.web.id('cvv')).typeText('123');
|
406
|
+
await specificWebView.element(by.web.id('pay-button')).tap();
|
407
|
+
`,
|
386
408
|
guidelines: [
|
387
409
|
'Use this method when multiple web views are present.',
|
388
|
-
'
|
410
|
+
'Ensure the web view is visible and its content is loaded before interacting. This wait should happen only once.',
|
411
|
+
'After the initial wait, you can interact with elements within the web view without additional delays.',
|
412
|
+
'Webview must be matched with `web(nativeMatcher)` (e.g., `web(by.id(..))` instead of `element(by.id(..))`).',
|
413
|
+
'Prefer the basic `web.element()` if only one web view is present on the screen.',
|
389
414
|
],
|
390
415
|
},
|
391
416
|
{
|
392
|
-
signature: 'web(nativeMatcher).atIndex(index: number).element(matcher: Matcher)',
|
417
|
+
signature: 'web(nativeMatcher: NativeMatcher).atIndex(index: number).element(matcher: Matcher)',
|
393
418
|
description: 'Selects an element within a specific web view at a given index (iOS only).',
|
394
|
-
example:
|
419
|
+
example: `
|
420
|
+
// Interact with an element within the second web view (index starts from 0)
|
421
|
+
const secondWebView = web(by.id('webview')).atIndex(1);
|
422
|
+
await secondWebView.element(by.web.id('search-input')).typeText('Detox Testing');
|
423
|
+
await secondWebView.element(by.web.id('search-button')).tap();
|
424
|
+
`,
|
395
425
|
guidelines: [
|
396
426
|
'Use when multiple web views with the same identifier are present on iOS.',
|
397
|
-
'This
|
427
|
+
'This method is available for iOS only.',
|
398
428
|
'Check the platform with `device.getPlatform()` before using.',
|
399
429
|
],
|
400
430
|
},
|
401
431
|
{
|
402
432
|
signature: 'by.web.id(id: string)',
|
403
|
-
description: 'Matches web elements by their
|
404
|
-
example:
|
433
|
+
description: 'Matches web elements by their "id" attribute.',
|
434
|
+
example: `await web.element(by.web.id('search')).tap();`,
|
405
435
|
guidelines: [
|
406
|
-
'
|
407
|
-
'This is the best-practice matcher for web elements.',
|
436
|
+
'Prefer `by.web.id` over any other matchers when available.',
|
408
437
|
],
|
409
438
|
},
|
410
439
|
{
|
411
440
|
signature: 'by.web.className(className: string)',
|
412
441
|
description: 'Matches web elements by their CSS class name.',
|
413
|
-
example:
|
442
|
+
example: `await web.element(by.web.className('btn-login')).tap();`,
|
414
443
|
},
|
415
444
|
{
|
416
445
|
signature: 'by.web.cssSelector(cssSelector: string)',
|
417
446
|
description: 'Matches web elements using a CSS selector.',
|
418
|
-
example:
|
447
|
+
example: `await web.element(by.web.cssSelector('#product-list .product-item[data-id="123"]')).scrollToView();`,
|
419
448
|
},
|
420
449
|
{
|
421
450
|
signature: 'by.web.name(name: string)',
|
422
451
|
description: 'Matches web elements by their name attribute.',
|
423
|
-
example:
|
452
|
+
example: `await web.element(by.web.name('firstName')).typeText('John');`,
|
424
453
|
},
|
425
454
|
{
|
426
455
|
signature: 'by.web.xpath(xpath: string)',
|
427
456
|
description: 'Matches web elements using an XPath expression.',
|
428
|
-
example:
|
429
|
-
guidelines: [
|
430
|
-
'Use when `by.web.id` is not available.',
|
431
|
-
'XPath matchers can be less performant.',
|
432
|
-
],
|
457
|
+
example: `await web.element(by.web.xpath('//button[text()="Continue"]')).tap();`,
|
433
458
|
},
|
434
459
|
{
|
435
460
|
signature: 'by.web.href(href: string)',
|
436
461
|
description: 'Matches web elements by their href attribute.',
|
437
|
-
example:
|
462
|
+
example: `await web.element(by.web.href('https://www.example.com/contact')).tap();`,
|
438
463
|
},
|
439
464
|
{
|
440
465
|
signature: 'by.web.hrefContains(href: string)',
|
441
466
|
description: 'Matches web elements whose href attribute contains the specified string.',
|
442
|
-
example:
|
467
|
+
example: `await web.element(by.web.hrefContains('/about')).tap();`,
|
443
468
|
},
|
444
469
|
{
|
445
470
|
signature: 'by.web.tag(tag: string)',
|
446
471
|
description: 'Matches web elements by their tag name.',
|
447
|
-
example:
|
472
|
+
example: `await expect(web.element(by.web.tag('h1'))).toHaveText('Welcome to Our Site');`,
|
448
473
|
},
|
449
474
|
{
|
450
475
|
signature: 'by.web.value(value: string)',
|
451
476
|
description: 'Matches web elements by their value attribute (iOS only).',
|
452
|
-
example:
|
453
|
-
guidelines: [
|
477
|
+
example: `await web.element(by.web.value('Sign In')).tap();`,
|
478
|
+
guidelines: [
|
479
|
+
'Available on iOS only.',
|
480
|
+
],
|
454
481
|
},
|
455
482
|
{
|
456
483
|
signature: 'by.web.label(label: string)',
|
457
|
-
description: 'Matches web elements by their
|
458
|
-
example:
|
484
|
+
description: 'Matches web elements by their label (iOS only, supports `asSecured()`).',
|
485
|
+
example: `await web.element(by.web.label('Next')).tap();`,
|
459
486
|
guidelines: [
|
460
487
|
'Available on iOS only.',
|
461
|
-
'Use when the element has a unique label.',
|
488
|
+
'Use when the element has a unique label or aria-label.',
|
489
|
+
'Can be used to match buttons and input elements by their inner text content.',
|
462
490
|
],
|
463
491
|
},
|
464
492
|
{
|
465
493
|
signature: 'by.web.type(accessibilityType: string)',
|
466
|
-
description: 'Matches web elements by accessibility type (iOS only,
|
467
|
-
example:
|
494
|
+
description: 'Matches web elements by accessibility type (iOS only, `asSecured()` only).',
|
495
|
+
example: `await web.element(by.web.type('textField')).asSecured().typeText('Sample Text');`,
|
468
496
|
guidelines: [
|
469
497
|
'Available on iOS only and used with `asSecured()`.',
|
470
498
|
'Type can be any XCUIElement.ElementType, e.g., "button", "textField".',
|
@@ -473,163 +501,166 @@ await device.launchApp({ launchArgs: { someLaunchArg: 1234 } });`,
|
|
473
501
|
{
|
474
502
|
signature: 'atIndex(index: number)',
|
475
503
|
description: 'Selects the web element at the specified index from matched elements.',
|
476
|
-
example:
|
477
|
-
guidelines: [
|
504
|
+
example: `await expect(web.element(by.web.tag('h2')).atIndex(1)).toHaveText('Features');`,
|
505
|
+
guidelines: [
|
506
|
+
'Use when multiple web elements match the same matcher.',
|
507
|
+
],
|
478
508
|
},
|
479
509
|
{
|
480
510
|
signature: 'tap()',
|
481
511
|
description: 'Taps on a web element.',
|
482
|
-
example:
|
512
|
+
example: `await web.element(by.web.label('Submit')).tap();`,
|
483
513
|
guidelines: [
|
484
514
|
'Supports `asSecured()` on iOS.',
|
485
|
-
'Use `asSecured()` when interacting with secured web views.',
|
486
515
|
],
|
487
516
|
},
|
488
517
|
{
|
489
|
-
signature: 'typeText(text: string
|
518
|
+
signature: 'typeText(text: string)',
|
490
519
|
description: 'Types text into a web element.',
|
491
|
-
example:
|
520
|
+
example: `await web.element(by.web.id('rich-text-editor')).typeText('This is a test message');`,
|
492
521
|
guidelines: [
|
493
|
-
'Set `isContentEditable` to `true` for content-editable elements on Android.',
|
494
|
-
'On iOS, content-editable elements are automatically detected.',
|
495
522
|
'Supports `asSecured()` on iOS.',
|
496
523
|
],
|
497
524
|
},
|
498
525
|
{
|
499
526
|
signature: 'replaceText(text: string)',
|
500
527
|
description: 'Replaces text in a web element.',
|
501
|
-
example:
|
528
|
+
example: `await web.element(by.web.id('username')).replaceText('new_user');`,
|
502
529
|
guidelines: [
|
503
|
-
'Currently not supported for content-editable elements on Android.',
|
504
530
|
'Supports `asSecured()` on iOS.',
|
505
531
|
],
|
506
532
|
},
|
507
533
|
{
|
508
534
|
signature: 'clearText()',
|
509
535
|
description: 'Clears text from a web element.',
|
510
|
-
example:
|
536
|
+
example: `await web.element(by.web.id('comments')).clearText();`,
|
511
537
|
guidelines: [
|
512
|
-
'Currently not supported for content-editable elements on Android.',
|
513
538
|
'Supports `asSecured()` on iOS.',
|
514
539
|
],
|
515
540
|
},
|
516
541
|
{
|
517
542
|
signature: 'selectAllText()',
|
518
543
|
description: 'Selects all text in a web element.',
|
519
|
-
example:
|
520
|
-
guidelines: [
|
521
|
-
'Supported for content-editable elements only on Android.',
|
522
|
-
'On iOS, Detox can select all text of any element that supports it.',
|
523
|
-
],
|
544
|
+
example: `await web.element(by.web.id('notes')).selectAllText();`,
|
524
545
|
},
|
525
546
|
{
|
526
547
|
signature: 'getText()',
|
527
548
|
description: 'Retrieves the text content of a web element.',
|
528
549
|
example: `
|
529
|
-
const
|
530
|
-
jestExpect(
|
531
|
-
`,
|
550
|
+
const description = await web.element(by.web.id('product-description')).getText();
|
551
|
+
jestExpect(description).toContain('This product is made from the finest materials.');
|
552
|
+
`,
|
532
553
|
guidelines: [
|
533
554
|
'Use for assertions on the element\'s text content.',
|
534
|
-
'Requires importing `jestExpect` for assertions.',
|
535
555
|
],
|
536
556
|
},
|
537
557
|
{
|
538
558
|
signature: 'scrollToView()',
|
539
559
|
description: 'Scrolls the web view to bring the element into view.',
|
540
|
-
example:
|
560
|
+
example: `await web.element(by.web.id('contact-section')).scrollToView();`,
|
541
561
|
},
|
542
562
|
{
|
543
563
|
signature: 'focus()',
|
544
564
|
description: 'Focuses on a web element.',
|
545
|
-
example:
|
565
|
+
example: `
|
566
|
+
await web.element(by.web.id('email-input')).focus();
|
567
|
+
await web.element(by.web.id('email-input')).typeText('user@example.com');
|
568
|
+
`,
|
569
|
+
guidelines: [
|
570
|
+
'Useful for input fields that require focus before typing.',
|
571
|
+
'No need for secured interactions on iOS.',
|
572
|
+
]
|
546
573
|
},
|
547
574
|
{
|
548
575
|
signature: 'moveCursorToEnd()',
|
549
576
|
description: 'Moves the input cursor to the end of the element\'s content.',
|
550
|
-
example:
|
551
|
-
|
552
|
-
|
553
|
-
|
554
|
-
],
|
577
|
+
example: `
|
578
|
+
await web.element(by.web.id('message-box')).moveCursorToEnd();
|
579
|
+
await web.element(by.web.id('message-box')).typeText(' Adding more text.');
|
580
|
+
`,
|
555
581
|
},
|
556
582
|
{
|
557
583
|
signature: 'runScript(script: string, args?: any[])',
|
558
584
|
description: 'Runs a JavaScript function on the element.',
|
559
585
|
example: `
|
560
|
-
|
561
|
-
await
|
586
|
+
// Click an element using a custom script
|
587
|
+
await web.element(by.web.id('hidden-button')).runScript('el => el.click()');
|
562
588
|
|
563
|
-
//
|
564
|
-
await
|
589
|
+
// Set the value of an input field using a custom script
|
590
|
+
await web.element(by.web.id('username')).runScript('(el, args) => el.value = args[0]', ['new_user']);
|
565
591
|
|
566
|
-
//
|
567
|
-
const
|
568
|
-
return
|
592
|
+
// Get the color of an element
|
593
|
+
const color = await web.element(by.web.id('header')).runScript(function(el) {
|
594
|
+
return window.getComputedStyle(el).color;
|
569
595
|
});
|
570
|
-
jestExpect(
|
596
|
+
jestExpect(color).toBe('rgb(0, 0, 0)');
|
571
597
|
|
572
|
-
//
|
573
|
-
await
|
574
|
-
`,
|
598
|
+
// Scroll an element into view if not visible
|
599
|
+
await web.element(by.web.id('lazy-image')).runScript('el => el.scrollIntoView()');
|
600
|
+
`,
|
575
601
|
guidelines: [
|
576
602
|
'The script can accept additional arguments and return a value.',
|
577
603
|
'Ensure that arguments and return values are serializable.',
|
578
604
|
'Useful for custom interactions or retrieving properties.',
|
605
|
+
'Avoid using this method for simple interactions like tapping or typing.',
|
579
606
|
],
|
580
607
|
},
|
581
608
|
{
|
582
609
|
signature: 'getCurrentUrl()',
|
583
610
|
description: 'Retrieves the current URL of the web view.',
|
584
611
|
example: `
|
585
|
-
|
586
|
-
|
587
|
-
|
612
|
+
await web.element(by.web.id('link-to-page')).tap();
|
613
|
+
const currentUrl = await web.element(by.web.tag('body')).getCurrentUrl();
|
614
|
+
jestExpect(currentUrl).toBe('https://www.example.com/target-page');
|
615
|
+
`,
|
588
616
|
guidelines: [
|
589
617
|
'Must be called from an inner element, not the root web view.',
|
590
|
-
'May have issues on Android; check relevant GitHub issues.',
|
591
618
|
],
|
592
619
|
},
|
593
620
|
{
|
594
621
|
signature: 'getTitle()',
|
595
622
|
description: 'Retrieves the title of the web view.',
|
596
623
|
example: `
|
597
|
-
const
|
598
|
-
jestExpect(
|
599
|
-
`,
|
624
|
+
const pageTitle = await web.element(by.web.tag('body')).getTitle();
|
625
|
+
jestExpect(pageTitle).toBe('Dashboard - MyApp');
|
626
|
+
`,
|
600
627
|
guidelines: [
|
601
628
|
'Must be called from an inner element, not the root web view.',
|
602
629
|
],
|
603
630
|
},
|
604
631
|
{
|
605
632
|
signature: 'toHaveText(text: string)',
|
606
|
-
description: 'Asserts that the web element has the specified text.',
|
607
|
-
example:
|
633
|
+
description: 'Asserts that the web element has the specified text. Used with `expect()`.',
|
634
|
+
example: `await expect(web.element(by.web.name('submit-button'))).toHaveText('Submit');`,
|
635
|
+
guidelines: [
|
636
|
+
'For web views, the text is the inner text of the element, e.g., `<h1>Welcome to the webpage!</h1>`.',
|
637
|
+
],
|
608
638
|
},
|
609
639
|
{
|
610
640
|
signature: 'toExist()',
|
611
|
-
description: 'Asserts that the web element exists.',
|
612
|
-
example:
|
641
|
+
description: 'Asserts that the web element exists. Used with `expect()`.',
|
642
|
+
example: `await expect(web.element(by.web.id('error-message'))).toExist();`,
|
613
643
|
guidelines: [
|
644
|
+
'Verifies the presence of a web element in the DOM.',
|
614
645
|
'Supports `asSecured()` on iOS.',
|
615
646
|
],
|
616
647
|
},
|
617
648
|
{
|
618
649
|
signature: 'not',
|
619
650
|
description: 'Negates the expectation for web elements.',
|
620
|
-
example:
|
651
|
+
example: `await expect(web.element(by.web.id('loading-spinner'))).not.toExist();`,
|
621
652
|
guidelines: [
|
653
|
+
'Use `not` to assert that an element should not be present.',
|
622
654
|
'Supports `asSecured()` on iOS.',
|
623
655
|
],
|
624
656
|
},
|
625
657
|
{
|
626
658
|
signature: 'asSecured()',
|
627
659
|
description: 'Interacts with secured web views (iOS only).',
|
628
|
-
example:
|
660
|
+
example: `await web.element(by.web.label('Confirm')).asSecured().tap();`,
|
629
661
|
guidelines: [
|
630
662
|
'Use for web pages with secured protocols when regular interactions fail.',
|
631
|
-
'
|
632
|
-
'Less performant and has fewer APIs.',
|
663
|
+
'Applicable on iOS only with specific APIs.',
|
633
664
|
],
|
634
665
|
},
|
635
666
|
],
|
@@ -638,7 +669,7 @@ jestExpect(title).toBe('Welcome Page');
|
|
638
669
|
},
|
639
670
|
|
640
671
|
captureSnapshotImage: async function () {
|
641
|
-
|
672
|
+
const fileName = `snapshot_${Date.now()}.png`;
|
642
673
|
try {
|
643
674
|
return await detox.device.takeScreenshot(fileName);
|
644
675
|
} catch (_error) {
|
@@ -1 +0,0 @@
|
|
1
|
-
8cd2f48786d004ff90fcc48db9b9e69a
|
@@ -1 +0,0 @@
|
|
1
|
-
4afea56e335fc27ee2b92be48673dea8a05185aa
|
@@ -1 +0,0 @@
|
|
1
|
-
0568be3312760e3a3a4259cc771a7253074502547e8eb3350213cde9f8db6165
|
@@ -1 +0,0 @@
|
|
1
|
-
2287316f0b862561456bef92c561598fcff17e286f17bc262470ef25cc6f71e84b16a8058e37f7f1536fc3a0433df990ba20173dd132b4c561c71e62a07e2fe6
|
Binary file
|
@@ -1 +0,0 @@
|
|
1
|
-
14161501d9cf4606ee49296e14c047e4
|
@@ -1 +0,0 @@
|
|
1
|
-
38e956edb72453c00c00ab752443f394389737bf
|
@@ -1 +0,0 @@
|
|
1
|
-
0a76b1d5efeea5e83fa9e92e75bc29913b9e7db28b7b30652638966506299f90
|
@@ -1 +0,0 @@
|
|
1
|
-
f3b3510a065744da054200cbcfb62549d469aa27068939879f07c64421cfef223aa34ed6346b6e9c5839a1a42cdc76699b16ad4395545abfb01cd611381df408
|
@@ -1 +0,0 @@
|
|
1
|
-
2d7e0ca8745e2abb2087e946367c0538
|
@@ -1 +0,0 @@
|
|
1
|
-
071d2ecd2ac499ecef2bff9c5b3f830c613709ca
|
@@ -1 +0,0 @@
|
|
1
|
-
865a27d4ce918936ef0a629b2eb2c21dedc9e21629710732b2eb8ae9fd4374df
|
@@ -1 +0,0 @@
|
|
1
|
-
58f3c7bc9e6bbc5885f03460545c4832bab2c29490afcbc003d5ee0acb3cf6975f0d890292d4ac587d73c986a42e1c67624617f6fee6da9163ccf76ee5d730ab
|
@@ -1 +0,0 @@
|
|
1
|
-
b4efad81e134dacbb7d81b566aed6d89
|
@@ -1 +0,0 @@
|
|
1
|
-
e994e4dad3f2dce5f5fde279bc6cd917ee6b2f07
|
@@ -1 +0,0 @@
|
|
1
|
-
7e9153002e13fa5ffeef31eeda43b00e38bacbcba46640ce59fb42220a51c22a
|
@@ -1 +0,0 @@
|
|
1
|
-
818984bbddf7bf9561bc6bc9e646cb2f89d5cd83c863aef37c5bf1a3911d08c6a4dc04b8251a85208c7ae308b11e6970a94d33fb2293dbd8bf3c6df6cd55d3ab
|
Binary file
|
@@ -1 +0,0 @@
|
|
1
|
-
02d974914d78e64b365486e3369ae1e1
|
@@ -1 +0,0 @@
|
|
1
|
-
173b898bfecd41c34b0ad24d7e1996c8d3b0621b
|
@@ -1 +0,0 @@
|
|
1
|
-
8a30f740e17ad80816f17ceb61b354d7da12f651764e040ddf85b1c3609992a3
|
@@ -1 +0,0 @@
|
|
1
|
-
90f61852b868773b3548daf4c04793cc0285df750cbfb8947375ec81f5882469cf6e6132295e3b115b27d61733c1bb5f4954a14e7246aa8da19e97bd28191c5f
|
@@ -1 +0,0 @@
|
|
1
|
-
965972ea4b2739cb5d958a329b9bcc3d
|
@@ -1 +0,0 @@
|
|
1
|
-
b6d5cfb02046495791ca031d12b9f2310f799a0e
|
@@ -1 +0,0 @@
|
|
1
|
-
b27221155e7cfcfab8c62c949d47cd71967e19b243c001e53ac518e4cf900769
|
@@ -1 +0,0 @@
|
|
1
|
-
d9c28fba54e53d5546f30c9b43326175f6ac8cf3194a8d0faea4d97b487198eb994f06249994c579b0f82f7ab0c7685689fe605887668dc2eaa5e659892e388a
|