detox 20.18.10-smoke.0 → 20.19.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (53) hide show
  1. package/Detox-android/com/wix/detox/20.19.0/detox-20.19.0-sources.jar +0 -0
  2. package/Detox-android/com/wix/detox/20.19.0/detox-20.19.0-sources.jar.md5 +1 -0
  3. package/Detox-android/com/wix/detox/20.19.0/detox-20.19.0-sources.jar.sha1 +1 -0
  4. package/Detox-android/com/wix/detox/20.19.0/detox-20.19.0-sources.jar.sha256 +1 -0
  5. package/Detox-android/com/wix/detox/20.19.0/detox-20.19.0-sources.jar.sha512 +1 -0
  6. package/Detox-android/com/wix/detox/20.19.0/detox-20.19.0.aar +0 -0
  7. package/Detox-android/com/wix/detox/20.19.0/detox-20.19.0.aar.md5 +1 -0
  8. package/Detox-android/com/wix/detox/20.19.0/detox-20.19.0.aar.sha1 +1 -0
  9. package/Detox-android/com/wix/detox/20.19.0/detox-20.19.0.aar.sha256 +1 -0
  10. package/Detox-android/com/wix/detox/20.19.0/detox-20.19.0.aar.sha512 +1 -0
  11. package/Detox-android/com/wix/detox/20.19.0/detox-20.19.0.pom +100 -0
  12. package/Detox-android/com/wix/detox/20.19.0/detox-20.19.0.pom.md5 +1 -0
  13. package/Detox-android/com/wix/detox/20.19.0/detox-20.19.0.pom.sha1 +1 -0
  14. package/Detox-android/com/wix/detox/20.19.0/detox-20.19.0.pom.sha256 +1 -0
  15. package/Detox-android/com/wix/detox/20.19.0/detox-20.19.0.pom.sha512 +1 -0
  16. package/Detox-android/com/wix/detox/maven-metadata.xml +13 -0
  17. package/Detox-android/com/wix/detox/maven-metadata.xml.md5 +1 -0
  18. package/Detox-android/com/wix/detox/maven-metadata.xml.sha1 +1 -0
  19. package/Detox-android/com/wix/detox/maven-metadata.xml.sha256 +1 -0
  20. package/Detox-android/com/wix/detox/maven-metadata.xml.sha512 +1 -0
  21. package/Detox-android/com/wix/detox-legacy/20.19.0/detox-legacy-20.19.0-sources.jar +0 -0
  22. package/Detox-android/com/wix/detox-legacy/20.19.0/detox-legacy-20.19.0-sources.jar.md5 +1 -0
  23. package/Detox-android/com/wix/detox-legacy/20.19.0/detox-legacy-20.19.0-sources.jar.sha1 +1 -0
  24. package/Detox-android/com/wix/detox-legacy/20.19.0/detox-legacy-20.19.0-sources.jar.sha256 +1 -0
  25. package/Detox-android/com/wix/detox-legacy/20.19.0/detox-legacy-20.19.0-sources.jar.sha512 +1 -0
  26. package/Detox-android/com/wix/detox-legacy/20.19.0/detox-legacy-20.19.0.aar +0 -0
  27. package/Detox-android/com/wix/detox-legacy/20.19.0/detox-legacy-20.19.0.aar.md5 +1 -0
  28. package/Detox-android/com/wix/detox-legacy/20.19.0/detox-legacy-20.19.0.aar.sha1 +1 -0
  29. package/Detox-android/com/wix/detox-legacy/20.19.0/detox-legacy-20.19.0.aar.sha256 +1 -0
  30. package/Detox-android/com/wix/detox-legacy/20.19.0/detox-legacy-20.19.0.aar.sha512 +1 -0
  31. package/Detox-android/com/wix/detox-legacy/20.19.0/detox-legacy-20.19.0.pom +100 -0
  32. package/Detox-android/com/wix/detox-legacy/20.19.0/detox-legacy-20.19.0.pom.md5 +1 -0
  33. package/Detox-android/com/wix/detox-legacy/20.19.0/detox-legacy-20.19.0.pom.sha1 +1 -0
  34. package/Detox-android/com/wix/detox-legacy/20.19.0/detox-legacy-20.19.0.pom.sha256 +1 -0
  35. package/Detox-android/com/wix/detox-legacy/20.19.0/detox-legacy-20.19.0.pom.sha512 +1 -0
  36. package/Detox-android/com/wix/detox-legacy/maven-metadata.xml +13 -0
  37. package/Detox-android/com/wix/detox-legacy/maven-metadata.xml.md5 +1 -0
  38. package/Detox-android/com/wix/detox-legacy/maven-metadata.xml.sha1 +1 -0
  39. package/Detox-android/com/wix/detox-legacy/maven-metadata.xml.sha256 +1 -0
  40. package/Detox-android/com/wix/detox-legacy/maven-metadata.xml.sha512 +1 -0
  41. package/Detox-ios-src.tbz +0 -0
  42. package/Detox-ios.tbz +0 -0
  43. package/detox.d.ts +27 -8
  44. package/package.json +2 -2
  45. package/src/android/core/WebElement.js +27 -15
  46. package/src/client/Client.js +6 -1
  47. package/src/devices/allocation/drivers/android/genycloud/exec/GenyCloudExec.js +0 -4
  48. package/src/devices/validation/android/GenycloudEnvValidator.js +1 -12
  49. package/src/devices/validation/factories/index.js +1 -4
  50. package/src/ios/expectTwo.js +28 -6
  51. package/src/ios/web.js +293 -0
  52. package/src/utils/invocationTraceDescriptions.js +16 -0
  53. package/src/devices/allocation/drivers/android/genycloud/services/GenyAuthService.js +0 -12
