detox 20.27.2 → 20.27.3
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.2/detox-20.27.2-sources.jar → 20.27.3/detox-20.27.3-sources.jar} +0 -0
- package/Detox-android/com/wix/detox/20.27.3/detox-20.27.3-sources.jar.md5 +1 -0
- package/Detox-android/com/wix/detox/20.27.3/detox-20.27.3-sources.jar.sha1 +1 -0
- package/Detox-android/com/wix/detox/20.27.3/detox-20.27.3-sources.jar.sha256 +1 -0
- package/Detox-android/com/wix/detox/20.27.3/detox-20.27.3-sources.jar.sha512 +1 -0
- package/Detox-android/com/wix/detox/{20.27.2/detox-20.27.2.pom → 20.27.3/detox-20.27.3.pom} +1 -1
- package/Detox-android/com/wix/detox/20.27.3/detox-20.27.3.pom.md5 +1 -0
- package/Detox-android/com/wix/detox/20.27.3/detox-20.27.3.pom.sha1 +1 -0
- package/Detox-android/com/wix/detox/20.27.3/detox-20.27.3.pom.sha256 +1 -0
- package/Detox-android/com/wix/detox/20.27.3/detox-20.27.3.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.2/detox-legacy-20.27.2-sources.jar → 20.27.3/detox-legacy-20.27.3-sources.jar} +0 -0
- package/Detox-android/com/wix/detox-legacy/20.27.3/detox-legacy-20.27.3-sources.jar.md5 +1 -0
- package/Detox-android/com/wix/detox-legacy/20.27.3/detox-legacy-20.27.3-sources.jar.sha1 +1 -0
- package/Detox-android/com/wix/detox-legacy/20.27.3/detox-legacy-20.27.3-sources.jar.sha256 +1 -0
- package/Detox-android/com/wix/detox-legacy/20.27.3/detox-legacy-20.27.3-sources.jar.sha512 +1 -0
- package/Detox-android/com/wix/detox-legacy/{20.27.2/detox-legacy-20.27.2.pom → 20.27.3/detox-legacy-20.27.3.pom} +1 -1
- package/Detox-android/com/wix/detox-legacy/20.27.3/detox-legacy-20.27.3.pom.md5 +1 -0
- package/Detox-android/com/wix/detox-legacy/20.27.3/detox-legacy-20.27.3.pom.sha1 +1 -0
- package/Detox-android/com/wix/detox-legacy/20.27.3/detox-legacy-20.27.3.pom.sha256 +1 -0
- package/Detox-android/com/wix/detox-legacy/20.27.3/detox-legacy-20.27.3.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/package.json +3 -3
- package/src/DetoxWorker.js +2 -0
- package/src/copilot/DetoxCopilot.js +2 -2
- package/src/copilot/detoxCopilotFrameworkDriver.js +449 -119
- package/src/realms/DetoxContext.js +2 -0
- package/Detox-android/com/wix/detox/20.27.2/detox-20.27.2-sources.jar.md5 +0 -1
- package/Detox-android/com/wix/detox/20.27.2/detox-20.27.2-sources.jar.sha1 +0 -1
- package/Detox-android/com/wix/detox/20.27.2/detox-20.27.2-sources.jar.sha256 +0 -1
- package/Detox-android/com/wix/detox/20.27.2/detox-20.27.2-sources.jar.sha512 +0 -1
- package/Detox-android/com/wix/detox/20.27.2/detox-20.27.2.pom.md5 +0 -1
- package/Detox-android/com/wix/detox/20.27.2/detox-20.27.2.pom.sha1 +0 -1
- package/Detox-android/com/wix/detox/20.27.2/detox-20.27.2.pom.sha256 +0 -1
- package/Detox-android/com/wix/detox/20.27.2/detox-20.27.2.pom.sha512 +0 -1
- package/Detox-android/com/wix/detox-legacy/20.27.2/detox-legacy-20.27.2-sources.jar.md5 +0 -1
- package/Detox-android/com/wix/detox-legacy/20.27.2/detox-legacy-20.27.2-sources.jar.sha1 +0 -1
- package/Detox-android/com/wix/detox-legacy/20.27.2/detox-legacy-20.27.2-sources.jar.sha256 +0 -1
- package/Detox-android/com/wix/detox-legacy/20.27.2/detox-legacy-20.27.2-sources.jar.sha512 +0 -1
- package/Detox-android/com/wix/detox-legacy/20.27.2/detox-legacy-20.27.2.pom.md5 +0 -1
- package/Detox-android/com/wix/detox-legacy/20.27.2/detox-legacy-20.27.2.pom.sha1 +0 -1
- package/Detox-android/com/wix/detox-legacy/20.27.2/detox-legacy-20.27.2.pom.sha256 +0 -1
- package/Detox-android/com/wix/detox-legacy/20.27.2/detox-legacy-20.27.2.pom.sha512 +0 -1
- /package/Detox-android/com/wix/detox/{20.27.2/detox-20.27.2.aar → 20.27.3/detox-20.27.3.aar} +0 -0
- /package/Detox-android/com/wix/detox/{20.27.2/detox-20.27.2.aar.md5 → 20.27.3/detox-20.27.3.aar.md5} +0 -0
- /package/Detox-android/com/wix/detox/{20.27.2/detox-20.27.2.aar.sha1 → 20.27.3/detox-20.27.3.aar.sha1} +0 -0
- /package/Detox-android/com/wix/detox/{20.27.2/detox-20.27.2.aar.sha256 → 20.27.3/detox-20.27.3.aar.sha256} +0 -0
- /package/Detox-android/com/wix/detox/{20.27.2/detox-20.27.2.aar.sha512 → 20.27.3/detox-20.27.3.aar.sha512} +0 -0
- /package/Detox-android/com/wix/detox-legacy/{20.27.2/detox-legacy-20.27.2.aar → 20.27.3/detox-legacy-20.27.3.aar} +0 -0
- /package/Detox-android/com/wix/detox-legacy/{20.27.2/detox-legacy-20.27.2.aar.md5 → 20.27.3/detox-legacy-20.27.3.aar.md5} +0 -0
- /package/Detox-android/com/wix/detox-legacy/{20.27.2/detox-legacy-20.27.2.aar.sha1 → 20.27.3/detox-legacy-20.27.3.aar.sha1} +0 -0
- /package/Detox-android/com/wix/detox-legacy/{20.27.2/detox-legacy-20.27.2.aar.sha256 → 20.27.3/detox-legacy-20.27.3.aar.sha256} +0 -0
- /package/Detox-android/com/wix/detox-legacy/{20.27.2/detox-legacy-20.27.2.aar.sha512 → 20.27.3/detox-legacy-20.27.3.aar.sha512} +0 -0
Binary file
|
@@ -0,0 +1 @@
|
|
1
|
+
8cd2f48786d004ff90fcc48db9b9e69a
|
@@ -0,0 +1 @@
|
|
1
|
+
4afea56e335fc27ee2b92be48673dea8a05185aa
|
@@ -0,0 +1 @@
|
|
1
|
+
0568be3312760e3a3a4259cc771a7253074502547e8eb3350213cde9f8db6165
|
@@ -0,0 +1 @@
|
|
1
|
+
2287316f0b862561456bef92c561598fcff17e286f17bc262470ef25cc6f71e84b16a8058e37f7f1536fc3a0433df990ba20173dd132b4c561c71e62a07e2fe6
|
@@ -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.3</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
|
+
2d7e0ca8745e2abb2087e946367c0538
|
@@ -0,0 +1 @@
|
|
1
|
+
071d2ecd2ac499ecef2bff9c5b3f830c613709ca
|
@@ -0,0 +1 @@
|
|
1
|
+
865a27d4ce918936ef0a629b2eb2c21dedc9e21629710732b2eb8ae9fd4374df
|
@@ -0,0 +1 @@
|
|
1
|
+
58f3c7bc9e6bbc5885f03460545c4832bab2c29490afcbc003d5ee0acb3cf6975f0d890292d4ac587d73c986a42e1c67624617f6fee6da9163ccf76ee5d730ab
|
@@ -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.3</latest>
|
7
|
+
<release>20.27.3</release>
|
8
8
|
<versions>
|
9
|
-
<version>20.27.
|
9
|
+
<version>20.27.3</version>
|
10
10
|
</versions>
|
11
|
-
<lastUpdated>
|
11
|
+
<lastUpdated>20241009154552</lastUpdated>
|
12
12
|
</versioning>
|
13
13
|
</metadata>
|
@@ -1 +1 @@
|
|
1
|
-
|
1
|
+
27e42826d06e4da1ec0844db0255a70c
|
@@ -1 +1 @@
|
|
1
|
-
|
1
|
+
8a719a4551a0fde056e3f53cd841131fe908fc4d
|
@@ -1 +1 @@
|
|
1
|
-
|
1
|
+
ad19b8a5540aabca7a9ea07890509a1e9161848db2682d1c82274168fcf710ef
|
@@ -1 +1 @@
|
|
1
|
-
|
1
|
+
b4fcc3ee40ae9bb22b6c97fd768a3b52281ca32229fd3fc50d8512b81ccec8cbbc3c94f03be1e843016fe97de37a5042938ba549e512894d6c08686ebf2d43c2
|
Binary file
|
@@ -0,0 +1 @@
|
|
1
|
+
b4efad81e134dacbb7d81b566aed6d89
|
@@ -0,0 +1 @@
|
|
1
|
+
e994e4dad3f2dce5f5fde279bc6cd917ee6b2f07
|
@@ -0,0 +1 @@
|
|
1
|
+
7e9153002e13fa5ffeef31eeda43b00e38bacbcba46640ce59fb42220a51c22a
|
@@ -0,0 +1 @@
|
|
1
|
+
818984bbddf7bf9561bc6bc9e646cb2f89d5cd83c863aef37c5bf1a3911d08c6a4dc04b8251a85208c7ae308b11e6970a94d33fb2293dbd8bf3c6df6cd55d3ab
|
@@ -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.3</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
|
+
965972ea4b2739cb5d958a329b9bcc3d
|
@@ -0,0 +1 @@
|
|
1
|
+
b6d5cfb02046495791ca031d12b9f2310f799a0e
|
@@ -0,0 +1 @@
|
|
1
|
+
b27221155e7cfcfab8c62c949d47cd71967e19b243c001e53ac518e4cf900769
|
@@ -0,0 +1 @@
|
|
1
|
+
d9c28fba54e53d5546f30c9b43326175f6ac8cf3194a8d0faea4d97b487198eb994f06249994c579b0f82f7ab0c7685689fe605887668dc2eaa5e659892e388a
|
@@ -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.3</latest>
|
7
|
+
<release>20.27.3</release>
|
8
8
|
<versions>
|
9
|
-
<version>20.27.
|
9
|
+
<version>20.27.3</version>
|
10
10
|
</versions>
|
11
|
-
<lastUpdated>
|
11
|
+
<lastUpdated>20241009154624</lastUpdated>
|
12
12
|
</versioning>
|
13
13
|
</metadata>
|
@@ -1 +1 @@
|
|
1
|
-
|
1
|
+
6ddea16ac39ebcaa72590d9b50ca41a1
|
@@ -1 +1 @@
|
|
1
|
-
|
1
|
+
1ad379b7c3de738b8adebc19d859742fdbf6797a
|
@@ -1 +1 @@
|
|
1
|
-
|
1
|
+
61f5bf7772111546173237486ddc5909ee6bc7053595adc3305c0ccfeb927736
|
@@ -1 +1 @@
|
|
1
|
-
|
1
|
+
03e8049bdb4784b4c54b25e9a14b30012ee6212ae6b7329d61ea357ed97f485d1e88a8f2e0d573046020c07fd7681ac9cd84189d195598b867401ef83e97b1e9
|
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/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.3",
|
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.14",
|
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": "4ccef46fa6cbc2526d02af45f3b2ca92f6e5d1df"
|
120
120
|
}
|
package/src/DetoxWorker.js
CHANGED
@@ -14,25 +14,25 @@ const detoxCopilotFrameworkDriver = {
|
|
14
14
|
signature: 'by.id(id: string)',
|
15
15
|
description: 'Matches elements by their test ID.',
|
16
16
|
example: "element(by.id('loginButton'))",
|
17
|
-
guidelines: ['
|
17
|
+
guidelines: ['Use test IDs (accessibility identifiers) to uniquely identify elements. This is the best-practice matcher.'],
|
18
18
|
},
|
19
19
|
{
|
20
20
|
signature: 'by.text(text: string)',
|
21
21
|
description: 'Matches elements by their text.',
|
22
22
|
example: "element(by.text('Login'))",
|
23
|
-
guidelines: ['
|
23
|
+
guidelines: ['Prefer test IDs over text matchers when possible.'],
|
24
24
|
},
|
25
25
|
{
|
26
26
|
signature: 'by.type(type: string)',
|
27
27
|
description: 'Matches elements by their type.',
|
28
28
|
example: "element(by.type('RCTTextInput'))",
|
29
|
-
guidelines: ['Use type matchers as a last resort
|
29
|
+
guidelines: ['Use type matchers as a last resort.'],
|
30
30
|
},
|
31
31
|
{
|
32
32
|
signature: 'atIndex(index: number)',
|
33
|
-
description: 'Selects the element at the specified index from
|
33
|
+
description: 'Selects the element at the specified index from matched elements.',
|
34
34
|
example: "element(by.id('listItem')).atIndex(2)",
|
35
|
-
guidelines: ['Use
|
35
|
+
guidelines: ['Use when multiple elements match the same matcher.'],
|
36
36
|
},
|
37
37
|
],
|
38
38
|
},
|
@@ -43,169 +43,141 @@ const detoxCopilotFrameworkDriver = {
|
|
43
43
|
signature: 'tap(point?: Point2D)',
|
44
44
|
description: 'Simulates tap on an element.',
|
45
45
|
example: "await element(by.id('loginButton')).tap();",
|
46
|
-
guidelines: ["Use `element(by.id('testID'))` to locate elements."],
|
47
46
|
},
|
48
47
|
{
|
49
48
|
signature: 'longPress(point?: Point2D, duration?: number)',
|
50
49
|
description: 'Simulates long press on an element.',
|
51
50
|
example: "await element(by.id('menuItem')).longPress();",
|
52
|
-
guidelines: [
|
53
|
-
'If the target element is not accessible, interact with its container or the most relevant parent element.',
|
54
|
-
'Long-press should be called with the relevant params only, e.g. `longPress(2000)`, `longPress({ x: 100, y: 200 })` or `longPress({ x: 100, y: 200 }, 2000)`.',
|
55
|
-
],
|
51
|
+
guidelines: ['Tapping on edges of elements might work better when adding a small offset to the point.'],
|
56
52
|
},
|
57
53
|
{
|
58
54
|
signature: 'multiTap(times: number)',
|
59
55
|
description: 'Simulates multiple taps on an element.',
|
60
56
|
example: "await element(by.id('tappable')).multiTap(3);",
|
61
|
-
guidelines: ['All taps are applied as part of the same gesture.'],
|
62
57
|
},
|
63
58
|
{
|
64
59
|
signature: 'typeText(text: string)',
|
65
60
|
description: 'Types text into a text field.',
|
66
61
|
example: "await element(by.id('usernameInput')).typeText('myusername');",
|
67
|
-
guidelines: ['
|
62
|
+
guidelines: ['Element must be a text input field.'],
|
68
63
|
},
|
69
64
|
{
|
70
65
|
signature: 'replaceText(text: string)',
|
71
66
|
description: 'Replaces text in a text field.',
|
72
67
|
example: "await element(by.id('textField')).replaceText('new text');",
|
73
|
-
guidelines: ['Faster than `typeText()`, but may not trigger all text input callbacks.'],
|
74
68
|
},
|
75
69
|
{
|
76
70
|
signature: 'clearText()',
|
77
71
|
description: 'Clears text from a text field.',
|
78
72
|
example: "await element(by.id('textField')).clearText();",
|
79
|
-
guidelines: ['Use this to clear text from input fields.'],
|
80
73
|
},
|
81
74
|
{
|
82
75
|
signature: 'tapReturnKey()',
|
83
76
|
description: 'Simulates tapping the return key on the keyboard while the element is focused.',
|
84
77
|
example: "await element(by.id('textField')).tapReturnKey();",
|
85
|
-
guidelines: ['Use this to simulate pressing the return key while typing into a text input field.'],
|
86
78
|
},
|
87
79
|
{
|
88
80
|
signature: 'tapBackspaceKey()',
|
89
81
|
description: 'Simulates tapping the backspace key on the keyboard while the element is focused.',
|
90
82
|
example: "await element(by.id('textField')).tapBackspaceKey();",
|
91
|
-
guidelines: ['Use this to simulate deleting text by pressing the backspace key in a text input field.'],
|
92
83
|
},
|
93
84
|
{
|
94
85
|
signature: 'adjustSliderToPosition(normalizedPosition: number)',
|
95
|
-
description: 'Adjusts
|
86
|
+
description: 'Adjusts slider to a normalized position between 0 and 1.',
|
96
87
|
example: "await element(by.id('slider')).adjustSliderToPosition(0.75);",
|
97
|
-
guidelines: ['The position is a normalized value between 0 and 1, where 0 is minimum and 1 is maximum.'],
|
98
88
|
},
|
99
89
|
{
|
100
90
|
signature: 'scroll(offset: number, direction: string, startPositionX?: number, startPositionY?: number)',
|
101
|
-
description: 'Scrolls an element.',
|
91
|
+
description: 'Scrolls an element by an offset in a direction.',
|
102
92
|
example: "await element(by.id('scrollView')).scroll(100, 'down');",
|
103
|
-
guidelines: [
|
93
|
+
guidelines: [
|
94
|
+
'Direction can be "up", "down", "left", or "right".',
|
95
|
+
'Use `startPositionX` and `startPositionY` to specify the starting point of the scroll gesture.',
|
96
|
+
'If multiple scroll actions are needed while waiting for an element, use `whileElement()` in conjunction with `waitFor()`.',
|
97
|
+
],
|
104
98
|
},
|
105
99
|
{
|
106
|
-
signature: 'scrollTo(edge: string)',
|
100
|
+
signature: 'scrollTo(edge: string, startPositionX?: number, startPositionY?: number)',
|
107
101
|
description: 'Scrolls to an edge of the element.',
|
108
102
|
example: "await element(by.id('scrollView')).scrollTo('bottom');",
|
109
|
-
guidelines: [
|
103
|
+
guidelines: [
|
104
|
+
'Edge can be "top", "bottom", "left", or "right".',
|
105
|
+
'Use `startPositionX` and `startPositionY` to specify the starting point of the scroll gesture.',
|
106
|
+
],
|
107
|
+
},
|
108
|
+
{
|
109
|
+
signature: 'whileElement(element: Matcher)',
|
110
|
+
description: 'Continuously performs an action while waiting for an expectation to be fulfilled.',
|
111
|
+
example: `
|
112
|
+
await waitFor(element(by.text('Load More')))
|
113
|
+
.toBeVisible()
|
114
|
+
.whileElement(by.id('scrollView'))
|
115
|
+
.scroll(50, 'down');`,
|
116
|
+
guidelines: [
|
117
|
+
'Used in conjunction with `waitFor()` to perform actions like scrolling while waiting for an element to meet the expectation.',
|
118
|
+
'The action (e.g., `scroll`) is performed on the element specified in `whileElement()`.',
|
119
|
+
],
|
110
120
|
},
|
111
121
|
{
|
112
122
|
signature: 'scrollToIndex(index: number)',
|
113
|
-
description: 'Scrolls
|
123
|
+
description: 'Scrolls to the specified index (Android only).',
|
114
124
|
example: "await element(by.id('scrollView')).scrollToIndex(10);",
|
115
|
-
guidelines: ['Use this to scroll to a specific item in a list. Only available on Android.'],
|
116
125
|
},
|
117
126
|
{
|
118
127
|
signature: 'swipe(direction: string, speed?: string, normalizedOffset?: number)',
|
119
|
-
description: 'Simulates a swipe
|
120
|
-
example: "await element(by.id('scrollView')).swipe('up'
|
128
|
+
description: 'Simulates a swipe gesture.',
|
129
|
+
example: "await element(by.id('scrollView')).swipe('up');",
|
121
130
|
guidelines: [
|
122
|
-
'
|
123
|
-
'
|
131
|
+
'Speed can be "fast" or "slow"; default is "fast".',
|
132
|
+
'Direction can be "up", "down", "left", or "right".',
|
133
|
+
'Up swipe scrolls down, left swipe scrolls right.',
|
124
134
|
],
|
125
135
|
},
|
126
136
|
{
|
127
137
|
signature: 'setColumnToValue(column: number, value: string)',
|
128
|
-
description: 'Sets
|
138
|
+
description: 'Sets picker column to a value (iOS only).',
|
129
139
|
example: "await element(by.id('pickerView')).setColumnToValue(1, '6');",
|
130
|
-
guidelines: ['Use this for picker views on iOS.'],
|
131
140
|
},
|
132
141
|
{
|
133
142
|
signature: 'setDatePickerDate(dateString: string, dateFormat: string)',
|
134
|
-
description: 'Sets
|
143
|
+
description: 'Sets date picker to a specific date.',
|
135
144
|
example: "await element(by.id('datePicker')).setDatePickerDate('2023-05-25', 'yyyy-MM-dd');",
|
136
|
-
guidelines: ['Use ISO8601 format when possible.'],
|
137
145
|
},
|
138
146
|
{
|
139
147
|
signature: 'performAccessibilityAction(actionName: string)',
|
140
|
-
description: '
|
148
|
+
description: 'Performs an accessibility action.',
|
141
149
|
example: "await element(by.id('scrollView')).performAccessibilityAction('activate');",
|
142
|
-
guidelines: ['Use this to trigger specific accessibility actions.'],
|
143
150
|
},
|
144
151
|
{
|
145
152
|
signature: 'pinch(scale: number, speed?: string, angle?: number)',
|
146
153
|
description: 'Simulates a pinch gesture.',
|
147
|
-
example: "await element(by.id('
|
148
|
-
guidelines: ['
|
154
|
+
example: "await element(by.id('pinchableView')).pinch(1.1);",
|
155
|
+
guidelines: ['Scale >1 to zoom in, <1 to zoom out.'],
|
149
156
|
},
|
150
|
-
|
151
157
|
{
|
152
158
|
signature: 'getAttributes()',
|
153
|
-
description:
|
154
|
-
Retrieves various attributes of the element.
|
155
|
-
|
156
|
-
**Attributes include:**
|
157
|
-
- **Common**: text (string), label (string), placeholder (string), enabled (boolean), identifier (string), visible (boolean), value (string | number | boolean), frame (object: x (number), y (number), width (number), height (number))
|
158
|
-
- **iOS-only**: activationPoint (object: x (number), y (number)), normalizedActivationPoint (object: x (number), y (number)), hittable (boolean), elementFrame (object: x (number), y (number), width (number), height (number)), elementBounds (object: x (number), y (number), width (number), height (number)), safeAreaInsets (object: top (number), bottom (number), left (number), right (number)), elementSafeBounds (object: x (number), y (number), width (number), height (number)), date (Date), normalizedSliderPosition (number), contentOffset (object: x (number), y (number)), contentInset (object: top (number), bottom (number), left (number), right (number)), adjustedContentInset (object: top (number), bottom (number), left (number), right (number)))
|
159
|
-
- **Android-only**: visibility (string: 'visible', 'invisible', 'gone'), width (number) *(deprecated)*, height (number) *(deprecated)*, elevation (number), alpha (number), focused (boolean), textSize (number), length (number)
|
160
|
-
|
161
|
-
*Note:* Attributes may vary based on the platform and element type. If an attribute's value is null or cannot be computed, the key might be absent or contain an empty string.
|
162
|
-
`,
|
159
|
+
description: 'Retrieves attributes of the element.',
|
163
160
|
example: `
|
164
|
-
|
165
|
-
|
166
|
-
jestExpect(attributes.text).toBe('Tap Me');
|
167
|
-
|
168
|
-
// Numerical assertions with allowed error range
|
169
|
-
jestExpect(attributes.frame.x).toBeCloseTo(100, 1);
|
170
|
-
jestExpect(attributes.frame.y).toBeCloseTo(200, 1);
|
171
|
-
|
172
|
-
// Platform-specific attribute check
|
173
|
-
if (device.getPlatform() === 'ios') {
|
174
|
-
jestExpect(attributes.hittable).toBe(true);
|
175
|
-
} else if (device.getPlatform() === 'android') {
|
176
|
-
jestExpect(attributes.visibility).toBe('visible');
|
177
|
-
}
|
178
|
-
`,
|
179
|
-
guidelines: [
|
180
|
-
'Use this to get properties like text, value, visibility, etc., for assertions or debugging. But only if the regular matchers or assertions are not sufficient.',
|
181
|
-
'Note that numerical values like position or size may not be very accurate; consider allowing a small error range in assertions.',
|
182
|
-
'Check the platform using `device.getPlatform()` before using platform-specific attributes.',
|
183
|
-
'Attributes include text, label, placeholder, enabled, identifier, visible, value, frame (with x, y, width, height), and platform-specific attributes.',
|
184
|
-
],
|
161
|
+
const attributes = await element(by.text('Tap Me')).getAttributes();
|
162
|
+
jestExpect(attributes.text).toBe('Tap Me');`,
|
185
163
|
},
|
186
164
|
{
|
187
165
|
signature: 'takeScreenshot(name: string)',
|
188
166
|
description: 'Captures a screenshot of the element.',
|
189
167
|
example: "const imagePath = await element(by.id('menuRoot')).takeScreenshot('menu_screenshot');",
|
190
|
-
guidelines: ['Use this to capture screenshots of elements for documentation or debugging purposes.'],
|
191
|
-
},
|
192
|
-
{
|
193
|
-
signature: 'longPressAndDrag(duration: number, normalizedPositionX: number, normalizedPositionY: number, targetElement: NativeElement, normalizedTargetPositionX?: number, normalizedTargetPositionY?: number, speed?: string, holdDuration?: number)',
|
194
|
-
description: 'Simulates a long press on the element and then drags it to a target element.',
|
195
|
-
example: "await element(by.id('draggable')).longPressAndDrag(2000, NaN, NaN, element(by.id('target')), NaN, NaN, 'fast', 0);",
|
196
|
-
guidelines: ['Use this to simulate drag-and-drop interactions between elements.'],
|
197
|
-
},
|
198
|
-
{
|
199
|
-
signature: 'launchApp(params: object)',
|
200
|
-
description: 'Launches the app with specified parameters.',
|
201
|
-
example: 'await device.launchApp({newInstance: true});',
|
202
|
-
guidelines: ['Use this to launch the app with specific configurations.'],
|
203
168
|
},
|
204
169
|
{
|
205
|
-
signature: '
|
206
|
-
description:
|
207
|
-
|
208
|
-
|
170
|
+
signature: 'longPressAndDrag(duration, normalizedPositionX, normalizedPositionY, targetElement, normalizedTargetPositionX, normalizedTargetPositionY, speed, holdDuration)',
|
171
|
+
description: `Performs a long press and drags to a target element.
|
172
|
+
- \`duration\` — the duration to press for, in ms (required)
|
173
|
+
- \`normalizedPositionX\` — X coordinate of the starting point, relative to the element width (required, a number between 0.0 and 1.0, NaN — choose an optimal value automatically)
|
174
|
+
- \`normalizedPositionY\` — Y coordinate of the starting point, relative to the element height (required, a number between 0.0 and 1.0, NaN — choose an optimal value automatically)
|
175
|
+
- \`targetElement\` — the target element to drag to (required)
|
176
|
+
- \`normalizedTargetPositionX\` — X coordinate of the ending point, relative to the target element width (optional, a number between 0.0 and 1.0, NaN — choose an optimal value automatically)
|
177
|
+
- \`normalizedTargetPositionY\` — Y coordinate of the ending point, relative to the target element height (optional, a number between 0.0 and 1.0, NaN — choose an optimal value automatically)
|
178
|
+
- \`speed\` — the speed of the drag (optional, valid input: "fast"/"slow" , default is "fast")
|
179
|
+
- \`holdDuration\` — the duration before releasing at the end, in ms (optional, default is 1000)`,
|
180
|
+
example: "await element(by.id('cellId_1')).longPressAndDrag(2000, 0.9, NaN, element(by.id('cellId_6')), 0.9, NaN, 'slow', 0);",
|
209
181
|
},
|
210
182
|
],
|
211
183
|
},
|
@@ -216,75 +188,56 @@ const detoxCopilotFrameworkDriver = {
|
|
216
188
|
signature: 'toBeVisible()',
|
217
189
|
description: 'Asserts that the element is visible.',
|
218
190
|
example: "await expect(element(by.id('loginButton'))).toBeVisible();",
|
219
|
-
guidelines: ['Use this to check if an element is visible on the screen.'],
|
220
191
|
},
|
221
192
|
{
|
222
193
|
signature: 'toExist()',
|
223
194
|
description: 'Asserts that the element exists.',
|
224
195
|
example: "await expect(element(by.id('username'))).toExist();",
|
225
|
-
guidelines: ['Use this to check if an element exists in the hierarchy, even if not visible.'],
|
226
196
|
},
|
227
197
|
{
|
228
198
|
signature: 'toHaveText(text: string)',
|
229
199
|
description: 'Asserts that the element has the specified text.',
|
230
200
|
example: "await expect(element(by.id('label'))).toHaveText('Hello, World!');",
|
231
|
-
guidelines: ['Use this to check the text content of an element.'],
|
232
201
|
},
|
233
202
|
{
|
234
203
|
signature: 'toHaveValue(value: string)',
|
235
204
|
description: 'Asserts that the element has the specified value.',
|
236
205
|
example: "await expect(element(by.id('slider'))).toHaveValue('0.5');",
|
237
|
-
guidelines: ['Use this to check the value of an element.'],
|
238
206
|
},
|
239
207
|
{
|
240
208
|
signature: 'toBeFocused()',
|
241
209
|
description: 'Asserts that the element is focused.',
|
242
210
|
example: "await expect(element(by.id('emailInput'))).toBeFocused();",
|
243
|
-
guidelines: ['Use this to check if an element is currently focused.'],
|
244
211
|
},
|
245
212
|
{
|
246
213
|
signature: 'toHaveLabel(label: string)',
|
247
214
|
description: 'Asserts that the element has the specified accessibility label.',
|
248
215
|
example: "await expect(element(by.id('submitButton'))).toHaveLabel('Submit');",
|
249
|
-
guidelines: [
|
250
|
-
'Use this to check the accessibility label of an element. Note that in React Native, the `accessibilityLabel` prop may behave differently on iOS and Android.',
|
251
|
-
],
|
252
216
|
},
|
253
217
|
{
|
254
218
|
signature: 'toHaveId(id: string)',
|
255
219
|
description: 'Asserts that the element has the specified accessibility identifier.',
|
256
220
|
example: "await expect(element(by.text('Submit'))).toHaveId('submitButton');",
|
257
|
-
guidelines: ['Use this to check the testID/accessibility identifier of an element.'],
|
258
221
|
},
|
259
222
|
{
|
260
223
|
signature: 'toHaveSliderPosition(normalizedPosition: number, tolerance?: number)',
|
261
|
-
description:
|
262
|
-
|
263
|
-
example:
|
264
|
-
"await expect(element(by.id('slider'))).toHaveSliderPosition(0.75);\nawait expect(element(by.id('slider'))).toHaveSliderPosition(0.3113, 0.00001);",
|
265
|
-
guidelines: ['Use this to verify the slider\'s position. Normalized position is between 0 and 1.'],
|
224
|
+
description: 'Asserts that the slider is at a normalized position.',
|
225
|
+
example: "await expect(element(by.id('slider'))).toHaveSliderPosition(0.75);",
|
266
226
|
},
|
267
227
|
{
|
268
228
|
signature: 'toHaveToggleValue(value: boolean)',
|
269
|
-
description: 'Asserts that a toggle
|
270
|
-
example:
|
271
|
-
"await expect(element(by.id('switch'))).toHaveToggleValue(true);\nawait expect(element(by.id('checkbox'))).toHaveToggleValue(false);",
|
272
|
-
guidelines: ['Use this to check the state of toggleable elements.'],
|
229
|
+
description: 'Asserts that a toggle element is on or off.',
|
230
|
+
example: "await expect(element(by.id('switch'))).toHaveToggleValue(true);",
|
273
231
|
},
|
274
232
|
{
|
275
233
|
signature: 'withTimeout(timeout: number)',
|
276
|
-
description:
|
277
|
-
|
278
|
-
example:
|
279
|
-
"await waitFor(element(by.id('bigButton'))).toBeVisible().withTimeout(2000);",
|
280
|
-
guidelines: ['Use this to set a custom timeout for an expectation.'],
|
234
|
+
description: 'Waits until the expectation is resolved or timeout occurs.',
|
235
|
+
example: "await waitFor(element(by.id('bigButton'))).toBeVisible().withTimeout(2000);",
|
281
236
|
},
|
282
237
|
{
|
283
238
|
signature: 'not',
|
284
239
|
description: 'Negates the expectation.',
|
285
|
-
example:
|
286
|
-
"await expect(element(by.id('tinyButton'))).not.toBeVisible();\nawait expect(element(by.id('tinyButton'))).not.toExist();",
|
287
|
-
guidelines: ["Use 'not' to negate an expectation."],
|
240
|
+
example: "await expect(element(by.id('tinyButton'))).not.toBeVisible();",
|
288
241
|
},
|
289
242
|
],
|
290
243
|
},
|
@@ -293,17 +246,394 @@ const detoxCopilotFrameworkDriver = {
|
|
293
246
|
items: [
|
294
247
|
{
|
295
248
|
signature: 'jestExpect',
|
296
|
-
description: 'Jest expect utility for
|
249
|
+
description: 'Jest expect utility for additional assertions.',
|
297
250
|
example: `
|
298
|
-
|
299
|
-
|
300
|
-
jestExpect('hello').toBe('hello');
|
301
|
-
jestExpect(true).toBeTruthy();
|
302
|
-
`,
|
303
|
-
guidelines: ['Use jestExpect for assertions in tests, only when the default expect is not helpful for the specific case.'],
|
251
|
+
jestExpect(2 + 2).toBe(4);
|
252
|
+
jestExpect('hello').toBe('hello');`,
|
304
253
|
},
|
305
254
|
],
|
306
|
-
}
|
255
|
+
},
|
256
|
+
{
|
257
|
+
title: 'Device APIs',
|
258
|
+
items: [
|
259
|
+
{
|
260
|
+
signature: 'device.launchApp(params?: object)',
|
261
|
+
description: `
|
262
|
+
Launches the app with specified parameters.
|
263
|
+
|
264
|
+
**Parameters:**
|
265
|
+
- \`newInstance\` (boolean): If \`true\`, terminates the app and launches a new instance.
|
266
|
+
- \`delete\` (boolean): If \`true\`, deletes the app data before launching.
|
267
|
+
- \`launchArgs\` (object): Additional launch arguments as key-value pairs.
|
268
|
+
- \`url\` (string): URL to open in the app.
|
269
|
+
- \`permissions\` (object): Permissions to grant the app. Supported permissions are:
|
270
|
+
| Permission | Values |
|
271
|
+
|-----------------|----------------------------|
|
272
|
+
| **location** | always / inuse / never / unset |
|
273
|
+
| **contacts** | YES / NO / unset / limited |
|
274
|
+
| **photos** | YES / NO / unset / limited |
|
275
|
+
| **calendar** | YES / NO / unset |
|
276
|
+
| **camera** | YES / NO / unset |
|
277
|
+
| **medialibrary**| YES / NO / unset |
|
278
|
+
| **microphone** | YES / NO / unset |
|
279
|
+
| **motion** | YES / NO / unset |
|
280
|
+
| **reminders** | YES / NO / unset |
|
281
|
+
| **siri** | YES / NO / unset |
|
282
|
+
| **notifications**| YES / NO / unset |
|
283
|
+
| **health** | YES / NO / unset |
|
284
|
+
| **homekit** | YES / NO / unset |
|
285
|
+
| **speech** | YES / NO / unset |
|
286
|
+
| **faceid** | YES / NO / unset |
|
287
|
+
| **userTracking**| YES / NO / unset |
|
288
|
+
`,
|
289
|
+
example: `
|
290
|
+
await device.launchApp({ newInstance: true });
|
291
|
+
await device.launchApp({ newInstance: true, permissions: { notifications: 'YES' } });
|
292
|
+
await device.launchApp({ launchArgs: { someLaunchArg: 1234 } });`,
|
293
|
+
guidelines: ['Use minimal parameters necessary for your launch scenario.'],
|
294
|
+
},
|
295
|
+
{
|
296
|
+
signature: 'device.reloadReactNative()',
|
297
|
+
description: 'Reloads the React Native JS bundle.',
|
298
|
+
example: 'await device.reloadReactNative();',
|
299
|
+
},
|
300
|
+
{
|
301
|
+
signature: 'device.setOrientation(orientation: string)',
|
302
|
+
description: 'Rotates the device to the specified orientation.',
|
303
|
+
example: 'await device.setOrientation("landscape");',
|
304
|
+
guidelines: ['Orientation can be "portrait" or "landscape".'],
|
305
|
+
},
|
306
|
+
{
|
307
|
+
signature: 'device.setLocation(lat: number, lon: number)',
|
308
|
+
description: 'Sets the device location.',
|
309
|
+
example: 'await device.setLocation(37.7749, -122.4194);',
|
310
|
+
},
|
311
|
+
{
|
312
|
+
signature: 'device.takeScreenshot(name?: string)',
|
313
|
+
description: 'Captures a screenshot of the device.',
|
314
|
+
example: 'const path = await device.takeScreenshot("home_screen");',
|
315
|
+
},
|
316
|
+
{
|
317
|
+
signature: 'device.getPlatform()',
|
318
|
+
description: 'Returns the current device platform ("ios" or "android").',
|
319
|
+
example: 'const platform = device.getPlatform();',
|
320
|
+
guidelines: ['Use to conditionally execute platform-specific code.'],
|
321
|
+
},
|
322
|
+
{
|
323
|
+
signature: 'device.openURL(url: string)',
|
324
|
+
description: 'Opens a deeplink within the app, or a URL in the browser.',
|
325
|
+
example: 'await device.openURL("app://home");',
|
326
|
+
}
|
327
|
+
],
|
328
|
+
},
|
329
|
+
{
|
330
|
+
title: 'System APIs (iOS)',
|
331
|
+
items: [
|
332
|
+
{
|
333
|
+
signature: 'system.element(matcher: Matcher)',
|
334
|
+
description: 'Selects an element within the system UI.',
|
335
|
+
example: "system.element(by.system.label('Allow')).tap();",
|
336
|
+
guidelines: [
|
337
|
+
'Can be used for iOS system alerts and permissions dialogs',
|
338
|
+
'Check the platform with `device.getPlatform()` before using, as it is iOS-specific',
|
339
|
+
'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
|
+
]
|
341
|
+
},
|
342
|
+
{
|
343
|
+
signature: 'by.system.label(label: string)',
|
344
|
+
description: 'Matches system elements by label.',
|
345
|
+
example: "system.element(by.system.label('Dismiss'));",
|
346
|
+
},
|
347
|
+
{
|
348
|
+
signature: 'by.system.type(type: string)',
|
349
|
+
description: 'Matches system elements by type.',
|
350
|
+
example: "system.element(by.system.type('button'));",
|
351
|
+
},
|
352
|
+
{
|
353
|
+
signature: 'tap()',
|
354
|
+
description: 'Taps on a system element.',
|
355
|
+
example: "system.element(by.system.label('Allow')).tap();",
|
356
|
+
},
|
357
|
+
{
|
358
|
+
signature: 'toExist()',
|
359
|
+
description: 'Asserts that the system element exists.',
|
360
|
+
example: "await system.element(by.system.label('Allow')).toExist();",
|
361
|
+
},
|
362
|
+
{
|
363
|
+
signature: 'not',
|
364
|
+
description: 'Negates the expectation for system elements.',
|
365
|
+
example: "await system.element(by.system.label('Allow')).not.toExist();",
|
366
|
+
},
|
367
|
+
],
|
368
|
+
},
|
369
|
+
{
|
370
|
+
title: 'Web APIs',
|
371
|
+
items: [
|
372
|
+
{
|
373
|
+
signature: 'web.element(matcher: Matcher)',
|
374
|
+
description: 'Selects an element within a web view. Use when there is only one web view on the screen.',
|
375
|
+
example: "const element = web.element(by.web.id('username'));",
|
376
|
+
guidelines: [
|
377
|
+
'Web APIs can only be used with web elements (within web views).',
|
378
|
+
'Avoid using web APIs for native elements or native APIs for web elements.',
|
379
|
+
'Always prefer the `by.web.id` matcher when possible.',
|
380
|
+
],
|
381
|
+
},
|
382
|
+
{
|
383
|
+
signature: 'web(nativeMatcher).element(matcher: Matcher)',
|
384
|
+
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: "const element = web(by.id('webview')).element(by.web.id('password'));",
|
386
|
+
guidelines: [
|
387
|
+
'Use this method when multiple web views are present.',
|
388
|
+
'Prefer `web.element` if only one web view is present on the screen.',
|
389
|
+
],
|
390
|
+
},
|
391
|
+
{
|
392
|
+
signature: 'web(nativeMatcher).atIndex(index: number).element(matcher: Matcher)',
|
393
|
+
description: 'Selects an element within a specific web view at a given index (iOS only).',
|
394
|
+
example: "const element = web(by.id('webview')).atIndex(1).element(by.web.id('password'));",
|
395
|
+
guidelines: [
|
396
|
+
'Use when multiple web views with the same identifier are present on iOS.',
|
397
|
+
'This matcher is available for iOS only.',
|
398
|
+
'Check the platform with `device.getPlatform()` before using.',
|
399
|
+
],
|
400
|
+
},
|
401
|
+
{
|
402
|
+
signature: 'by.web.id(id: string)',
|
403
|
+
description: 'Matches web elements by their ID attribute.',
|
404
|
+
example: "web.element(by.web.id('submit_button'));",
|
405
|
+
guidelines: [
|
406
|
+
'Use for web elements with unique IDs.',
|
407
|
+
'This is the best-practice matcher for web elements.',
|
408
|
+
],
|
409
|
+
},
|
410
|
+
{
|
411
|
+
signature: 'by.web.className(className: string)',
|
412
|
+
description: 'Matches web elements by their CSS class name.',
|
413
|
+
example: "web.element(by.web.className('btn-primary'));",
|
414
|
+
},
|
415
|
+
{
|
416
|
+
signature: 'by.web.cssSelector(cssSelector: string)',
|
417
|
+
description: 'Matches web elements using a CSS selector.',
|
418
|
+
example: "web.element(by.web.cssSelector('.container > .item'));",
|
419
|
+
},
|
420
|
+
{
|
421
|
+
signature: 'by.web.name(name: string)',
|
422
|
+
description: 'Matches web elements by their name attribute.',
|
423
|
+
example: "web.element(by.web.name('email'));",
|
424
|
+
},
|
425
|
+
{
|
426
|
+
signature: 'by.web.xpath(xpath: string)',
|
427
|
+
description: 'Matches web elements using an XPath expression.',
|
428
|
+
example: "web.element(by.web.xpath('//*[@id=\"submit\"]'));",
|
429
|
+
guidelines: [
|
430
|
+
'Use when `by.web.id` is not available.',
|
431
|
+
'XPath matchers can be less performant.',
|
432
|
+
],
|
433
|
+
},
|
434
|
+
{
|
435
|
+
signature: 'by.web.href(href: string)',
|
436
|
+
description: 'Matches web elements by their href attribute.',
|
437
|
+
example: "web.element(by.web.href('https://example.com'));",
|
438
|
+
},
|
439
|
+
{
|
440
|
+
signature: 'by.web.hrefContains(href: string)',
|
441
|
+
description: 'Matches web elements whose href attribute contains the specified string.',
|
442
|
+
example: "web.element(by.web.hrefContains('example.com'));",
|
443
|
+
},
|
444
|
+
{
|
445
|
+
signature: 'by.web.tag(tag: string)',
|
446
|
+
description: 'Matches web elements by their tag name.',
|
447
|
+
example: "web.element(by.web.tag('h1'));",
|
448
|
+
},
|
449
|
+
{
|
450
|
+
signature: 'by.web.value(value: string)',
|
451
|
+
description: 'Matches web elements by their value attribute (iOS only).',
|
452
|
+
example: "web.element(by.web.value('Submit'));",
|
453
|
+
guidelines: ['Available on iOS only.'],
|
454
|
+
},
|
455
|
+
{
|
456
|
+
signature: 'by.web.label(label: string)',
|
457
|
+
description: 'Matches web elements by their accessibility label (iOS only, supports `asSecured()`).',
|
458
|
+
example: "web.element(by.web.label('Submit')).asSecured();",
|
459
|
+
guidelines: [
|
460
|
+
'Available on iOS only.',
|
461
|
+
'Use when the element has a unique label.',
|
462
|
+
],
|
463
|
+
},
|
464
|
+
{
|
465
|
+
signature: 'by.web.type(accessibilityType: string)',
|
466
|
+
description: 'Matches web elements by accessibility type (iOS only, with `asSecured()`).',
|
467
|
+
example: "web.element(by.web.type('textField')).asSecured();",
|
468
|
+
guidelines: [
|
469
|
+
'Available on iOS only and used with `asSecured()`.',
|
470
|
+
'Type can be any XCUIElement.ElementType, e.g., "button", "textField".',
|
471
|
+
],
|
472
|
+
},
|
473
|
+
{
|
474
|
+
signature: 'atIndex(index: number)',
|
475
|
+
description: 'Selects the web element at the specified index from matched elements.',
|
476
|
+
example: "web.element(by.web.tag('h1')).atIndex(1);",
|
477
|
+
guidelines: ['Use when multiple web elements match the same matcher.'],
|
478
|
+
},
|
479
|
+
{
|
480
|
+
signature: 'tap()',
|
481
|
+
description: 'Taps on a web element.',
|
482
|
+
example: "await web.element(by.web.id('link')).tap();",
|
483
|
+
guidelines: [
|
484
|
+
'Supports `asSecured()` on iOS.',
|
485
|
+
'Use `asSecured()` when interacting with secured web views.',
|
486
|
+
],
|
487
|
+
},
|
488
|
+
{
|
489
|
+
signature: 'typeText(text: string, isContentEditable?: boolean)',
|
490
|
+
description: 'Types text into a web element.',
|
491
|
+
example: "await web.element(by.web.name('search')).typeText('Detox');",
|
492
|
+
guidelines: [
|
493
|
+
'Set `isContentEditable` to `true` for content-editable elements on Android.',
|
494
|
+
'On iOS, content-editable elements are automatically detected.',
|
495
|
+
'Supports `asSecured()` on iOS.',
|
496
|
+
],
|
497
|
+
},
|
498
|
+
{
|
499
|
+
signature: 'replaceText(text: string)',
|
500
|
+
description: 'Replaces text in a web element.',
|
501
|
+
example: "await web.element(by.web.name('search')).replaceText('Detox');",
|
502
|
+
guidelines: [
|
503
|
+
'Currently not supported for content-editable elements on Android.',
|
504
|
+
'Supports `asSecured()` on iOS.',
|
505
|
+
],
|
506
|
+
},
|
507
|
+
{
|
508
|
+
signature: 'clearText()',
|
509
|
+
description: 'Clears text from a web element.',
|
510
|
+
example: "await web.element(by.web.name('search')).clearText();",
|
511
|
+
guidelines: [
|
512
|
+
'Currently not supported for content-editable elements on Android.',
|
513
|
+
'Supports `asSecured()` on iOS.',
|
514
|
+
],
|
515
|
+
},
|
516
|
+
{
|
517
|
+
signature: 'selectAllText()',
|
518
|
+
description: 'Selects all text in a web element.',
|
519
|
+
example: "await web.element(by.web.id('editor')).selectAllText();",
|
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
|
+
],
|
524
|
+
},
|
525
|
+
{
|
526
|
+
signature: 'getText()',
|
527
|
+
description: 'Retrieves the text content of a web element.',
|
528
|
+
example: `
|
529
|
+
const text = await web.element(by.web.id('identifier')).getText();
|
530
|
+
jestExpect(text).toBe('Hello World!');
|
531
|
+
`,
|
532
|
+
guidelines: [
|
533
|
+
'Use for assertions on the element\'s text content.',
|
534
|
+
'Requires importing `jestExpect` for assertions.',
|
535
|
+
],
|
536
|
+
},
|
537
|
+
{
|
538
|
+
signature: 'scrollToView()',
|
539
|
+
description: 'Scrolls the web view to bring the element into view.',
|
540
|
+
example: "await web.element(by.web.id('footer')).scrollToView();",
|
541
|
+
},
|
542
|
+
{
|
543
|
+
signature: 'focus()',
|
544
|
+
description: 'Focuses on a web element.',
|
545
|
+
example: "await web.element(by.web.id('search')).focus();",
|
546
|
+
},
|
547
|
+
{
|
548
|
+
signature: 'moveCursorToEnd()',
|
549
|
+
description: 'Moves the input cursor to the end of the element\'s content.',
|
550
|
+
example: "await web.element(by.web.id('editor')).moveCursorToEnd();",
|
551
|
+
guidelines: [
|
552
|
+
'Supported for content-editable elements only on Android.',
|
553
|
+
'On iOS, Detox can move the cursor to the end of any element that supports it.',
|
554
|
+
],
|
555
|
+
},
|
556
|
+
{
|
557
|
+
signature: 'runScript(script: string, args?: any[])',
|
558
|
+
description: 'Runs a JavaScript function on the element.',
|
559
|
+
example: `
|
560
|
+
const webElement = web.element(by.web.id('identifier'));
|
561
|
+
await webElement.runScript('(el) => el.click()');
|
562
|
+
|
563
|
+
// With arguments
|
564
|
+
await webElement.runScript('(el, args) => el.setAttribute("value", args[0])', ['Detox']);
|
565
|
+
|
566
|
+
// Using function syntax
|
567
|
+
const fontSize = await webElement.runScript(function get(element) {
|
568
|
+
return element.style.fontSize;
|
569
|
+
});
|
570
|
+
jestExpect(fontSize).toBe('16px');
|
571
|
+
|
572
|
+
// Scrolling to the bottom of a scrollable web-element
|
573
|
+
await webElement.runScript('el => el.scrollTop = el.scrollHeight');
|
574
|
+
`,
|
575
|
+
guidelines: [
|
576
|
+
'The script can accept additional arguments and return a value.',
|
577
|
+
'Ensure that arguments and return values are serializable.',
|
578
|
+
'Useful for custom interactions or retrieving properties.',
|
579
|
+
],
|
580
|
+
},
|
581
|
+
{
|
582
|
+
signature: 'getCurrentUrl()',
|
583
|
+
description: 'Retrieves the current URL of the web view.',
|
584
|
+
example: `
|
585
|
+
const url = await web.element(by.web.id('identifier')).getCurrentUrl();
|
586
|
+
jestExpect(url).toBe('https://example.com');
|
587
|
+
`,
|
588
|
+
guidelines: [
|
589
|
+
'Must be called from an inner element, not the root web view.',
|
590
|
+
'May have issues on Android; check relevant GitHub issues.',
|
591
|
+
],
|
592
|
+
},
|
593
|
+
{
|
594
|
+
signature: 'getTitle()',
|
595
|
+
description: 'Retrieves the title of the web view.',
|
596
|
+
example: `
|
597
|
+
const title = await web.element(by.web.id('identifier')).getTitle();
|
598
|
+
jestExpect(title).toBe('Welcome Page');
|
599
|
+
`,
|
600
|
+
guidelines: [
|
601
|
+
'Must be called from an inner element, not the root web view.',
|
602
|
+
],
|
603
|
+
},
|
604
|
+
{
|
605
|
+
signature: 'toHaveText(text: string)',
|
606
|
+
description: 'Asserts that the web element has the specified text.',
|
607
|
+
example: "await expect(web.element(by.web.tag('h1'))).toHaveText('Welcome');",
|
608
|
+
},
|
609
|
+
{
|
610
|
+
signature: 'toExist()',
|
611
|
+
description: 'Asserts that the web element exists.',
|
612
|
+
example: "await expect(web.element(by.web.xpath('//*[@id=\"main\"]'))).toExist();",
|
613
|
+
guidelines: [
|
614
|
+
'Supports `asSecured()` on iOS.',
|
615
|
+
],
|
616
|
+
},
|
617
|
+
{
|
618
|
+
signature: 'not',
|
619
|
+
description: 'Negates the expectation for web elements.',
|
620
|
+
example: "await expect(web.element(by.web.id('error'))).not.toExist();",
|
621
|
+
guidelines: [
|
622
|
+
'Supports `asSecured()` on iOS.',
|
623
|
+
],
|
624
|
+
},
|
625
|
+
{
|
626
|
+
signature: 'asSecured()',
|
627
|
+
description: 'Interacts with secured web views (iOS only).',
|
628
|
+
example: "await web.element(by.web.label('Submit')).asSecured().tap();",
|
629
|
+
guidelines: [
|
630
|
+
'Use for web pages with secured protocols when regular interactions fail.',
|
631
|
+
'Available on iOS only and currently experimental.',
|
632
|
+
'Less performant and has fewer APIs.',
|
633
|
+
],
|
634
|
+
},
|
635
|
+
],
|
636
|
+
},
|
307
637
|
],
|
308
638
|
},
|
309
639
|
|
@@ -81,6 +81,8 @@ class DetoxContext {
|
|
81
81
|
|
82
82
|
web = funpermaproxy.callable(() => this[symbols.worker].web);
|
83
83
|
|
84
|
+
system = funpermaproxy.callable(() => this[symbols.worker].system);
|
85
|
+
|
84
86
|
copilot = funpermaproxy.callable(() => this[symbols.worker].copilot);
|
85
87
|
|
86
88
|
get DetoxConstants() {
|
@@ -1 +0,0 @@
|
|
1
|
-
00e771ad7d4bca70272e33279c46e466
|
@@ -1 +0,0 @@
|
|
1
|
-
a6159ac03cb71d378a64cc5ce2edd1785dbda1f9
|
@@ -1 +0,0 @@
|
|
1
|
-
34a26f4fb8f6602196e9ea8cc9e437b30a6f7969ae25aed3b38194b15a342a07
|
@@ -1 +0,0 @@
|
|
1
|
-
0d2eb7a4c0e4704bcc18cece68a788f14a4b5daea69b2b629acb3cefe7952e38e605f7ed827338ac375ee840802b93c9a10e4fe8155cb9be7b2af9a499d69941
|
@@ -1 +0,0 @@
|
|
1
|
-
6e2b31eb45632080d05012110384ed2c
|
@@ -1 +0,0 @@
|
|
1
|
-
63a763fcbfa75f8bb710cb574dfe26abf733752c
|
@@ -1 +0,0 @@
|
|
1
|
-
12142ae0599d9ea97ec70c8ab1aea4b0743f1e7c1ca83aacffbabebfeecf92ec
|
@@ -1 +0,0 @@
|
|
1
|
-
fad2af646bb65acc13528d220795c690668eabe5697c1d94495367e6cb73c55b9fc235b06e5baf2cd1d56a5e8a22df8adc6bde726050316168a8f9ce31be6dd6
|
@@ -1 +0,0 @@
|
|
1
|
-
e1481e091b0d7a1c7da0da248773c085
|
@@ -1 +0,0 @@
|
|
1
|
-
72b5129454784fbbd8bf5e5661c6534bd1d9dd63
|
@@ -1 +0,0 @@
|
|
1
|
-
288dd5edc91a6eee6d96834f5357e946fcb45d7e0302473959199bc37e46ad3a
|
@@ -1 +0,0 @@
|
|
1
|
-
d04dfa63bf863d39e689ba99cf45d2e27204d97cbe71d1cc67ed243e3e2b6637bc5c99654e5bd185dc93e89e716817a6247ea6bf965d9473e018596c8d31bb71
|
@@ -1 +0,0 @@
|
|
1
|
-
31eb9663feea512165f1608e0f4c9660
|
@@ -1 +0,0 @@
|
|
1
|
-
121dadd5b1d1c8db0fe0f7e72da53746e9bd88e8
|
@@ -1 +0,0 @@
|
|
1
|
-
0016623b8e8a15087ccfb15a291b3b8f38d784b97f905034b07a9e172354d670
|
@@ -1 +0,0 @@
|
|
1
|
-
44a518be9a5e8c027288c81948beed0484709f201dee662765b1f4761f0073792748394aaae7537ad0e66837caf74ef2d90286da2b65a0dd8850d862d446736d
|
/package/Detox-android/com/wix/detox/{20.27.2/detox-20.27.2.aar → 20.27.3/detox-20.27.3.aar}
RENAMED
File without changes
|
/package/Detox-android/com/wix/detox/{20.27.2/detox-20.27.2.aar.md5 → 20.27.3/detox-20.27.3.aar.md5}
RENAMED
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|