@@ -0,0 +1 @@
1
+ 93da431e849afaaada5a954c32d35f44
@@ -0,0 +1 @@
1
+ bc8c6b4083b5d2ad3a5e88ee9031f2ea10793f8e
@@ -0,0 +1 @@
1
+ ea68075a8963f48ee52e873efb8d8fb027cb46c6a33e55aafca72559b219dd62
@@ -0,0 +1 @@
1
+ eb8fef410b6faa599991d7b15c76f2118dcfde5843608519fed029252cacf05f3c6a95e1c92b673b7ecf2c35e7e5b4a7608308d0361e75fad9e212133faa2ce4
@@ -0,0 +1 @@
1
+ 221afe495c4ff28f344cff35e41e566a
@@ -0,0 +1 @@
1
+ 9657a291e6e1725adb2a3e333248ad4a05892015
@@ -0,0 +1 @@
1
+ 23a9f6a86b0fb26b426f6188be04dc98eed5edeaa7f77c6e682bae9b80906312
@@ -0,0 +1 @@
1
+ a43c0a36b2b519a777662f087ba88e2bf781613ec86633434499ba70483fe072ebbbff6507f3ec3cb1cff7bfd5326af172d6fe7dcdc7990790796fe97d9c1519
@@ -0,0 +1,100 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <project xmlns="http://maven.apache.org/POM/4.0.0" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
3
+ <modelVersion>4.0.0</modelVersion>
4
+ <groupId>com.wix</groupId>
5
+ <artifactId>detox</artifactId>
6
+ <version>20.19.0</version>
7
+ <packaging>aar</packaging>
8
+ <name>Detox</name>
9
+ <description>Gray box end-to-end testing and automation library for mobile apps</description>
10
+ <url>https://github.com/wix/Detox</url>
11
+ <licenses>
12
+ <license>
13
+ <name>The MIT License</name>
14
+ <url>https://github.com/wix/Detox/blob/master/LICENSE</url>
15
+ </license>
16
+ </licenses>
17
+ <developers>
18
+ <developer>
19
+ <name>WixMobile</name>
20
+ <email>mobile1@wix.com</email>
21
+ </developer>
22
+ <developer>
23
+ <name>d4vidi</name>
24
+ <email>amitd@wix.com</email>
25
+ </developer>
26
+ </developers>
27
+ <scm>
28
+ <connection>scm:git:git://github.com/wix/detox.git</connection>
29
+ <developerConnection>scm:git:git@github.com/wix/detox.git</developerConnection>
30
+ <url>https://github.com/wix/detox</url>
31
+ </scm>
32
+ <dependencies>
33
+ <dependency>
34
+ <groupId>androidx.test.espresso</groupId>
35
+ <artifactId>espresso-core</artifactId>
36
+ <version>3.5.1</version>
37
+ <scope>compile</scope>
38
+ </dependency>
39
+ <dependency>
40
+ <groupId>androidx.test.espresso</groupId>
41
+ <artifactId>espresso-web</artifactId>
42
+ <version>3.5.1</version>
43
+ <scope>compile</scope>
44
+ </dependency>
45
+ <dependency>
46
+ <groupId>androidx.test.espresso</groupId>
47
+ <artifactId>espresso-contrib</artifactId>
48
+ <version>3.5.1</version>
49
+ <scope>compile</scope>
50
+ <exclusions>
51
+ <exclusion>
52
+ <groupId>org.checkerframework</groupId>
53
+ <artifactId>checker</artifactId>
54
+ </exclusion>
55
+ </exclusions>
56
+ </dependency>
57
+ <dependency>
58
+ <groupId>org.hamcrest</groupId>
59
+ <artifactId>hamcrest</artifactId>
60
+ <version>2.2</version>
61
+ <scope>compile</scope>
62
+ </dependency>
63
+ <dependency>
64
+ <groupId>androidx.test</groupId>
65
+ <artifactId>rules</artifactId>
66
+ <version>1.5.0</version>
67
+ <scope>compile</scope>
68
+ </dependency>
69
+ <dependency>
70
+ <groupId>androidx.test.ext</groupId>
71
+ <artifactId>junit</artifactId>
72
+ <version>1.1.5</version>
73
+ <scope>compile</scope>
74
+ </dependency>
75
+ <dependency>
76
+ <groupId>androidx.test.uiautomator</groupId>
77
+ <artifactId>uiautomator</artifactId>
78
+ <version>2.2.0</version>
79
+ <scope>compile</scope>
80
+ </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
+ <dependency>
88
+ <groupId>org.apache.commons</groupId>
89
+ <artifactId>commons-lang3</artifactId>
90
+ <version>3.7</version>
91
+ <scope>runtime</scope>
92
+ </dependency>
93
+ <dependency>
94
+ <groupId>com.github.anrwatchdog</groupId>
95
+ <artifactId>anrwatchdog</artifactId>
96
+ <version>1.4.0</version>
97
+ <scope>runtime</scope>
98
+ </dependency>
99
+ </dependencies>
100
+ </project>
@@ -0,0 +1 @@
1
+ c6d8c8257e300db4afc240ddac881ed6
@@ -0,0 +1 @@
1
+ 1fc4b40c3eb57f43eb34f0a797b04f468aed6f81
@@ -0,0 +1 @@
1
+ 07bb45f9dc99d5433808324ee4d2b306475f6b3afaba4f188f995fb8f3af3941
@@ -0,0 +1 @@
1
+ b700eac54c47c0f601f8d12334745bba02cf6ff861b883c8aae02b203f4298ba8205ac2746466d5e120b5a6ddeda915343f04680b0a1a0380e44c5369ab1e06d
@@ -0,0 +1,13 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <metadata>
3
+ <groupId>com.wix</groupId>
4
+ <artifactId>detox</artifactId>
5
+ <versioning>
6
+ <latest>20.19.0</latest>
7
+ <release>20.19.0</release>
8
+ <versions>
9
+ <version>20.19.0</version>
10
+ </versions>
11
+ <lastUpdated>20240312084805</lastUpdated>
12
+ </versioning>
13
+ </metadata>
@@ -0,0 +1 @@
1
+ e759f9b47be57b3bf681c63f63a6cc91
@@ -0,0 +1 @@
1
+ 9997bb72b5c4ded3260eb24e5f5c9c77eb8e3df2
@@ -0,0 +1 @@
1
+ 7b2e03fba4720f0b7a37fb4ae546b478379eb65c58d67bf25bfe408c8edbabce
@@ -0,0 +1 @@
1
+ 71b33008992d4d0da6fb609f2b829cc3f7120fb68087799eedc05d3e554e695b258a4ce07a65d34b57c5fb8e77317b6cf92a9c7d51f020cd6744866fdb02e054
@@ -0,0 +1 @@
1
+ 524fd7892c84c981fec999b10e7de40a
@@ -0,0 +1 @@
1
+ de1b48f46528186dca92b5fee117232162f9eecf
@@ -0,0 +1 @@
1
+ 5960e46c650514431d817239f5053eedcd2d9889ab584ae064b473aceb413700
@@ -0,0 +1 @@
1
+ 7f39d4ff2d1ea6ce1ab72014084e2db06cc0219ee19e5d9c1d3ff9ad8d24c95b6ae995539cd8379f6d18ec62a8dab836f707c28e6b3d44bea072a016c82c6d79
@@ -0,0 +1 @@
1
+ 2ccac07d6c4079ce6a948d8cb8e78985
@@ -0,0 +1 @@
1
+ e3b8881d1f3a9ff8c71cdfa84a7cc2a69b025401
@@ -0,0 +1 @@
1
+ 73266b3affb9ce645c35133ef28db777e3e321343d9b7d946610b2178b5b3863
@@ -0,0 +1 @@
1
+ d9032a388871d30165507ca248712125a3cf6f5443b2a74eed35ab3a4a075d9a6c5c631e0d80395b66b465a464e4ee7f795a65acbeb3b6082177eabafe29e1b5
@@ -0,0 +1,100 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <project xmlns="http://maven.apache.org/POM/4.0.0" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
3
+ <modelVersion>4.0.0</modelVersion>
4
+ <groupId>com.wix</groupId>
5
+ <artifactId>detox-legacy</artifactId>
6
+ <version>20.19.0</version>
7
+ <packaging>aar</packaging>
8
+ <name>Detox</name>
9
+ <description>Gray box end-to-end testing and automation library for mobile apps</description>
10
+ <url>https://github.com/wix/Detox</url>
11
+ <licenses>
12
+ <license>
13
+ <name>The MIT License</name>
14
+ <url>https://github.com/wix/Detox/blob/master/LICENSE</url>
15
+ </license>
16
+ </licenses>
17
+ <developers>
18
+ <developer>
19
+ <name>WixMobile</name>
20
+ <email>mobile1@wix.com</email>
21
+ </developer>
22
+ <developer>
23
+ <name>d4vidi</name>
24
+ <email>amitd@wix.com</email>
25
+ </developer>
26
+ </developers>
27
+ <scm>
28
+ <connection>scm:git:git://github.com/wix/detox.git</connection>
29
+ <developerConnection>scm:git:git@github.com/wix/detox.git</developerConnection>
30
+ <url>https://github.com/wix/detox</url>
31
+ </scm>
32
+ <dependencies>
33
+ <dependency>
34
+ <groupId>androidx.test.espresso</groupId>
35
+ <artifactId>espresso-core</artifactId>
36
+ <version>3.5.1</version>
37
+ <scope>compile</scope>
38
+ </dependency>
39
+ <dependency>
40
+ <groupId>androidx.test.espresso</groupId>
41
+ <artifactId>espresso-web</artifactId>
42
+ <version>3.5.1</version>
43
+ <scope>compile</scope>
44
+ </dependency>
45
+ <dependency>
46
+ <groupId>androidx.test.espresso</groupId>
47
+ <artifactId>espresso-contrib</artifactId>
48
+ <version>3.5.1</version>
49
+ <scope>compile</scope>
50
+ <exclusions>
51
+ <exclusion>
52
+ <groupId>org.checkerframework</groupId>
53
+ <artifactId>checker</artifactId>
54
+ </exclusion>
55
+ </exclusions>
56
+ </dependency>
57
+ <dependency>
58
+ <groupId>org.hamcrest</groupId>
59
+ <artifactId>hamcrest</artifactId>
60
+ <version>2.2</version>
61
+ <scope>compile</scope>
62
+ </dependency>
63
+ <dependency>
64
+ <groupId>androidx.test</groupId>
65
+ <artifactId>rules</artifactId>
66
+ <version>1.5.0</version>
67
+ <scope>compile</scope>
68
+ </dependency>
69
+ <dependency>
70
+ <groupId>androidx.test.ext</groupId>
71
+ <artifactId>junit</artifactId>
72
+ <version>1.1.5</version>
73
+ <scope>compile</scope>
74
+ </dependency>
75
+ <dependency>
76
+ <groupId>androidx.test.uiautomator</groupId>
77
+ <artifactId>uiautomator</artifactId>
78
+ <version>2.2.0</version>
79
+ <scope>compile</scope>
80
+ </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
+ <dependency>
88
+ <groupId>org.apache.commons</groupId>
89
+ <artifactId>commons-lang3</artifactId>
90
+ <version>3.7</version>
91
+ <scope>runtime</scope>
92
+ </dependency>
93
+ <dependency>
94
+ <groupId>com.github.anrwatchdog</groupId>
95
+ <artifactId>anrwatchdog</artifactId>
96
+ <version>1.4.0</version>
97
+ <scope>runtime</scope>
98
+ </dependency>
99
+ </dependencies>
100
+ </project>
@@ -0,0 +1 @@
1
+ bbfb7226e948f6c39940107f277c04c3
@@ -0,0 +1 @@
1
+ e4717b8e2067de946b0e86a78807ee2fab2d6221
@@ -0,0 +1 @@
1
+ 6e390e43db070e682fc99eceedc9944bd27bef9e3933458d9b511c480f39884b
@@ -0,0 +1 @@
1
+ 204a67a2c7d0cead067e8b437e79ed9a4e0b2bdd6ccd049a7e508701608e90007740644f3c68fa5bf47410a262a025d5c5d633f3feff6b20e3c8846172e7a6e5
@@ -0,0 +1,13 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <metadata>
3
+ <groupId>com.wix</groupId>
4
+ <artifactId>detox-legacy</artifactId>
5
+ <versioning>
6
+ <latest>20.19.0</latest>
7
+ <release>20.19.0</release>
8
+ <versions>
9
+ <version>20.19.0</version>
10
+ </versions>
11
+ <lastUpdated>20240312084842</lastUpdated>
12
+ </versioning>
13
+ </metadata>
@@ -0,0 +1 @@
1
+ 247fae7567595e8ce8c6b440d3ffa13f
@@ -0,0 +1 @@
1
+ fe36e55336b83bfebe1f369f82ad9f5d58644c13
@@ -0,0 +1 @@
1
+ 34722d13589064242a26f9edf746ab1e29719cd05eb538e8fbaa4a80428f5bfd
@@ -0,0 +1 @@
1
+ 380dba4eb8e7a9032f6470f7a535bc31ab3501594bf354157616bc49c0a9eff2f9d102b05e96317005af560524cd0004d9fc66465a1390504381f453ee9fb733
package/Detox-ios-src.tbz CHANGED
Binary file
package/Detox-ios.tbz CHANGED
Binary file
package/detox.d.ts CHANGED
@@ -1137,7 +1137,21 @@ declare global {
1137
1137
  }
1138
1138
 
1139
1139
  interface WebViewElement {
1140
+ /**
1141
+ * Find a web element by a matcher.
1142
+ * @param webMatcher a web matcher for the web element.
1143
+ */
1140
1144
  element(webMatcher: WebMatcher): IndexableWebElement;
1145
+
1146
+ /**
1147
+ * Returns the index-th web-view in the UI hierarchy that is matched by the given matcher.
1148
+ * @param index the index of the web-view.
1149
+ *
1150
+ * @note Currently, supported only for iOS.
1151
+ *
1152
+ * @example await web(by.id('webview')).atIndex(1);
1153
+ */
1154
+ atIndex(index: number): WebViewElement;
1141
1155
  }
1142
1156
 
1143
1157
  interface WebFacade extends WebViewElement {
@@ -1507,8 +1521,8 @@ declare global {
1507
1521
 
1508
1522
  interface IndexableWebElement extends WebElement {
1509
1523
  /**
1510
- * Choose from multiple elements matching the same matcher using index
1511
- * @example await web.element(by.web.hrefContains('Details')).atIndex(2).tap();
1524
+ * Choose from multiple elements matching the same matcher using index.
1525
+ * @example await web.element(by.web.tag('p')).atIndex(2).tap();
1512
1526
  */
1513
1527
  atIndex(index: number): WebElement;
1514
1528
  }
@@ -1520,24 +1534,27 @@ declare global {
1520
1534
  tap(): Promise<void>;
1521
1535
 
1522
1536
  /**
1537
+ * Type text into a web element.
1523
1538
  * @param text to type
1524
- * @param isContentEditable whether its a ContentEditable element, default is false.
1539
+ * @param isContentEditable whether the element is content-editable, default is false. Ignored on iOS.
1525
1540
  */
1526
1541
  typeText(text: string, isContentEditable: boolean): Promise<void>;
1527
1542
 
1528
1543
  /**
1529
- * At the moment not working on content-editable
1544
+ * Replaces the input content with the new text.
1545
+ * @note On Android, not working for content-editable elements.
1530
1546
  * @param text to replace with the old content.
1531
1547
  */
1532
1548
  replaceText(text: string): Promise<void>;
1533
1549
 
1534
1550
  /**
1535
- * At the moment not working on content-editable
1551
+ * Clears the input content.
1552
+ * @note On Android, not working for content-editable elements.
1536
1553
  */
1537
1554
  clearText(): Promise<void>;
1538
1555
 
1539
1556
  /**
1540
- * scrolling to the view, the element top position will be at the top of the screen.
1557
+ * Scrolling to the view, the element top position will be at the top of the screen.
1541
1558
  */
1542
1559
  scrollToView(): Promise<void>;
1543
1560
 
@@ -1552,12 +1569,14 @@ declare global {
1552
1569
  focus(): Promise<void>;
1553
1570
 
1554
1571
  /**
1555
- * Selects all the input content, works on ContentEditable at the moment.
1572
+ * Selects all the input content.
1573
+ * @note On Android, it works only for content-editable elements.
1556
1574
  */
1557
1575
  selectAllText(): Promise<void>;
1558
1576
 
1559
1577
  /**
1560
- * Moves the input cursor / caret to the end of the content, works on ContentEditable at the moment.
1578
+ * Moves the input cursor to the end of the content.
1579
+ * @note On Android, it works only for content-editable elements.
1561
1580
  */
1562
1581
  moveCursorToEnd(): Promise<void>;
1563
1582
 
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.18.10-smoke.0",
4
+ "version": "20.19.0",
5
5
  "bin": {
6
6
  "detox": "local-cli/cli.js"
7
7
  },
@@ -115,5 +115,5 @@
115
115
  "browserslist": [
116
116
  "node 18"
117
117
  ],
118
- "gitHead": "d0e36c797acb5932e26c9bf2d64d2e2f8243a9b1"
118
+ "gitHead": "4ddafb71ed2207a4f0cad9038421e94f2670f81a"
119
119
  }
@@ -22,6 +22,7 @@ class WebElement {
22
22
  this[_invocationManager] = invocationManager;
23
23
  this[_webMatcher] = webMatcher;
24
24
  this[_webViewElement] = webViewElement;
25
+
25
26
  this.atIndex(0);
26
27
  }
27
28
 
@@ -33,64 +34,70 @@ class WebElement {
33
34
  return this;
34
35
  }
35
36
 
36
- // At the moment not working on content-editable
37
+ async executeAction(action) {
38
+ const result = await new ActionInteraction(this[_invocationManager], action).execute();
39
+ // Workaround since Detox doesn't wait for the action to complete.
40
+ await new Promise(resolve => setTimeout(resolve, 500));
41
+ return result;
42
+ }
43
+
37
44
  async tap() {
38
- return await new ActionInteraction(this[_invocationManager], new actions.WebTapAction(this)).execute();
45
+ return await this.executeAction(new actions.WebTapAction(this));
39
46
  }
40
47
 
41
48
  async typeText(text, isContentEditable = false) {
42
49
  if (isContentEditable) {
43
50
  return await this[_device]._typeText(text);
44
51
  }
45
- return await new ActionInteraction(this[_invocationManager], new actions.WebTypeTextAction(this, text)).execute();
52
+ return await this.executeAction(new actions.WebTypeTextAction(this, text));
46
53
  }
47
54
 
48
55
  // At the moment not working on content-editable
49
56
  async replaceText(text) {
50
- return await new ActionInteraction(this[_invocationManager], new actions.WebReplaceTextAction(this, text)).execute();
57
+ return await this.executeAction(new actions.WebReplaceTextAction(this, text));
51
58
  }
52
59
 
53
60
  // At the moment not working on content-editable
54
61
  async clearText() {
55
- return await new ActionInteraction(this[_invocationManager], new actions.WebClearTextAction(this)).execute();
62
+ return await this.executeAction(new actions.WebClearTextAction(this));
56
63
  }
57
64
 
58
65
  async scrollToView() {
59
- return await new ActionInteraction(this[_invocationManager], new actions.WebScrollToViewAction(this)).execute();
66
+ return await this.executeAction(new actions.WebScrollToViewAction(this));
60
67
  }
61
68
 
62
69
  async getText() {
63
- return await new ActionInteraction(this[_invocationManager], new actions.WebGetTextAction(this)).execute();
70
+ return await this.executeAction(new actions.WebGetTextAction(this));
64
71
  }
65
72
 
66
73
  async focus() {
67
- return await new ActionInteraction(this[_invocationManager], new actions.WebFocusAction(this)).execute();
74
+ return await this.executeAction(new actions.WebFocusAction(this));
68
75
  }
69
76
 
70
77
  async selectAllText() {
71
- return await new ActionInteraction(this[_invocationManager], new actions.WebSelectAllText(this)).execute();
78
+ return await this.executeAction(new actions.WebSelectAllText(this));
72
79
  }
73
80
 
74
81
  async moveCursorToEnd() {
75
- return await new ActionInteraction(this[_invocationManager], new actions.WebMoveCursorEnd(this)).execute();
82
+ return await this.executeAction(new actions.WebMoveCursorEnd(this));
76
83
  }
77
84
 
78
85
  async runScript(maybeFunction, args) {
79
86
  const script = stringifyScript(maybeFunction);
80
87
 
81
88
  if (args) {
82
- return await new ActionInteraction(this[_invocationManager], new actions.WebRunScriptWithArgsAction(this, script, args)).execute();
89
+ return await this.executeAction(new actions.WebRunScriptWithArgsAction(this, script, args));
83
90
  } else {
84
- return await new ActionInteraction(this[_invocationManager], new actions.WebRunScriptAction(this, script)).execute();
91
+ return await this.executeAction(new actions.WebRunScriptAction(this, script));
85
92
  }
86
93
  }
87
94
 
88
95
  async getCurrentUrl() {
89
- return await new ActionInteraction(this[_invocationManager], new actions.WebGetCurrentUrlAction(this)).execute();
96
+ return await this.executeAction(new actions.WebGetCurrentUrlAction(this));
90
97
  }
91
98
 
92
99
  async getTitle() {
93
- return await new ActionInteraction(this[_invocationManager], new actions.WebGetTitleAction(this)).execute();
100
+ return await this.executeAction(new actions.WebGetTitleAction(this));
94
101
  }
95
102
  }
96
103
 
@@ -105,7 +112,7 @@ class WebViewElement {
105
112
  this._call = invoke.callDirectly(EspressoWebDetoxApi.getWebView(matcher._call.value));
106
113
  } else {
107
114
  this._call = invoke.callDirectly(EspressoWebDetoxApi.getWebView());
108
- }
115
+ }
109
116
 
110
117
  this.element = this.element.bind(this);
111
118
  }
@@ -122,6 +129,11 @@ class WebViewElement {
122
129
 
123
130
  throw new DetoxRuntimeError(`element() argument is invalid, expected a web matcher, but got ${typeof webMatcher}`);
124
131
  }
132
+
133
+ atIndex(_index) {
134
+ // Not implemented yet
135
+ throw new Error('atIndex() is not supported for Android WebViewElement');
136
+ }
125
137
  }
126
138
 
127
139
  function stringifyScript(maybeFunction) {
@@ -137,6 +137,10 @@ class Client {
137
137
  }
138
138
 
139
139
  async sendAction(action) {
140
+ if (this._pendingAppCrash) {
141
+ throw this._pendingAppCrash;
142
+ }
143
+
140
144
  const { shouldQueryStatus, ...options } = this._inferSendOptions(action);
141
145
 
142
146
  return await (shouldQueryStatus
@@ -302,6 +306,8 @@ class Client {
302
306
  }
303
307
 
304
308
  _onAppConnected() {
309
+ this._pendingAppCrash = null;
310
+
305
311
  if (this._whenAppIsConnected.isPending()) {
306
312
  this._whenAppIsConnected.resolve();
307
313
  } else {
@@ -352,7 +358,6 @@ class Client {
352
358
  if (this._pendingAppCrash) {
353
359
  this._whenAppDisconnected.reject(this._pendingAppCrash);
354
360
  this._asyncWebSocket.rejectAll(this._pendingAppCrash);
355
- this._pendingAppCrash = null;
356
361
  } else if (this._asyncWebSocket.hasPendingActions()) {
357
362
  const error = new DetoxRuntimeError('The app has unexpectedly disconnected from Detox server.');
358
363
  this._asyncWebSocket.rejectAll(error);
@@ -11,10 +11,6 @@ class GenyCloudExec {
11
11
  return this._exec('--version');
12
12
  }
13
13
 
14
- whoAmI() {
15
- return this._exec('auth whoami');
16
- }
17
-
18
14
  getRecipe(name) {
19
15
  return this._exec(`recipes list --name "${name}"`);
20
16
  }
@@ -12,15 +12,13 @@ class GenycloudEnvValidator extends EnvironmentValidatorBase {
12
12
  * @param authService { GenyAuthService }
13
13
  * @param exec { GenyCloudExec }
14
14
  */
15
- constructor({ authService, exec }) {
15
+ constructor({ exec }) {
16
16
  super();
17
- this._authService = authService;
18
17
  this._exec = exec;
19
18
  }
20
19
 
21
20
  async validate() {
22
21
  await this._validateGmsaasVersion();
23
- await this._validateGmsaasAuth();
24
22
  }
25
23
 
26
24
  async _validateGmsaasVersion() {
@@ -32,15 +30,6 @@ class GenycloudEnvValidator extends EnvironmentValidatorBase {
32
30
  });
33
31
  }
34
32
  }
35
-
36
- async _validateGmsaasAuth() {
37
- if (!await this._authService.getLoginEmail()) {
38
- throw new DetoxRuntimeError({
39
- message: `Cannot run tests using 'android.genycloud' type devices, because Genymotion was not logged-in to!`,
40
- hint: `Log-in to Genymotion-cloud by running this command (and following instructions):\n${environment.getGmsaasPath()} auth login --help`,
41
- });
42
- }
43
- }
44
33
  }
45
34
 
46
35
  module.exports = GenycloudEnvValidator;
@@ -7,11 +7,8 @@ class Genycloud extends EnvValidatorFactory {
7
7
  const serviceLocator = require('../../servicelocator/android');
8
8
  const exec = serviceLocator.genycloud.exec;
9
9
 
10
- const GenyAuthService = require('../../allocation/drivers/android/genycloud/services/GenyAuthService');
11
- const authService = new GenyAuthService(exec);
12
-
13
10
  const GenycloudEnvValidator = require('../android/GenycloudEnvValidator');
14
- return new GenycloudEnvValidator({ authService, exec });
11
+ return new GenycloudEnvValidator({ exec });
15
12
  }
16
13
  }
17
14
 
@@ -6,6 +6,7 @@ const fs = require('fs-extra');
6
6
  const _ = require('lodash');
7
7
  const tempfile = require('tempfile');
8
8
 
9
+
9
10
  const { assertEnum, assertNormalized } = require('../utils/assertArgument');
10
11
  const { removeMilliseconds } = require('../utils/dateUtils');
11
12
  const { actionDescription, expectDescription } = require('../utils/invocationTraceDescriptions');
@@ -13,6 +14,8 @@ const { isRegExp } = require('../utils/isRegExp');
13
14
  const log = require('../utils/logger').child({ cat: 'ws-client, ws' });
14
15
  const traceInvocationCall = require('../utils/traceInvocationCall').bind(null, log);
15
16
 
17
+ const { webElement, webMatcher, webExpect, isWebElement } = require('./web');
18
+
16
19
  const assertDirection = assertEnum(['left', 'right', 'up', 'down']);
17
20
  const assertSpeed = assertEnum(['fast', 'slow']);
18
21
 
@@ -26,7 +29,7 @@ class Expect {
26
29
  toBeVisible(percent) {
27
30
  if (percent !== undefined && (!Number.isSafeInteger(percent) || percent < 1 || percent > 100)) {
28
31
  throw new Error('`percent` must be an integer between 1 and 100, but got '
29
- + (percent + (' (' + (typeof percent + ')'))));
32
+ + (percent + (' (' + (typeof percent + ')'))));
30
33
  }
31
34
 
32
35
  const traceDescription = expectDescription.toBeVisible(percent);
@@ -170,7 +173,7 @@ class Element {
170
173
  }
171
174
 
172
175
  longPressAndDrag(duration, normalizedPositionX, normalizedPositionY, targetElement,
173
- normalizedTargetPositionX = NaN, normalizedTargetPositionY = NaN, speed = 'fast', holdDuration = 1000) {
176
+ normalizedTargetPositionX = NaN, normalizedTargetPositionY = NaN, speed = 'fast', holdDuration = 1000) {
174
177
  if (typeof duration !== 'number') throw new Error('duration should be a number, but got ' + (duration + (' (' + (typeof duration + ')'))));
175
178
 
176
179
  if (!(targetElement instanceof Element)) throwElementError(targetElement);
@@ -403,7 +406,7 @@ class By {
403
406
  }
404
407
 
405
408
  get web() {
406
- throw new Error('Detox does not support by.web matchers on iOS.');
409
+ return webMatcher();
407
410
  }
408
411
  }
409
412
 
@@ -758,7 +761,7 @@ class IosExpect {
758
761
  this.waitFor = this.waitFor.bind(this);
759
762
  this.by = new By();
760
763
  this.web = this.web.bind(this);
761
- this.web.element = this.web;
764
+ this.web.element = this.web().element;
762
765
  }
763
766
 
764
767
  element(matcher) {
@@ -766,6 +769,10 @@ class IosExpect {
766
769
  }
767
770
 
768
771
  expect(element) {
772
+ if (isWebElement(element)) {
773
+ return webExpect(this._invocationManager, element);
774
+ }
775
+
769
776
  return expect(this._invocationManager, element);
770
777
  }
771
778
 
@@ -773,8 +780,23 @@ class IosExpect {
773
780
  return waitFor(this._invocationManager, this._emitter, element);
774
781
  }
775
782
 
776
- web(_matcher) {
777
- throw new Error('Detox does not support web(), web.element() API on iOS.');
783
+ web(matcher) {
784
+ return {
785
+ atIndex: index => {
786
+ if (typeof index !== 'number' || index < 0) throw new Error('index should be an integer, got ' + (index + (' (' + (typeof index + ')'))));
787
+ if (!(matcher instanceof Matcher)) throw new Error('cannot apply atIndex to a non-matcher');
788
+ matcher.index = index;
789
+ return this.web(matcher);
790
+ },
791
+ element: webMatcher => {
792
+ if (!(matcher instanceof Matcher) && matcher !== undefined) {
793
+ throwMatcherError(matcher);
794
+ }
795
+
796
+ const webViewElement = matcher ? element(this._invocationManager, this._emitter, matcher) : undefined;
797
+ return webElement(this._invocationManager, this._emitter, webViewElement, webMatcher);
798
+ }
799
+ };
778
800
  }
779
801
  }
780
802
 
package/src/ios/web.js ADDED
@@ -0,0 +1,293 @@
1
+ const assert = require('assert');
2
+
3
+ const _ = require('lodash');
4
+
5
+ const { DetoxRuntimeError } = require('../errors');
6
+ const { webViewActionDescription, expectDescription } = require('../utils/invocationTraceDescriptions');
7
+ const log = require('../utils/logger').child({ cat: 'ws-client, ws' });
8
+ const traceInvocationCall = require('../utils/traceInvocationCall').bind(null, log);
9
+
10
+
11
+ class WebExpect {
12
+ constructor(invocationManager, element) {
13
+ this._invocationManager = invocationManager;
14
+ this.element = element;
15
+ this.modifiers = [];
16
+ }
17
+
18
+ toHaveText(text) {
19
+ if (typeof text !== 'string') throw new DetoxRuntimeError('text should be a string, but got ' + (text + (' (' + (typeof text + ')'))));
20
+ const traceDescription = expectDescription.toHaveText(text);
21
+ return this.expect('toHaveText', traceDescription, text);
22
+ }
23
+
24
+ toExist() {
25
+ const traceDescription = expectDescription.toExist();
26
+ return this.expect('toExist', traceDescription);
27
+ }
28
+
29
+ get not() {
30
+ this.modifiers.push('not');
31
+ return this;
32
+ }
33
+
34
+ createInvocation(webExpectation, ...params) {
35
+ const definedParams = _.without(params, undefined);
36
+ return {
37
+ type: 'webExpectation',
38
+ ...(this.element.webViewElement !== undefined) && {
39
+ predicate: this.element.webViewElement.matcher.predicate,
40
+ ...(this.element.webViewElement.matcher.index !== undefined && { atIndex: this.element.webViewElement.matcher.index }),
41
+ },
42
+ webPredicate: this.element.matcher.predicate,
43
+ ...(this.element.index !== undefined && { webAtIndex: this.element.index }),
44
+ ...(this.modifiers.length !== 0 && { webModifiers: this.modifiers }),
45
+ webExpectation,
46
+ ...(definedParams.length !== 0 && { params: definedParams })
47
+ };
48
+ }
49
+
50
+ expect(expectation, traceDescription, ...params) {
51
+ assert(traceDescription, `must provide trace description for expectation: \n ${JSON.stringify(expectation)}`);
52
+
53
+ const invocation = this.createInvocation(expectation, ...params);
54
+ traceDescription = expectDescription.full(traceDescription, this.modifiers.includes('not'));
55
+ return _executeInvocation(this._invocationManager, invocation, traceDescription);
56
+ }
57
+ }
58
+
59
+ class WebElement {
60
+ constructor(invocationManager, emitter, webViewElement, matcher, index) {
61
+ this._invocationManager = invocationManager;
62
+ this._emitter = emitter;
63
+ this.webViewElement = webViewElement;
64
+ this.matcher = matcher;
65
+ this.index = index;
66
+ }
67
+
68
+ atIndex(index) {
69
+ if (typeof index !== 'number' || index < 0) throw new DetoxRuntimeError(`index should be an integer, got ${index} (${typeof index})`);
70
+ this.index = index;
71
+ return this;
72
+ }
73
+
74
+ tap() {
75
+ const traceDescription = webViewActionDescription.tap();
76
+ return this.withAction('tap', traceDescription);
77
+ }
78
+
79
+ typeText(text, isContentEditable = false) {
80
+ const traceDescription = webViewActionDescription.typeText(text, isContentEditable);
81
+ return this.withAction('typeText', traceDescription, text);
82
+ }
83
+
84
+ replaceText(text) {
85
+ const traceDescription = webViewActionDescription.replaceText(text);
86
+ return this.withAction('replaceText', traceDescription, text);
87
+ }
88
+
89
+ clearText() {
90
+ const traceDescription = webViewActionDescription.clearText();
91
+ return this.withAction('clearText', traceDescription);
92
+ }
93
+
94
+ selectAllText() {
95
+ const traceDescription = webViewActionDescription.selectAllText();
96
+ return this.withAction('selectAllText', traceDescription);
97
+ }
98
+
99
+ async getText() {
100
+ const traceDescription = webViewActionDescription.getText();
101
+ let result = await this.withAction('getText', traceDescription);
102
+ return this.extractResult(result, { type: 'text' });
103
+ }
104
+
105
+ extractResult(result, options) {
106
+ // iOS returns the result under `result` key, while Android returns it under the action `type` key.
107
+ if (result['error']) {
108
+ throw new DetoxRuntimeError(`Error thrown in web action: ${result['error']}`);
109
+ } else if (options.type && result[options.type]) {
110
+ return result[options.type];
111
+ } else if (result['result']) {
112
+ return result['result'];
113
+ } else if (options.allowUndefined && Object.keys(result).length === 0) {
114
+ return undefined;
115
+ } else {
116
+ log.warn(`Failed to extract ${options.type ?? 'result'} from result: ${JSON.stringify(result)}`);
117
+ return result;
118
+ }
119
+ }
120
+
121
+ scrollToView() {
122
+ const traceDescription = webViewActionDescription.scrollToView();
123
+ return this.withAction('scrollToView', traceDescription);
124
+ }
125
+
126
+ focus() {
127
+ const traceDescription = webViewActionDescription.focus();
128
+ return this.withAction('focus', traceDescription);
129
+ }
130
+
131
+ moveCursorToEnd() {
132
+ const traceDescription = webViewActionDescription.moveCursorToEnd();
133
+ return this.withAction('moveCursorToEnd', traceDescription);
134
+ }
135
+
136
+ async runScript(script, args) {
137
+ if (args !== undefined && args.length !== 0) {
138
+ return await this.runScriptWithArgs(script, args);
139
+ }
140
+
141
+ if (typeof script === 'function') {
142
+ script = script.toString();
143
+ }
144
+
145
+ const traceDescription = webViewActionDescription.runScript(script);
146
+ const result = await this.withAction('runScript', traceDescription, script);
147
+ return this.extractResult(result, { allowUndefined: true });
148
+ }
149
+
150
+ async runScriptWithArgs(script, args) {
151
+ if (typeof script === 'function') {
152
+ script = script.toString();
153
+ }
154
+
155
+ const traceDescription = webViewActionDescription.runScriptWithArgs(script, args);
156
+ const result = await this.withAction('runScriptWithArgs', traceDescription, script, args);
157
+ return this.extractResult(result, { allowUndefined: true });
158
+ }
159
+
160
+ async getCurrentUrl() {
161
+ const traceDescription = webViewActionDescription.getCurrentUrl();
162
+ let result = await this.withAction('getCurrentUrl', traceDescription);
163
+ return this.extractResult(result, { type: 'url' });
164
+ }
165
+
166
+ async getTitle() {
167
+ const traceDescription = webViewActionDescription.getTitle();
168
+ let result = await this.withAction('getTitle', traceDescription);
169
+ return this.extractResult(result, { type: 'title' });
170
+ }
171
+
172
+ withAction(action, traceDescription, ...params) {
173
+ assert(traceDescription, `must provide trace description for action: \n ${JSON.stringify(action)}`);
174
+
175
+ const invocation = {
176
+ type: 'webAction',
177
+ ...(this.webViewElement !== undefined) && {
178
+ predicate: this.webViewElement.matcher.predicate,
179
+ ...(this.webViewElement.matcher.index !== undefined && { atIndex: this.webViewElement.matcher.index }),
180
+ },
181
+ webPredicate: this.matcher.predicate,
182
+ ...(this.index !== undefined && { webAtIndex: this.index }),
183
+ webAction: action,
184
+ ...(params.length !== 0 && { params }),
185
+ };
186
+ traceDescription = webViewActionDescription.full(traceDescription);
187
+ return _executeInvocation(this._invocationManager, invocation, traceDescription);
188
+ }
189
+ }
190
+
191
+ class WebElementMatcher {
192
+ id(id) {
193
+ if (typeof id !== 'string') throw new DetoxRuntimeError('id should be a string, but got ' + (id + (' (' + (typeof id + ')'))));
194
+ this.predicate = { type: 'id', value: id.toString() };
195
+ return this;
196
+ }
197
+
198
+ className(className) {
199
+ if (typeof className !== 'string') throw new DetoxRuntimeError('className should be a string, but got ' + (className + (' (' + (typeof className + ')'))));
200
+ this.predicate = { type: 'class', value: className.toString() };
201
+ return this;
202
+ }
203
+
204
+ cssSelector(cssSelector) {
205
+ if (typeof cssSelector !== 'string') throw new DetoxRuntimeError('cssSelector should be a string, but got ' + (cssSelector + (' (' + (typeof cssSelector + ')'))));
206
+ this.predicate = { type: 'css', value: cssSelector.toString() };
207
+ return this;
208
+ }
209
+
210
+ name(name) {
211
+ if (typeof name !== 'string') throw new DetoxRuntimeError('name should be a string, but got ' + (name + (' (' + (typeof name + ')'))));
212
+ this.predicate = { type: 'name', value: name.toString() };
213
+ return this;
214
+ }
215
+
216
+ xpath(xpath) {
217
+ if (typeof xpath !== 'string') throw new DetoxRuntimeError('xpath should be a string, but got ' + (xpath + (' (' + (typeof xpath + ')'))));
218
+ this.predicate = { type: 'xpath', value: xpath.toString() };
219
+ return this;
220
+ }
221
+
222
+ href(href) {
223
+ if (typeof href !== 'string') throw new DetoxRuntimeError('href should be a string, but got ' + (href + (' (' + (typeof href + ')'))));
224
+ this.predicate = { type: 'href', value: href.toString() };
225
+ return this;
226
+ }
227
+
228
+ hrefContains(href) {
229
+ if (typeof href !== 'string') throw new DetoxRuntimeError('href should be a string, but got ' + (href + (' (' + (typeof href + ')'))));
230
+ this.predicate = { type: 'hrefContains', value: href.toString() };
231
+ return this;
232
+ }
233
+
234
+ tag(tag) {
235
+ if (typeof tag !== 'string') throw new DetoxRuntimeError('tag should be a string, but got ' + (tag + (' (' + (typeof tag + ')'))));
236
+ this.predicate = { type: 'tag', value: tag.toString() };
237
+ return this;
238
+ }
239
+
240
+ label(label) {
241
+ if (typeof label !== 'string') throw new DetoxRuntimeError('label should be a string, but got ' + (label + (' (' + (typeof label + ')'))));
242
+ this.predicate = { type: 'label', value: label.toString() };
243
+ return this;
244
+ }
245
+
246
+ value(value) {
247
+ if (typeof value !== 'string') throw new DetoxRuntimeError('value should be a string, but got ' + (value + (' (' + (typeof value + ')'))));
248
+ this.predicate = { type: 'value', value: value.toString() };
249
+ return this;
250
+ }
251
+
252
+ accessibilityType(type) {
253
+ if (typeof type !== 'string') throw new DetoxRuntimeError('accessibilityType should be a string, but got ' + (type + (' (' + (typeof type + ')'))));
254
+ this.predicate = { type: 'accessibilityType', value: type.toString() };
255
+ return this;
256
+ }
257
+ }
258
+
259
+ function webMatcher() {
260
+ return new WebElementMatcher();
261
+ }
262
+
263
+ function webElement(invocationManager, emitter, webViewElement, matcher) {
264
+ if (!(matcher instanceof WebElementMatcher)) {
265
+ throwWebViewMatcherError(matcher);
266
+ }
267
+
268
+ return new WebElement(invocationManager, emitter, webViewElement, matcher);
269
+ }
270
+
271
+ function throwWebViewMatcherError(param) {
272
+ const paramDescription = JSON.stringify(param);
273
+ throw new DetoxRuntimeError(`${paramDescription} is not a Detox web-view matcher. More about web-view matchers here: https://wix.github.io/Detox/docs/api/webviews`);
274
+ }
275
+
276
+ function webExpect(invocationManager, element) {
277
+ return new WebExpect(invocationManager, element);
278
+ }
279
+
280
+ function _executeInvocation(invocationManager, invocation, traceDescription) {
281
+ return traceInvocationCall(traceDescription, invocation, invocationManager.execute(invocation));
282
+ }
283
+
284
+ function isWebElement(element) {
285
+ return element instanceof WebElement;
286
+ }
287
+
288
+ module.exports = {
289
+ webMatcher,
290
+ webElement,
291
+ webExpect,
292
+ isWebElement
293
+ };
@@ -27,6 +27,22 @@ module.exports = {
27
27
  tapReturnKey: () => 'tap on return key',
28
28
  typeText: (value) => `type input text: "${value}"`,
29
29
  },
30
+ webViewActionDescription: {
31
+ tap: () => `tap`,
32
+ typeText: (value, isContentEditable) => `type input text: "${value}"${isContentEditable ? ' in content editable' : ''}`,
33
+ replaceText: (value) => `replace input text: "${value}"`,
34
+ clearText: () => 'clear input text',
35
+ selectAllText: () => 'select all input text',
36
+ getText: () => 'get input text',
37
+ scrollToView: () => 'scroll to view',
38
+ focus: () => 'focus',
39
+ moveCursorToEnd: () => 'move cursor to end',
40
+ runScript: (script) => `run script: "${script}"`,
41
+ runScriptWithArgs: (script, ...args) => `run script: "${script}" with args: "${args}"`,
42
+ getCurrentUrl: () => 'get current url',
43
+ getTitle: () => 'get title',
44
+ full: (actionDescription) => `perform web view action: ${actionDescription}`
45
+ },
30
46
  expectDescription: {
31
47
  waitFor: (actionDescription) => `wait for expectation while ${actionDescription}`,
32
48
  waitForWithTimeout: (expectDescription, timeout) => `${expectDescription} with timeout (${timeout} ms)`,
@@ -1,12 +0,0 @@
1
- class GenyAuthService {
2
- constructor(genyCloudExec) {
3
- this.genyCloudExec = genyCloudExec;
4
- }
5
-
6
- async getLoginEmail() {
7
- const whoAmI = await this.genyCloudExec.whoAmI();
8
- return whoAmI.auth.email;
9
- }
10
- }
11
-
12
- module.exports = GenyAuthService;