detox 21.0.0-rc.6 → 21.0.0-rc.8

Sign up to get free protection for your applications and to get access to all the features.
Files changed (185) hide show
  1. package/.eslintignore +1 -0
  2. package/Detox-android/com/wix/detox/{21.0.0-rc.6/detox-21.0.0-rc.6-javadoc.jar → 21.0.0-rc.8/detox-21.0.0-rc.8-javadoc.jar} +0 -0
  3. package/Detox-android/com/wix/detox/21.0.0-rc.8/detox-21.0.0-rc.8-javadoc.jar.md5 +1 -0
  4. package/Detox-android/com/wix/detox/21.0.0-rc.8/detox-21.0.0-rc.8-javadoc.jar.sha1 +1 -0
  5. package/Detox-android/com/wix/detox/21.0.0-rc.8/detox-21.0.0-rc.8-javadoc.jar.sha256 +1 -0
  6. package/Detox-android/com/wix/detox/21.0.0-rc.8/detox-21.0.0-rc.8-javadoc.jar.sha512 +1 -0
  7. package/Detox-android/com/wix/detox/{21.0.0-rc.6/detox-21.0.0-rc.6-sources.jar → 21.0.0-rc.8/detox-21.0.0-rc.8-sources.jar} +0 -0
  8. package/Detox-android/com/wix/detox/21.0.0-rc.8/detox-21.0.0-rc.8-sources.jar.md5 +1 -0
  9. package/Detox-android/com/wix/detox/21.0.0-rc.8/detox-21.0.0-rc.8-sources.jar.sha1 +1 -0
  10. package/Detox-android/com/wix/detox/21.0.0-rc.8/detox-21.0.0-rc.8-sources.jar.sha256 +1 -0
  11. package/Detox-android/com/wix/detox/21.0.0-rc.8/detox-21.0.0-rc.8-sources.jar.sha512 +1 -0
  12. package/Detox-android/com/wix/detox/21.0.0-rc.8/detox-21.0.0-rc.8.aar +0 -0
  13. package/Detox-android/com/wix/detox/21.0.0-rc.8/detox-21.0.0-rc.8.aar.md5 +1 -0
  14. package/Detox-android/com/wix/detox/21.0.0-rc.8/detox-21.0.0-rc.8.aar.sha1 +1 -0
  15. package/Detox-android/com/wix/detox/21.0.0-rc.8/detox-21.0.0-rc.8.aar.sha256 +1 -0
  16. package/Detox-android/com/wix/detox/21.0.0-rc.8/detox-21.0.0-rc.8.aar.sha512 +1 -0
  17. package/Detox-android/com/wix/detox/{21.0.0-rc.6/detox-21.0.0-rc.6.pom → 21.0.0-rc.8/detox-21.0.0-rc.8.pom} +1 -7
  18. package/Detox-android/com/wix/detox/21.0.0-rc.8/detox-21.0.0-rc.8.pom.md5 +1 -0
  19. package/Detox-android/com/wix/detox/21.0.0-rc.8/detox-21.0.0-rc.8.pom.sha1 +1 -0
  20. package/Detox-android/com/wix/detox/21.0.0-rc.8/detox-21.0.0-rc.8.pom.sha256 +1 -0
  21. package/Detox-android/com/wix/detox/21.0.0-rc.8/detox-21.0.0-rc.8.pom.sha512 +1 -0
  22. package/Detox-android/com/wix/detox/maven-metadata.xml +4 -4
  23. package/Detox-android/com/wix/detox/maven-metadata.xml.md5 +1 -1
  24. package/Detox-android/com/wix/detox/maven-metadata.xml.sha1 +1 -1
  25. package/Detox-android/com/wix/detox/maven-metadata.xml.sha256 +1 -1
  26. package/Detox-android/com/wix/detox/maven-metadata.xml.sha512 +1 -1
  27. package/Detox-ios-framework.tbz +0 -0
  28. package/Detox-ios-src.tbz +0 -0
  29. package/Detox-ios-xcuitest.tbz +0 -0
  30. package/android/detox/build.gradle +13 -8
  31. package/android/detox/src/full/java/com/wix/detox/espresso/DetoxAssertion.java +44 -25
  32. package/android/detox/src/full/java/com/wix/detox/espresso/EspressoDetox.java +6 -7
  33. package/android/detox/src/full/java/com/wix/detox/espresso/action/AdjustSliderToPositionAction.kt +2 -2
  34. package/android/detox/src/full/java/com/wix/detox/espresso/action/GetAttributesAction.kt +34 -35
  35. package/android/detox/src/full/java/com/wix/detox/espresso/common/MaterialSliderHelper.kt +21 -0
  36. package/android/detox/src/full/java/com/wix/detox/espresso/common/{SliderHelper.kt → ReactSliderHelper.kt} +6 -5
  37. package/android/detox/src/full/java/com/wix/detox/espresso/matcher/ViewMatchers.kt +2 -2
  38. package/android/detox/src/full/java/com/wix/detox/espresso/performer/MultipleViewsActionPerformer.kt +43 -0
  39. package/android/detox/src/full/java/com/wix/detox/espresso/performer/SingleViewActionPerformer.kt +19 -0
  40. package/android/detox/src/full/java/com/wix/detox/espresso/performer/ViewActionPerformer.kt +24 -0
  41. package/android/detox/src/full/java/com/wix/detox/espresso/web/WebElement.java +4 -4
  42. package/android/detox/src/full/java/com/wix/invoke/types/Invocation.java +7 -6
  43. package/android/detox/src/main/java/com/wix/detox/espresso/MultipleViewsAction.kt +4 -0
  44. package/android/detox/src/main/java/com/wix/detox/espresso/UiControllerSpy.kt +0 -1
  45. package/android/detox/src/main/java/com/wix/detox/espresso/ViewActionWithResult.kt +2 -1
  46. package/android/detox/src/main/java/com/wix/detox/espresso/action/common/MotionEvents.kt +60 -4
  47. package/android/detox/src/testFull/java/com/wix/detox/espresso/action/GetAttributesActionTest.kt +6 -5
  48. package/android/detox/src/testFull/java/com/wix/detox/espresso/common/MaterialSliderHelperTest.kt +33 -0
  49. package/android/detox/src/testFull/java/com/wix/detox/espresso/common/{SliderHelperTest.kt → ReactSliderHelperTest.kt} +3 -3
  50. package/android/detox/src/testFull/java/com/wix/detox/espresso/performer/ViewActionPerformerSpec.kt +37 -0
  51. package/android/detox/src/testFull/java/com/wix/invoke/JsonParserTest.java +23 -7
  52. package/android/detox/src/testFull/resources/targetInvocationEspressoWebDetoxScript.json +47 -0
  53. package/detox.d.ts +1840 -0
  54. package/globals.d.ts +23 -0
  55. package/index.d.ts +2 -1823
  56. package/internals.d.ts +11 -1
  57. package/jest.config.js +108 -0
  58. package/local-cli/reset-lock-file.js +5 -9
  59. package/local-cli/testCommand/TestRunnerCommand.js +26 -3
  60. package/local-cli/utils/interruptListeners.js +15 -0
  61. package/package.json +2 -100
  62. package/runners/jest/reporter.js +21 -1
  63. package/runners/jest/reporters/DetoxIPCReporter.js +34 -0
  64. package/runners/jest/reporters/DetoxReporterDispatcher.js +144 -0
  65. package/runners/jest/reporters/DetoxSummaryReporter.js +16 -0
  66. package/runners/jest/reporters/DetoxVerboseReporter.js +16 -0
  67. package/runners/jest/reporters/index.js +6 -0
  68. package/runners/jest/testEnvironment/index.js +11 -0
  69. package/src/DetoxWorker.js +5 -11
  70. package/src/android/core/NativeElement.js +26 -29
  71. package/src/android/core/WebElement.js +24 -6
  72. package/src/android/espressoapi/DetoxAssertion.js +16 -14
  73. package/src/android/espressoapi/EspressoDetox.js +9 -2
  74. package/src/android/espressoapi/web/WebElement.js +1 -4
  75. package/src/android/interactions/native.js +2 -3
  76. package/src/android/matchers/index.js +2 -1
  77. package/src/android/matchers/web.js +9 -1
  78. package/src/artifacts/providers/index.js +3 -3
  79. package/src/artifacts/screenshot/SimulatorScreenshotPlugin.js +0 -17
  80. package/src/configuration/composeLoggerConfig.js +1 -0
  81. package/src/configuration/composeRunnerConfig.js +3 -1
  82. package/src/devices/allocation/DeviceAllocator.js +66 -20
  83. package/src/devices/allocation/DeviceList.js +44 -0
  84. package/src/devices/allocation/DeviceRegistry.js +189 -0
  85. package/src/devices/allocation/drivers/AllocationDriverBase.d.ts +15 -0
  86. package/src/devices/{common/drivers/android/tools → allocation/drivers/android}/FreeDeviceFinder.js +11 -10
  87. package/src/devices/allocation/drivers/android/attached/AttachedAndroidAllocDriver.js +22 -17
  88. package/src/devices/allocation/drivers/android/emulator/EmulatorAllocDriver.js +97 -38
  89. package/src/devices/allocation/drivers/android/emulator/EmulatorLauncher.js +32 -45
  90. package/src/devices/allocation/drivers/android/emulator/FreeEmulatorFinder.js +1 -1
  91. package/src/devices/allocation/drivers/android/emulator/FreePortFinder.js +37 -0
  92. package/src/devices/allocation/drivers/android/emulator/launchEmulatorProcess.js +3 -3
  93. package/src/devices/allocation/drivers/android/genycloud/GenyAllocDriver.js +104 -32
  94. package/src/devices/allocation/drivers/android/genycloud/GenyInstanceLauncher.js +40 -31
  95. package/src/devices/allocation/drivers/android/genycloud/GenyRegistry.js +121 -0
  96. package/src/devices/allocation/drivers/android/genycloud/services/GenyInstanceLifecycleService.js +24 -0
  97. package/src/devices/{common → allocation}/drivers/android/genycloud/services/GenyRecipesService.js +1 -1
  98. package/src/devices/allocation/drivers/android/genycloud/services/dto/GenyInstance.js +83 -0
  99. package/src/devices/allocation/drivers/android/genycloud/services/dto/GenyRecipe.js +25 -0
  100. package/src/devices/allocation/drivers/ios/SimulatorAllocDriver.js +95 -54
  101. package/src/devices/allocation/drivers/ios/SimulatorQuery.js +24 -0
  102. package/src/devices/allocation/factories/android.js +29 -35
  103. package/src/devices/allocation/factories/ios.js +6 -7
  104. package/src/devices/common/drivers/DeviceCookie.d.ts +12 -0
  105. package/src/devices/common/drivers/android/cookies.d.ts +11 -0
  106. package/src/devices/common/drivers/android/emulator/exec/EmulatorExec.js +17 -5
  107. package/src/devices/common/drivers/android/exec/ADB.js +1 -0
  108. package/src/devices/common/drivers/android/tools/instrumentationArgs.js +7 -1
  109. package/src/devices/common/drivers/ios/cookies.d.ts +9 -0
  110. package/src/devices/common/drivers/ios/tools/AppleSimUtils.js +3 -1
  111. package/src/devices/cookies/index.js +0 -6
  112. package/src/devices/runtime/drivers/android/genycloud/GenyCloudDriver.js +7 -6
  113. package/src/devices/runtime/drivers/ios/SimulatorDriver.js +5 -4
  114. package/src/devices/runtime/factories/android.js +3 -11
  115. package/src/devices/runtime/factories/ios.js +3 -4
  116. package/src/{servicelocator → devices/servicelocator}/android/emulatorServiceLocator.js +1 -1
  117. package/src/devices/servicelocator/android/genycloudServiceLocator.js +17 -0
  118. package/src/devices/servicelocator/android/index.js +23 -0
  119. package/src/{validation → devices/validation}/EnvironmentValidatorBase.js +1 -0
  120. package/src/{validation → devices/validation}/android/GenycloudEnvValidator.js +2 -2
  121. package/src/{validation → devices/validation}/factories/index.js +1 -1
  122. package/src/{validation → devices/validation}/ios/IosSimulatorEnvValidator.js +2 -2
  123. package/src/environmentFactory.js +1 -11
  124. package/src/ios/web.js +27 -5
  125. package/src/ipc/IPCClient.js +22 -1
  126. package/src/ipc/IPCServer.js +42 -1
  127. package/src/ipc/SessionState.js +1 -0
  128. package/src/logger/DetoxLogger.js +2 -2
  129. package/src/realms/DetoxContext.js +8 -0
  130. package/src/realms/DetoxInternalsFacade.js +1 -0
  131. package/src/realms/DetoxPrimaryContext.js +48 -42
  132. package/src/realms/DetoxSecondaryContext.js +27 -0
  133. package/src/realms/symbols.js +6 -0
  134. package/src/utils/PIDService.js +27 -0
  135. package/src/utils/assertIsFunction.js +35 -0
  136. package/src/utils/environment.js +8 -15
  137. package/src/utils/errorUtils.js +3 -3
  138. package/src/utils/isArrowFunction.js +24 -0
  139. package/tsconfig.json +8 -3
  140. package/Detox-android/com/wix/detox/21.0.0-rc.6/detox-21.0.0-rc.6-javadoc.jar.md5 +0 -1
  141. package/Detox-android/com/wix/detox/21.0.0-rc.6/detox-21.0.0-rc.6-javadoc.jar.sha1 +0 -1
  142. package/Detox-android/com/wix/detox/21.0.0-rc.6/detox-21.0.0-rc.6-javadoc.jar.sha256 +0 -1
  143. package/Detox-android/com/wix/detox/21.0.0-rc.6/detox-21.0.0-rc.6-javadoc.jar.sha512 +0 -1
  144. package/Detox-android/com/wix/detox/21.0.0-rc.6/detox-21.0.0-rc.6-sources.jar.md5 +0 -1
  145. package/Detox-android/com/wix/detox/21.0.0-rc.6/detox-21.0.0-rc.6-sources.jar.sha1 +0 -1
  146. package/Detox-android/com/wix/detox/21.0.0-rc.6/detox-21.0.0-rc.6-sources.jar.sha256 +0 -1
  147. package/Detox-android/com/wix/detox/21.0.0-rc.6/detox-21.0.0-rc.6-sources.jar.sha512 +0 -1
  148. package/Detox-android/com/wix/detox/21.0.0-rc.6/detox-21.0.0-rc.6.aar +0 -0
  149. package/Detox-android/com/wix/detox/21.0.0-rc.6/detox-21.0.0-rc.6.aar.md5 +0 -1
  150. package/Detox-android/com/wix/detox/21.0.0-rc.6/detox-21.0.0-rc.6.aar.sha1 +0 -1
  151. package/Detox-android/com/wix/detox/21.0.0-rc.6/detox-21.0.0-rc.6.aar.sha256 +0 -1
  152. package/Detox-android/com/wix/detox/21.0.0-rc.6/detox-21.0.0-rc.6.aar.sha512 +0 -1
  153. package/Detox-android/com/wix/detox/21.0.0-rc.6/detox-21.0.0-rc.6.pom.md5 +0 -1
  154. package/Detox-android/com/wix/detox/21.0.0-rc.6/detox-21.0.0-rc.6.pom.sha1 +0 -1
  155. package/Detox-android/com/wix/detox/21.0.0-rc.6/detox-21.0.0-rc.6.pom.sha256 +0 -1
  156. package/Detox-android/com/wix/detox/21.0.0-rc.6/detox-21.0.0-rc.6.pom.sha512 +0 -1
  157. package/runners/jest/reporters/DetoxReporter.js +0 -36
  158. package/src/devices/DeviceRegistry.js +0 -176
  159. package/src/devices/allocation/drivers/AllocationDriverBase.js +0 -30
  160. package/src/devices/allocation/drivers/android/attached/AttachedAndroidLauncher.js +0 -13
  161. package/src/devices/allocation/drivers/android/emulator/EmulatorAllocationHelper.js +0 -72
  162. package/src/devices/allocation/drivers/android/genycloud/GenyDeviceRegistryFactory.js +0 -16
  163. package/src/devices/allocation/drivers/android/genycloud/GenyInstanceAllocationHelper.js +0 -65
  164. package/src/devices/allocation/drivers/ios/SimulatorLauncher.js +0 -21
  165. package/src/devices/common/drivers/DeviceAllocationHelper.js +0 -20
  166. package/src/devices/common/drivers/DeviceLauncher.js +0 -19
  167. package/src/devices/common/drivers/android/genycloud/services/GenyInstanceLifecycleService.js +0 -25
  168. package/src/devices/common/drivers/android/genycloud/services/GenyInstanceLookupService.js +0 -38
  169. package/src/devices/common/drivers/android/genycloud/services/GenyInstanceNaming.js +0 -14
  170. package/src/devices/common/drivers/android/genycloud/services/dto/GenyInstance.js +0 -66
  171. package/src/devices/common/drivers/android/genycloud/services/dto/GenyRecipe.js +0 -13
  172. package/src/devices/cookies/AndroidDeviceCookie.js +0 -13
  173. package/src/devices/cookies/AndroidEmulatorCookie.js +0 -6
  174. package/src/devices/cookies/AttachedAndroidDeviceCookie.js +0 -12
  175. package/src/devices/cookies/DeviceCookie.js +0 -4
  176. package/src/devices/cookies/GenycloudEmulatorCookie.js +0 -20
  177. package/src/devices/cookies/IosCookie.js +0 -6
  178. package/src/devices/cookies/IosSimulatorCookie.js +0 -10
  179. package/src/devices/lifecycle/GenyGlobalLifecycleHandler.js +0 -71
  180. package/src/devices/lifecycle/factories/GenyGlobalLifecycleHandlerFactory.js +0 -18
  181. package/src/servicelocator/android/genycloudServiceLocator.js +0 -21
  182. package/src/servicelocator/android/index.js +0 -25
  183. package/src/servicelocator/ios.js +0 -7
  184. /package/src/devices/{common → allocation}/drivers/android/genycloud/exec/GenyCloudExec.js +0 -0
  185. /package/src/devices/{common → allocation}/drivers/android/genycloud/services/GenyAuthService.js +0 -0
package/detox.d.ts ADDED
@@ -0,0 +1,1840 @@
1
+ // TypeScript definitions for Detox
2
+ // Original authors (from DefinitelyTyped):
3
+ // * Jane Smith <jsmith@example.com>
4
+ // * Tareq El-Masri <https://github.com/TareqElMasri>
5
+ // * Steve Chun <https://github.com/stevechun>
6
+ // * Hammad Jutt <https://github.com/hammadj>
7
+ // * pera <https://github.com/santiagofm>
8
+ // * Max Komarychev <https://github.com/maxkomarychev>
9
+ // * Dor Ben Baruch <https://github.com/Dor256>
10
+
11
+ import { BunyanDebugStreamOptions } from 'bunyan-debug-stream';
12
+
13
+ declare global {
14
+ namespace Detox {
15
+ //#region DetoxConfig
16
+
17
+ interface DetoxConfig extends DetoxConfigurationCommon {
18
+ /**
19
+ * @example extends: './relative/detox.config'
20
+ * @example extends: '@my-org/detox-preset'
21
+ */
22
+ extends?: string;
23
+
24
+ apps?: Record<string, DetoxAppConfig>;
25
+ devices?: Record<string, DetoxDeviceConfig>;
26
+ selectedConfiguration?: string;
27
+ configurations: Record<string, DetoxConfiguration>;
28
+ }
29
+
30
+ type DetoxConfigurationCommon = {
31
+ artifacts?: false | DetoxArtifactsConfig;
32
+ behavior?: DetoxBehaviorConfig;
33
+ logger?: DetoxLoggerConfig;
34
+ session?: DetoxSessionConfig;
35
+ testRunner?: DetoxTestRunnerConfig;
36
+ };
37
+
38
+ interface DetoxArtifactsConfig {
39
+ rootDir?: string;
40
+ pathBuilder?: string;
41
+ plugins?: {
42
+ log?: 'none' | 'failing' | 'all' | DetoxLogArtifactsPluginConfig;
43
+ screenshot?: 'none' | 'manual' | 'failing' | 'all' | DetoxScreenshotArtifactsPluginConfig;
44
+ video?: 'none' | 'failing' | 'all' | DetoxVideoArtifactsPluginConfig;
45
+ instruments?: 'none' | 'all' | DetoxInstrumentsArtifactsPluginConfig;
46
+ uiHierarchy?: 'disabled' | 'enabled' | DetoxUIHierarchyArtifactsPluginConfig;
47
+
48
+ [pluginId: string]: unknown;
49
+ };
50
+ }
51
+
52
+ interface DetoxBehaviorConfig {
53
+ init?: {
54
+ /**
55
+ * By default, Detox exports `device`, `expect`, `element`, `by` and `waitFor`
56
+ * as global variables. If you want to control their initialization manually,
57
+ * set this property to `false`.
58
+ *
59
+ * This is useful when during E2E tests you also need to run regular expectations
60
+ * in Node.js. Jest's `expect` for instance, will not be overridden by Detox when
61
+ * this option is used.
62
+ */
63
+ exposeGlobals?: boolean;
64
+ /**
65
+ * By default, Detox will uninstall and install the app upon initialization.
66
+ * If you wish to reuse the existing app for a faster run, set the property to
67
+ * `false`.
68
+ */
69
+ reinstallApp?: boolean;
70
+ /**
71
+ * When false, `detox test` command always deletes the shared lock file on start,
72
+ * assuming it had been left from the previous, already finished test session.
73
+ * The lock file contains information about busy and free devices and ensures
74
+ * no device can be used simultaneously by multiple test workers.
75
+ *
76
+ * Setting it to **true** might be useful when if you need to run multiple
77
+ * `detox test` commands in parallel, e.g. test a few configurations at once.
78
+ *
79
+ * @default false
80
+ */
81
+ keepLockFile?: boolean;
82
+ };
83
+ launchApp?: 'auto' | 'manual';
84
+ cleanup?: {
85
+ shutdownDevice?: boolean;
86
+ };
87
+ }
88
+
89
+ type _DetoxLoggerOptions = Omit<BunyanDebugStreamOptions, 'out'>;
90
+
91
+ interface DetoxLoggerConfig {
92
+ /**
93
+ * Log level filters the messages printed to your terminal,
94
+ * and it does not affect the logs written to the artifacts.
95
+ *
96
+ * Use `info` by default.
97
+ * Use `error` or warn when you want to make the output as silent as possible.
98
+ * Use `debug` to control what generally is happening under the hood.
99
+ * Use `trace` when troubleshooting specific issues.
100
+ *
101
+ * @default 'info'
102
+ */
103
+ level?: DetoxLogLevel;
104
+ /**
105
+ * When enabled, hijacks all the console methods (console.log, console.warn, etc)
106
+ * so that the messages printed via them are formatted and saved as Detox logs.
107
+ *
108
+ * @default true
109
+ */
110
+ overrideConsole?: boolean;
111
+ /**
112
+ * Since Detox is using
113
+ * {@link https://www.npmjs.com/package/bunyan-debug-stream bunyan-debug-stream}
114
+ * for printing logs, all its options are exposed for sake of simplicity
115
+ * of customization.
116
+ *
117
+ * The only exception is {@link BunyanDebugStreamOptions#out} option,
118
+ * which is always set to `process.stdout`.
119
+ *
120
+ * You can also pass a callback function to override the logger config
121
+ * programmatically, e.g. depending on the selected log level.
122
+ *
123
+ * @see {@link BunyanDebugStreamOptions}
124
+ */
125
+ options?: _DetoxLoggerOptions | ((config: Partial<DetoxLoggerConfig>) => _DetoxLoggerOptions);
126
+ }
127
+
128
+ interface DetoxSessionConfig {
129
+ autoStart?: boolean;
130
+ debugSynchronization?: number;
131
+ server?: string;
132
+ sessionId?: string;
133
+ }
134
+
135
+ interface DetoxTestRunnerConfig {
136
+ args?: {
137
+ /**
138
+ * The command to use for runner: 'jest', 'nyc jest',
139
+ */
140
+ $0: string;
141
+ /**
142
+ * The positional arguments to pass to the runner.
143
+ */
144
+ _?: string[];
145
+ /**
146
+ * Any other properties recognized by test runner
147
+ */
148
+ [prop: string]: unknown;
149
+ };
150
+
151
+ /**
152
+ * This is an add-on section used by our Jest integration code (but not Detox core itself).
153
+ * In other words, if you’re implementing (or using) a custom integration with some other test runner, feel free to define a section for yourself (e.g. `testRunner.mocha`)
154
+ */
155
+ jest?: {
156
+ /**
157
+ * Environment setup timeout
158
+ *
159
+ * As a part of the environment setup, Detox boots the device and installs the apps.
160
+ * If that takes longer than the specified value, the entire test suite will be considered as failed, e.g.:
161
+ * ```plain text
162
+ * FAIL e2e/starter.test.js
163
+ * ● Test suite failed to run
164
+ *
165
+ * Exceeded timeout of 300000ms while setting up Detox environment
166
+ * ```
167
+ *
168
+ * The default value is 5 minutes.
169
+ *
170
+ * @default 300000
171
+ * @see {@link https://jestjs.io/docs/configuration/#testenvironment-string}
172
+ */
173
+ setupTimeout?: number | undefined;
174
+ /**
175
+ * Environemnt teardown timeout
176
+ *
177
+ * If the environment teardown takes longer than the specified value, Detox will throw a timeout error.
178
+ * The default value is half a minute.
179
+ *
180
+ * @default 30000 (30 seconds)
181
+ * @see {@link https://jestjs.io/docs/configuration/#testenvironment-string}
182
+ */
183
+ teardownTimeout?: number | undefined;
184
+ /**
185
+ * Jest provides an API to re-run individual failed tests: `jest.retryTimes(count)`.
186
+ * When Detox detects the use of this API, it suppresses its own CLI retry mechanism controlled via `detox test … --retries <N>` or {@link DetoxTestRunnerConfig#retries}.
187
+ * The motivation is simple – activating the both mechanisms is apt to increase your test duration dramatically, if your tests are flaky.
188
+ * If you wish nevertheless to use both the mechanisms simultaneously, set it to `true`.
189
+ *
190
+ * @default false
191
+ * @see {@link https://jestjs.io/docs/29.0/jest-object#jestretrytimesnumretries-options}
192
+ */
193
+ retryAfterCircusRetries?: boolean;
194
+ /**
195
+ * By default, Jest prints the test names and their status (_passed_ or _failed_) at the very end of the test session.
196
+ * When enabled, it makes Detox to print messages like these each time the new test starts and ends:
197
+ * ```plain text
198
+ * 18:03:36.258 detox[40125] i Sanity: should have welcome screen
199
+ * 18:03:37.495 detox[40125] i Sanity: should have welcome screen [OK]
200
+ * 18:03:37.496 detox[40125] i Sanity: should show hello screen after tap
201
+ * 18:03:38.928 detox[40125] i Sanity: should show hello screen after tap [OK]
202
+ * 18:03:38.929 detox[40125] i Sanity: should show world screen after tap
203
+ * 18:03:40.351 detox[40125] i Sanity: should show world screen after tap [OK]
204
+ * ```
205
+ * By default, it is enabled automatically in test sessions with a single worker.
206
+ * And vice versa, if multiple tests are executed concurrently, Detox turns it off to avoid confusion in the log.
207
+ * Use boolean values, `true` or `false`, to turn off the automatic choice.
208
+ *
209
+ * @default undefined
210
+ */
211
+ reportSpecs?: boolean | undefined;
212
+ /**
213
+ * In the environment setup phase, Detox boots the device and installs the apps.
214
+ * This flag tells Detox to print messages like these every time the device gets assigned to a specific suite:
215
+ *
216
+ * ```plain text
217
+ * 18:03:29.869 detox[40125] i starter.test.js is assigned to 4EC84833-C7EA-4CA3-A6E9-5C30A29EA596 (iPhone 12 Pro Max)
218
+ * ```
219
+ *
220
+ * @default true
221
+ */
222
+ reportWorkerAssign?: boolean | undefined;
223
+ };
224
+ /**
225
+ * Retries count. Zero means a single attempt to run tests.
226
+ */
227
+ retries?: number;
228
+ /**
229
+ * When true, tells Detox CLI to cancel next retrying if it gets
230
+ * at least one report about a permanent test suite failure.
231
+ * Has no effect, if {@link DetoxTestRunnerConfig#retries} is
232
+ * undefined or set to zero.
233
+ *
234
+ * @default false
235
+ * @see {DetoxInternals.DetoxTestFileReport#isPermanentFailure}
236
+ */
237
+ bail?: boolean;
238
+ /**
239
+ * When true, tells `detox test` to spawn the test runner in a detached mode.
240
+ * This is useful in CI environments, where you want to intercept SIGINT and SIGTERM signals to gracefully shut down the test runner and the device.
241
+ * Instead of passing the kill signal to the child process (the test runner), Detox will send an emergency shutdown request to all the workers, and then it will wait for them to finish.
242
+ * @default false
243
+ */
244
+ detached?: boolean;
245
+ /**
246
+ * Custom handler to process --inspect-brk CLI flag.
247
+ * Use it when you rely on another test runner than Jest to mutate the config.
248
+ */
249
+ inspectBrk?: (config: DetoxTestRunnerConfig) => void;
250
+ /**
251
+ * Forward environment variables to the spawned test runner
252
+ * accordingly to the given CLI argument overrides.
253
+ *
254
+ * If false, Detox CLI will be only printing a hint message on
255
+ * how to start the test runner using environment variables,
256
+ * in case when a user wants to avoid using Detox CLI.
257
+ *
258
+ * @default false
259
+ */
260
+ forwardEnv?: boolean;
261
+ }
262
+
263
+ type DetoxAppConfig = (DetoxBuiltInAppConfig | DetoxCustomAppConfig) & {
264
+ /**
265
+ * App name to use with device.selectApp(appName) calls.
266
+ * Can be omitted if you have a single app under the test.
267
+ *
268
+ * @see Device#selectApp
269
+ */
270
+ name?: string;
271
+ };
272
+
273
+ type DetoxDeviceConfig = DetoxBuiltInDeviceConfig | DetoxCustomDriverConfig;
274
+
275
+ interface DetoxLogArtifactsPluginConfig {
276
+ enabled?: boolean;
277
+ keepOnlyFailedTestsArtifacts?: boolean;
278
+ }
279
+
280
+ interface DetoxScreenshotArtifactsPluginConfig {
281
+ enabled?: boolean;
282
+ keepOnlyFailedTestsArtifacts?: boolean;
283
+ shouldTakeAutomaticSnapshots?: boolean;
284
+ takeWhen?: {
285
+ testStart?: boolean;
286
+ testFailure?: boolean;
287
+ testDone?: boolean;
288
+ appNotReady?: boolean;
289
+ };
290
+ }
291
+
292
+ interface DetoxVideoArtifactsPluginConfig {
293
+ enabled?: boolean;
294
+ keepOnlyFailedTestsArtifacts?: boolean;
295
+ android?: Partial<{
296
+ size: [number, number];
297
+ bitRate: number;
298
+ timeLimit: number;
299
+ verbose: boolean;
300
+ }>;
301
+ simulator?: Partial<{
302
+ codec: string;
303
+ }>;
304
+ }
305
+
306
+ interface DetoxInstrumentsArtifactsPluginConfig {
307
+ enabled?: boolean;
308
+ }
309
+
310
+ interface DetoxUIHierarchyArtifactsPluginConfig {
311
+ enabled?: boolean;
312
+ }
313
+
314
+ type DetoxBuiltInAppConfig = (DetoxIosAppConfig | DetoxAndroidAppConfig);
315
+
316
+ interface DetoxIosAppConfig {
317
+ type: 'ios.app';
318
+ binaryPath: string;
319
+ bundleId?: string;
320
+ build?: string;
321
+ start?: string;
322
+ launchArgs?: Record<string, any>;
323
+ }
324
+
325
+ interface DetoxAndroidAppConfig {
326
+ type: 'android.apk';
327
+ binaryPath: string;
328
+ bundleId?: string;
329
+ build?: string;
330
+ start?: string;
331
+ testBinaryPath?: string;
332
+ launchArgs?: Record<string, any>;
333
+ /**
334
+ * TCP ports to `adb reverse` upon the installation.
335
+ * E.g. 8081 - to be able to access React Native packager in Debug mode.
336
+ *
337
+ * @example [8081]
338
+ */
339
+ reversePorts?: number[];
340
+ }
341
+
342
+ interface DetoxCustomAppConfig {
343
+ type: string;
344
+
345
+ [prop: string]: unknown;
346
+ }
347
+
348
+ type DetoxBuiltInDeviceConfig =
349
+ | DetoxIosSimulatorDriverConfig
350
+ | DetoxAttachedAndroidDriverConfig
351
+ | DetoxAndroidEmulatorDriverConfig
352
+ | DetoxGenymotionCloudDriverConfig;
353
+
354
+ interface DetoxIosSimulatorDriverConfig {
355
+ type: 'ios.simulator';
356
+ device: string | Partial<IosSimulatorQuery>;
357
+ bootArgs?: string;
358
+ }
359
+
360
+ interface DetoxSharedAndroidDriverConfig {
361
+ forceAdbInstall?: boolean;
362
+ utilBinaryPaths?: string[];
363
+ }
364
+
365
+ interface DetoxAttachedAndroidDriverConfig extends DetoxSharedAndroidDriverConfig {
366
+ type: 'android.attached';
367
+ device: string | { adbName: string };
368
+ }
369
+
370
+ interface DetoxAndroidEmulatorDriverConfig extends DetoxSharedAndroidDriverConfig {
371
+ type: 'android.emulator';
372
+ device: string | { avdName: string };
373
+ bootArgs?: string;
374
+ gpuMode?: 'auto' | 'host' | 'swiftshader_indirect' | 'angle_indirect' | 'guest' | 'off';
375
+ headless?: boolean;
376
+ /**
377
+ * @default true
378
+ */
379
+ readonly?: boolean;
380
+ }
381
+
382
+ interface DetoxGenymotionCloudDriverConfig extends DetoxSharedAndroidDriverConfig {
383
+ type: 'android.genycloud';
384
+ device: string | { recipeUUID: string; } | { recipeName: string; };
385
+ }
386
+
387
+ interface DetoxCustomDriverConfig {
388
+ type: string;
389
+
390
+ [prop: string]: unknown;
391
+ }
392
+
393
+ interface IosSimulatorQuery {
394
+ id: string;
395
+ type: string;
396
+ name: string;
397
+ os: string;
398
+ }
399
+
400
+ type DetoxConfiguration = DetoxConfigurationCommon & (
401
+ | DetoxConfigurationSingleApp
402
+ | DetoxConfigurationMultiApps
403
+ );
404
+
405
+ interface DetoxConfigurationSingleApp {
406
+ device: DetoxAliasedDevice;
407
+ app: DetoxAliasedApp;
408
+ }
409
+
410
+ interface DetoxConfigurationMultiApps {
411
+ device: DetoxAliasedDevice;
412
+ apps: DetoxAliasedApp[];
413
+ }
414
+
415
+ type DetoxAliasedDevice = string | DetoxDeviceConfig;
416
+
417
+ type DetoxAliasedApp = string | DetoxAppConfig;
418
+
419
+ //#endregion
420
+
421
+ interface DetoxExportWrapper {
422
+ readonly device: Device;
423
+
424
+ readonly element: ElementFacade;
425
+
426
+ readonly waitFor: WaitForFacade;
427
+
428
+ readonly expect: ExpectFacade;
429
+
430
+ readonly by: ByFacade;
431
+
432
+ readonly web: WebFacade;
433
+
434
+ readonly DetoxConstants: {
435
+ userNotificationTriggers: {
436
+ push: 'push';
437
+ calendar: 'calendar';
438
+ timeInterval: 'timeInterval';
439
+ location: 'location';
440
+ };
441
+ userActivityTypes: {
442
+ searchableItem: string;
443
+ browsingWeb: string;
444
+ },
445
+ searchableItemActivityIdentifier: string;
446
+ };
447
+
448
+ /**
449
+ * Detox logger instance. Can be used for saving user logs to the general log file.
450
+ */
451
+ readonly log: Logger;
452
+
453
+ /**
454
+ * @deprecated
455
+ *
456
+ * Deprecated - use {@link Detox.Logger#trace}
457
+ * Detox tracer instance. Can be used for building timelines in Google Event Tracing format.
458
+ */
459
+ readonly trace: {
460
+ /** @deprecated */
461
+ readonly startSection: (name: string) => void;
462
+ /** @deprecated */
463
+ readonly endSection: (name: string) => void;
464
+ };
465
+
466
+ /**
467
+ * Trace a single call, with a given name and arguments.
468
+ *
469
+ * @deprecated
470
+ * @param sectionName The name of the section to trace.
471
+ * @param promiseOrFunction Promise or a function that provides a promise.
472
+ * @param args Optional arguments to pass to the trace.
473
+ * @returns The returned value of the traced call.
474
+ * @see https://wix.github.io/Detox/docs/19.x/api/detox-object-api/#detoxtracecall
475
+ */
476
+ readonly traceCall: <T>(event: string, action: () => Promise<T>, args?: Record<string, unknown>) => Promise<T>;
477
+ }
478
+
479
+ interface Logger {
480
+ readonly level: DetoxLogLevel;
481
+
482
+ readonly fatal: _LogMethod;
483
+ readonly error: _LogMethod;
484
+ readonly warn: _LogMethod;
485
+ readonly info: _LogMethod;
486
+ readonly debug: _LogMethod;
487
+ readonly trace: _LogMethod;
488
+
489
+ child(context?: Partial<LogEvent>): Logger;
490
+ }
491
+
492
+ /** @internal */
493
+ interface _LogMethod extends _LogMethodSignature {
494
+ readonly begin: _LogMethodSignature;
495
+ readonly complete: _CompleteMethodSignature;
496
+ readonly end: _LogMethodSignature;
497
+ }
498
+
499
+ /** @internal */
500
+ interface _LogMethodSignature {
501
+ (...args: unknown[]): void
502
+ (event: LogEvent, ...args: unknown[]): void;
503
+ }
504
+
505
+ /** @internal */
506
+ interface _CompleteMethodSignature {
507
+ <T>(message: string, action: T | (() => T)): T;
508
+ <T>(event: LogEvent, message: string, action: T | (() => T)): T;
509
+ }
510
+
511
+ type LogEvent = {
512
+ /** Use when there's a risk of logging several parallel duration events. */
513
+ id?: string | number;
514
+ /** Optional. Event categories (tags) to facilitate filtering. */
515
+ cat?: string | string[];
516
+ /** Optional. Color name (applicable in Google Chrome Trace Format) */
517
+ cname?: string;
518
+
519
+ /** Reserved property. Process ID. */
520
+ pid?: never;
521
+ /** Reserved property. Thread ID. */
522
+ tid?: never;
523
+ /** Reserved property. Timestamp. */
524
+ ts?: never;
525
+ /** Reserved property. Event phase. */
526
+ ph?: never;
527
+
528
+ [customProperty: string]: unknown;
529
+ };
530
+
531
+ type DetoxLogLevel = 'fatal' | 'error' | 'warn' | 'info' | 'debug' | 'trace';
532
+
533
+ type Point2D = {
534
+ x: number,
535
+ y: number,
536
+ }
537
+
538
+ /**
539
+ * A construct allowing for the querying and modification of user arguments passed to an app upon launch by Detox.
540
+ *
541
+ * @see AppLaunchArgs#modify
542
+ * @see AppLaunchArgs#reset
543
+ * @see AppLaunchArgs#get
544
+ */
545
+ interface AppLaunchArgs {
546
+ /**
547
+ * Shared (global) arguments that are not specific to a particular application.
548
+ * Selecting another app does not reset them, yet they still can be overridden
549
+ * by configuring app-specific launch args.
550
+ * @see Device#selectApp
551
+ * @see AppLaunchArgs
552
+ */
553
+ readonly shared: ScopedAppLaunchArgs;
554
+
555
+ /**
556
+ * Modify the launch-arguments via a modifier object, according to the following logic:
557
+ * - Non-nullish modifier properties would set a new value or override the previous value of
558
+ * existing properties with the same name.
559
+ * - Modifier properties set to either `undefined` or `null` would delete the corresponding property
560
+ * if it existed.
561
+ * These custom app launch arguments get erased whenever you select a different application.
562
+ * If you need to share them between all the applications, use {@link AppLaunchArgs#shared} property.
563
+ * Note: app-specific launch args have a priority over shared ones.
564
+ *
565
+ * @param modifier The modifier object.
566
+ * @example
567
+ * // With current launch arguments set to:
568
+ * // {
569
+ * // mockServerPort: 1234,
570
+ * // mockServerCredentials: 'user@test.com:12345678',
571
+ * // }
572
+ * device.appLaunchArgs.modify({
573
+ * mockServerPort: 4321,
574
+ * mockServerCredentials: null,
575
+ * mockServerToken: 'abcdef',
576
+ * });
577
+ * await device.launchApp();
578
+ * // ==> launch-arguments become:
579
+ * // {
580
+ * // mockServerPort: 4321,
581
+ * // mockServerToken: 'abcdef',
582
+ * // }
583
+ */
584
+ modify(modifier: object): this;
585
+
586
+ /**
587
+ * Reset all app-specific launch arguments (back to an empty object).
588
+ * If you need to reset the shared launch args, use {@link AppLaunchArgs#shared}.
589
+ */
590
+ reset(): this;
591
+
592
+ /**
593
+ * Get all currently set launch arguments (including shared ones).
594
+ * @returns An object containing all launch-arguments.
595
+ * Note: mutating the values inside the result object is pointless, as it is immutable.
596
+ */
597
+ get(): object;
598
+ }
599
+
600
+ /**
601
+ * Shared (global) arguments that are not specific to a particular application.
602
+ */
603
+ interface ScopedAppLaunchArgs {
604
+ /** @see AppLaunchArgs#modify */
605
+ modify(modifier: object): this;
606
+
607
+ /** @see AppLaunchArgs#reset */
608
+ reset(): this;
609
+
610
+ /** @see AppLaunchArgs#get */
611
+ get(): object;
612
+ }
613
+
614
+ type DigitWithoutZero = 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9;
615
+ type Digit = 0 | DigitWithoutZero;
616
+ type BatteryLevel = `${Digit}` | `${DigitWithoutZero}${Digit}` | "100";
617
+
618
+ interface Device {
619
+ /**
620
+ * Holds the environment-unique ID of the device, namely, the adb ID on Android (e.g. emulator-5554) and the Mac-global simulator UDID on iOS -
621
+ * as used by simctl (e.g. AAAAAAAA-BBBB-CCCC-DDDD-EEEEEEEEEEEE).
622
+ */
623
+ id: string;
624
+ /**
625
+ * Holds a descriptive name of the device. Example: emulator-5554 (Pixel_API_29)
626
+ */
627
+ name: string;
628
+
629
+ /**
630
+ * Select the current app (relevant only to multi-app configs) by its name.
631
+ * After execution, all app-specific device methods will target the selected app.
632
+ *
633
+ * @see DetoxAppConfig#name
634
+ * @example
635
+ * await device.selectApp('passenger');
636
+ * await device.launchApp(); // passenger
637
+ * // ... run tests for the passenger app
638
+ * await device.uninstallApp(); // passenger
639
+ * await device.selectApp('driver');
640
+ * await device.installApp(); // driver
641
+ * await device.launchApp(); // driver
642
+ * // ... run tests for the driver app
643
+ * await device.terminateApp(); // driver
644
+ */
645
+ selectApp(app: string): Promise<void>;
646
+
647
+ /**
648
+ * Launch the app.
649
+ *
650
+ * <p>For info regarding launch arguments, refer to the [dedicated guide](https://wix.github.io/Detox/docs/api/launch-args).
651
+ *
652
+ * @example
653
+ * // Terminate the app and launch it again. If set to false, the simulator will try to bring app from background,
654
+ * // if the app isn't running, it will launch a new instance. default is false
655
+ * await device.launchApp({newInstance: true});
656
+ * @example
657
+ * // Grant or deny runtime permissions for your application.
658
+ * await device.launchApp({permissions: {calendar: 'YES'}});
659
+ * @example
660
+ * // Mock opening the app from URL to test your app's deep link handling mechanism.
661
+ * await device.launchApp({url: url});
662
+ * @example
663
+ * // Start the app with some custom arguments.
664
+ * await device.launchApp({
665
+ * launchArgs: {arg1: 1, arg2: "2"},
666
+ * });
667
+ */
668
+ launchApp(config?: DeviceLaunchAppConfig): Promise<void>;
669
+
670
+ /**
671
+ * Relaunch the app. Convenience method that calls {@link Device#launchApp}
672
+ * with { newInstance: true } override.
673
+ *
674
+ * @deprecated
675
+ * @param config
676
+ * @see Device#launchApp
677
+ */
678
+ relaunchApp(config?: DeviceLaunchAppConfig): Promise<void>;
679
+
680
+ /**
681
+ * Access the user-defined launch-arguments predefined through static scopes such as the Detox configuration file and
682
+ * command-line arguments. This access allows - through dedicated methods, for both value-querying and
683
+ * modification (see {@link AppLaunchArgs}).
684
+ * Refer to the [dedicated guide](https://wix.github.io/Detox/docs/api/launch-args) for complete details.
685
+ *
686
+ * @example
687
+ * // With Detox being preconfigured statically to use these arguments in app launch:
688
+ * // {
689
+ * // mockServerPort: 1234,
690
+ * // }
691
+ * // The following code would result in these arguments eventually passed into the launched app:
692
+ * // {
693
+ * // mockServerPort: 4321,
694
+ * // mockServerToken: 'uvwxyz',
695
+ * // }
696
+ * device.appLaunchArgs.modify({
697
+ * mockServerPort: 4321,
698
+ * mockServerToken: 'abcdef',
699
+ * });
700
+ * await device.launchApp({ launchArgs: { mockServerToken: 'uvwxyz' } });
701
+ *
702
+ * @see AppLaunchArgs
703
+ */
704
+ appLaunchArgs: AppLaunchArgs;
705
+
706
+ /**
707
+ * Terminate the app.
708
+ *
709
+ * @example
710
+ * // By default, terminateApp() with no params will terminate the app
711
+ * await device.terminateApp();
712
+ * @example
713
+ * // To terminate another app, specify its bundle id
714
+ * await device.terminateApp('other.bundle.id');
715
+ */
716
+ terminateApp(bundle?: string): Promise<void>;
717
+
718
+ /**
719
+ * Send application to background by bringing com.apple.springboard to the foreground.
720
+ * Combining sendToHome() with launchApp({newInstance: false}) will simulate app coming back from background.
721
+ * @example
722
+ * await device.sendToHome();
723
+ * await device.launchApp({newInstance: false});
724
+ */
725
+ sendToHome(): Promise<void>;
726
+
727
+ /**
728
+ * If this is a React Native app, reload the React Native JS bundle. This action is much faster than device.launchApp(), and can be used if you just need to reset your React Native logic.
729
+ *
730
+ * @example await device.reloadReactNative()
731
+ */
732
+ reloadReactNative(): Promise<void>;
733
+
734
+ /**
735
+ * By default, installApp() with no params will install the app file defined in the current configuration.
736
+ * To install another app, specify its path
737
+ * @example await device.installApp();
738
+ * @example await device.installApp('path/to/other/app');
739
+ */
740
+ installApp(path?: any): Promise<void>;
741
+
742
+ /**
743
+ * By default, uninstallApp() with no params will uninstall the app defined in the current configuration.
744
+ * To uninstall another app, specify its bundle id
745
+ * @example await device.installApp('other.bundle.id');
746
+ */
747
+ uninstallApp(bundle?: string): Promise<void>;
748
+
749
+ /**
750
+ * Mock opening the app from URL. sourceApp is an optional parameter to specify source application bundle id.
751
+ */
752
+ openURL(url: { url: string; sourceApp?: string }): Promise<void>;
753
+
754
+ /**
755
+ * Mock handling of received user notification when app is in foreground.
756
+ */
757
+ sendUserNotification(...params: any[]): Promise<void>;
758
+
759
+ /**
760
+ * Mock handling of received user activity when app is in foreground.
761
+ */
762
+ sendUserActivity(...params: any[]): Promise<void>;
763
+
764
+ /**
765
+ * Takes "portrait" or "landscape" and rotates the device to the given orientation. Currently only available in the iOS Simulator.
766
+ */
767
+ setOrientation(orientation: Orientation): Promise<void>;
768
+
769
+ /**
770
+ * Sets the simulator/emulator location to the given latitude and longitude.
771
+ *
772
+ * <p/>On iOS `setLocation` is dependent on [fbsimctl](https://github.com/facebook/idb/tree/4b7929480c3c0f158f33f78a5b802c1d0e7030d2/fbsimctl)
773
+ * which [is now deprecated](https://github.com/wix/Detox/issues/1371).
774
+ * If `fbsimctl` is not installed, the command will fail, asking for it to be installed.
775
+ *
776
+ * <p/>On Android `setLocation` will work with both Android Emulator (bundled with Android development tools) and Genymotion.
777
+ * The correct permissions must be set in your app manifest.
778
+ *
779
+ * @example await device.setLocation(32.0853, 34.7818);
780
+ */
781
+ setLocation(lat: number, lon: number): Promise<void>;
782
+
783
+ /**
784
+ * (iOS only) Override simulator’s status bar.
785
+ * @platform iOS
786
+ * @param {config} config status bar configuration.
787
+ * @example
788
+ * await device.setStatusBar({
789
+ * time: "12:34",
790
+ * // Set the date or time to a fixed value.
791
+ * // If the string is a valid ISO date string it will also set the date on relevant devices.
792
+ * dataNetwork: "wifi",
793
+ * // If specified must be one of 'hide', 'wifi', '3g', '4g', 'lte', 'lte-a', 'lte+', '5g', '5g+', '5g-uwb', or '5g-uc'.
794
+ * wifiMode: "failed",
795
+ * // If specified must be one of 'searching', 'failed', or 'active'.
796
+ * wifiBars: "2",
797
+ * // If specified must be 0-3.
798
+ * cellularMode: "searching",
799
+ * // If specified must be one of 'notSupported', 'searching', 'failed', or 'active'.
800
+ * cellularBars: "3",
801
+ * // If specified must be 0-4.
802
+ * operatorName: "A1",
803
+ * // Set the cellular operator/carrier name. Use '' for the empty string.
804
+ * batteryState: "charging",
805
+ * // If specified must be one of 'charging', 'charged', or 'discharging'.
806
+ * batteryLevel: "50",
807
+ * // If specified must be 0-100.
808
+ * });
809
+ */
810
+ setStatusBar(config: {
811
+ time?: string,
812
+ dataNetwork?: "hide" | "wifi" | "3g" | "4g" | "lte" | "lte-a" | "lte+" | "5g" | "5g+" | "5g-uwb" | "5g-uc",
813
+ wifiMode?: "searching" |"failed" | "active",
814
+ wifiBars?: "0" | "1" | "2" | "3",
815
+ cellularMode?: "notSupported" | "searching" | "failed" | "active",
816
+ cellularBars?: "0" | "1" | "2" | "3" | "4",
817
+ operatorName?: string;
818
+ batteryState?: "charging" | "charged" | "discharging",
819
+ batteryLevel?: BatteryLevel,
820
+ }): Promise<void>;
821
+
822
+ /**
823
+ * Disable network synchronization mechanism on preferred endpoints. Useful if you want to on skip over synchronizing on certain URLs.
824
+ *
825
+ * @example await device.setURLBlacklist(['.*127.0.0.1.*']);
826
+ */
827
+ setURLBlacklist(urls: string[]): Promise<void>;
828
+
829
+ /**
830
+ * Temporarily disable synchronization (idle/busy monitoring) with the app - namely, stop waiting for the app to go idle before moving forward in the test execution.
831
+ *
832
+ * <p/>This API is useful for cases where test assertions must be made in an area of your application where it is okay for it to ever remain partly *busy* (e.g. due to an
833
+ * endlessly repeating on-screen animation). However, using it inherently suggests that you are likely to resort to applying `sleep()`'s in your test code - testing
834
+ * that area, **which is not recommended and can never be 100% stable.
835
+ * **Therefore, as a rule of thumb, test code running "inside" a sync-disabled mode must be reduced to the bare minimum.
836
+ *
837
+ * <p/>Note: Synchronization is enabled by default, and it gets **reenabled on every launch of a new instance of the app.**
838
+ *
839
+ * @example await device.disableSynchronization();
840
+ */
841
+ disableSynchronization(): Promise<void>;
842
+
843
+ /**
844
+ * Reenable synchronization (idle/busy monitoring) with the app - namely, resume waiting for the app to go idle before moving forward in the test execution, after a
845
+ * previous disabling of it through a call to `device.disableSynchronization()`.
846
+ *
847
+ * <p/>Warning: Making this call would resume synchronization **instantly**, having its returned promise only resolve when the app becomes idle again.
848
+ * In other words, this **must only be called after you navigate back to "the safe zone", where the app should be able to eventually become idle again**, or it would
849
+ * remain suspended "forever" (i.e. until a safeguard time-out expires).
850
+ *
851
+ * @example await device.enableSynchronization();
852
+ */
853
+ enableSynchronization(): Promise<void>;
854
+
855
+ /**
856
+ * Resets the Simulator to clean state (like the Simulator > Reset Content and Settings... menu item), especially removing previously set permissions.
857
+ *
858
+ * @example await device.resetContentAndSettings();
859
+ */
860
+ resetContentAndSettings(): Promise<void>;
861
+
862
+ /**
863
+ * Returns the current device, ios or android.
864
+ *
865
+ * @example
866
+ * if (device.getPlatform() === 'ios') {
867
+ * await expect(loopSwitch).toHaveValue('1');
868
+ * }
869
+ */
870
+ getPlatform(): 'ios' | 'android';
871
+
872
+ /**
873
+ * Takes a screenshot on the device and schedules putting it in the artifacts folder upon completion of the current test.
874
+ * @param name for the screenshot artifact
875
+ * @returns a temporary path to the screenshot.
876
+ * @example
877
+ * test('Menu items should have logout', async () => {
878
+ * const tempPath = await device.takeScreenshot('tap on menu');
879
+ * // The temporary path will remain valid until the test completion.
880
+ * // Afterwards, the screenshot will be moved, e.g.:
881
+ * // * on success, to: <artifacts-location>/✓ Menu items should have Logout/tap on menu.png
882
+ * // * on failure, to: <artifacts-location>/✗ Menu items should have Logout/tap on menu.png
883
+ * });
884
+ */
885
+ takeScreenshot(name: string): Promise<string>;
886
+
887
+ /**
888
+ * (iOS only) Saves a view hierarchy snapshot (*.viewhierarchy) of the currently opened application
889
+ * to a temporary folder and schedules putting it to the artifacts folder upon the completion of
890
+ * the current test. The file can be opened later in Xcode 12.0 and above.
891
+ * @see https://developer.apple.com/documentation/xcode-release-notes/xcode-12-release-notes#:~:text=57933113
892
+ * @param [name="capture"] optional name for the *.viewhierarchy artifact
893
+ * @returns a temporary path to the captured view hierarchy snapshot.
894
+ * @example
895
+ * test('Menu items should have logout', async () => {
896
+ * await device.captureViewHierarchy('myElements');
897
+ * // The temporary path will remain valid until the test completion.
898
+ * // Afterwards, the artifact will be moved, e.g.:
899
+ * // * on success, to: <artifacts-location>/✓ Menu items should have Logout/myElements.viewhierarchy
900
+ * // * on failure, to: <artifacts-location>/✗ Menu items should have Logout/myElements.viewhierarchy
901
+ * });
902
+ */
903
+ captureViewHierarchy(name?: string): Promise<string>;
904
+
905
+ /**
906
+ * Simulate shake (iOS Only)
907
+ */
908
+ shake(): Promise<void>;
909
+
910
+ /**
911
+ * Toggles device enrollment in biometric auth (TouchID or FaceID) (iOS Only)
912
+ * @example await device.setBiometricEnrollment(true);
913
+ * @example await device.setBiometricEnrollment(false);
914
+ */
915
+ setBiometricEnrollment(enabled: boolean): Promise<void>;
916
+
917
+ /**
918
+ * Simulates the success of a face match via FaceID (iOS Only)
919
+ */
920
+ matchFace(): Promise<void>;
921
+
922
+ /**
923
+ * Simulates the failure of a face match via FaceID (iOS Only)
924
+ */
925
+ unmatchFace(): Promise<void>;
926
+
927
+ /**
928
+ * Simulates the success of a finger match via TouchID (iOS Only)
929
+ */
930
+ matchFinger(): Promise<void>;
931
+
932
+ /**
933
+ * Simulates the failure of a finger match via TouchID (iOS Only)
934
+ */
935
+ unmatchFinger(): Promise<void>;
936
+
937
+ /**
938
+ * Clears the simulator keychain (iOS Only)
939
+ */
940
+ clearKeychain(): Promise<void>;
941
+
942
+ /**
943
+ * Simulate press back button (Android Only)
944
+ * @example await device.pressBack();
945
+ */
946
+ pressBack(): Promise<void>;
947
+
948
+ /**
949
+ * (Android Only)
950
+ * Exposes UiAutomator's UiDevice API (https://developer.android.com/reference/android/support/test/uiautomator/UiDevice).
951
+ * This is not a part of the official Detox API,
952
+ * it may break and change whenever an update to UiDevice or UiAutomator gradle dependencies ('androidx.test.uiautomator:uiautomator') is introduced.
953
+ * UIDevice's autogenerated code reference: https://github.com/wix/Detox/blob/master/detox/src/android/espressoapi/UIDevice.js
954
+ */
955
+ getUiDevice(): Promise<void>;
956
+
957
+ /**
958
+ * (Android Only)
959
+ * Runs `adb reverse tcp:PORT tcp:PORT` for the current device
960
+ * to enable network requests forwarding on localhost:PORT (computer<->device).
961
+ * For more information, see {@link https://www.reddit.com/r/reactnative/comments/5etpqw/what_do_you_call_what_adb_reverse_is_doing|here}.
962
+ * This is a no-op when running on iOS.
963
+ */
964
+ reverseTcpPort(port: number): Promise<void>;
965
+
966
+ /**
967
+ * (Android Only)
968
+ * Runs `adb reverse --remove tcp:PORT tcp:PORT` for the current device
969
+ * to disable network requests forwarding on localhost:PORT (computer<->device).
970
+ * For more information, see {@link https://www.reddit.com/r/reactnative/comments/5etpqw/what_do_you_call_what_adb_reverse_is_doing|here}.
971
+ * This is a no-op when running on iOS.
972
+ */
973
+ unreverseTcpPort(port: number): Promise<void>;
974
+ }
975
+
976
+ /**
977
+ * @deprecated
978
+ */
979
+ type DetoxAny = NativeElement & WaitFor;
980
+
981
+ interface ElementFacade {
982
+ (by: NativeMatcher): IndexableNativeElement;
983
+ }
984
+
985
+ interface IndexableNativeElement extends NativeElement {
986
+ /**
987
+ * Choose from multiple elements matching the same matcher using index
988
+ * @example await element(by.text('Product')).atIndex(2).tap();
989
+ */
990
+ atIndex(index: number): NativeElement;
991
+ }
992
+
993
+ interface NativeElement extends NativeElementActions {
994
+ }
995
+
996
+ interface ByFacade {
997
+ /**
998
+ * by.id will match an id that is given to the view via testID prop.
999
+ * @example
1000
+ * // In a React Native component add testID like so:
1001
+ * <TouchableOpacity testID={'tap_me'}>
1002
+ * // Then match with by.id:
1003
+ * await element(by.id('tap_me'));
1004
+ * await element(by.id(/^tap_[a-z]+$/));
1005
+ */
1006
+ id(id: string | RegExp): NativeMatcher;
1007
+
1008
+ /**
1009
+ * Find an element by text, useful for text fields, buttons.
1010
+ * @example
1011
+ * await element(by.text('Tap Me'));
1012
+ * await element(by.text(/^Tap .*$/));
1013
+ */
1014
+ text(text: string | RegExp): NativeMatcher;
1015
+
1016
+ /**
1017
+ * Find an element by accessibilityLabel on iOS, or by contentDescription on Android.
1018
+ * @example
1019
+ * await element(by.label('Welcome'));
1020
+ * await element(by.label(/[a-z]+/i));
1021
+ */
1022
+ label(label: string | RegExp): NativeMatcher;
1023
+
1024
+ /**
1025
+ * Find an element by native view type.
1026
+ * @example await element(by.type('RCTImageView'));
1027
+ */
1028
+ type(nativeViewType: string): NativeMatcher;
1029
+
1030
+ /**
1031
+ * Find an element with an accessibility trait. (iOS only)
1032
+ * @example await element(by.traits(['button']));
1033
+ */
1034
+ traits(traits: string[]): NativeMatcher;
1035
+
1036
+ /**
1037
+ * Collection of web matchers
1038
+ */
1039
+ readonly web: ByWebFacade;
1040
+ }
1041
+
1042
+ interface ByWebFacade {
1043
+ /**
1044
+ * Find an element on the DOM tree by its id
1045
+ * @param id
1046
+ * @example
1047
+ * web.element(by.web.id('testingh1'))
1048
+ */
1049
+ id(id: string): WebMatcher;
1050
+
1051
+ /**
1052
+ * Find an element on the DOM tree by its CSS class
1053
+ * @param className
1054
+ * @example
1055
+ * web.element(by.web.className('a'))
1056
+ */
1057
+ className(className: string): WebMatcher;
1058
+
1059
+ /**
1060
+ * Find an element on the DOM tree matching the given CSS selector
1061
+ * @param cssSelector
1062
+ * @example
1063
+ * web.element(by.web.cssSelector('#cssSelector'))
1064
+ */
1065
+ cssSelector(cssSelector: string): WebMatcher;
1066
+
1067
+ /**
1068
+ * Find an element on the DOM tree by its "name" attribute
1069
+ * @param name
1070
+ * @example
1071
+ * web.element(by.web.name('sec_input'))
1072
+ */
1073
+ name(name: string): WebMatcher;
1074
+
1075
+ /**
1076
+ * Find an element on the DOM tree by its XPath
1077
+ * @param xpath
1078
+ * @example
1079
+ * web.element(by.web.xpath('//*[@id="testingh1-1"]'))
1080
+ */
1081
+ xpath(xpath: string): WebMatcher;
1082
+
1083
+ /**
1084
+ * Find an <a> element on the DOM tree by its link text (href content)
1085
+ * @param linkText
1086
+ * @example
1087
+ * web.element(by.web.href('disney.com'))
1088
+ */
1089
+ href(linkText: string): WebMatcher;
1090
+
1091
+ /**
1092
+ * Find an <a> element on the DOM tree by its partial link text (href content)
1093
+ * @param linkTextFragment
1094
+ * @example
1095
+ * web.element(by.web.hrefContains('disney'))
1096
+ */
1097
+ hrefContains(linkTextFragment: string): WebMatcher;
1098
+
1099
+ /**
1100
+ * Find an element on the DOM tree by its tag name
1101
+ * @param tag
1102
+ * @example
1103
+ * web.element(by.web.tag('mark'))
1104
+ */
1105
+ tag(tagName: string): WebMatcher;
1106
+
1107
+ /**
1108
+ * Find an element on the DOM tree by its accessibility type
1109
+ * For iOS, uses XCUITest element type: https://developer.apple.com/documentation/xctest/xcuielement/elementtype
1110
+ * @note This API is only available on iOS
1111
+ * @param viewType
1112
+ * @example
1113
+ * web.element(by.web.accessibilityType('TextField'))
1114
+ */
1115
+ accessibilityType(viewType: string): WebMatcher;
1116
+ }
1117
+
1118
+ interface NativeMatcher {
1119
+ /**
1120
+ * Find an element satisfying all the matchers
1121
+ * @example await element(by.text('Product').and(by.id('product_name'));
1122
+ */
1123
+ and(by: NativeMatcher): NativeMatcher;
1124
+
1125
+ /**
1126
+ * Find an element by a matcher with a parent matcher
1127
+ * @example await element(by.id('Grandson883').withAncestor(by.id('Son883')));
1128
+ */
1129
+ withAncestor(parentBy: NativeMatcher): NativeMatcher;
1130
+
1131
+ /**
1132
+ * Find an element by a matcher with a child matcher
1133
+ * @example await element(by.id('Son883').withDescendant(by.id('Grandson883')));
1134
+ */
1135
+ withDescendant(childBy: NativeMatcher): NativeMatcher;
1136
+ }
1137
+
1138
+ interface WebMatcher {
1139
+ __web__: any; // prevent type coersion
1140
+ }
1141
+
1142
+ interface ExpectFacade {
1143
+ (element: NativeElement): Expect;
1144
+
1145
+ (webElement: WebElement): WebExpect;
1146
+ }
1147
+
1148
+ interface WebViewElement {
1149
+ element(webMatcher: WebMatcher): IndexableWebElement;
1150
+ }
1151
+
1152
+ interface WebFacade extends WebViewElement {
1153
+ /**
1154
+ * Gets the webview element as a testing element.
1155
+ * @param matcher a simple view matcher for the webview element in th UI hierarchy.
1156
+ * If there is only ONE webview element in the UI hierarchy, its NOT a must to supply it.
1157
+ * If there are MORE then one webview element in the UI hierarchy you MUST supply are view matcher.
1158
+ */
1159
+ (matcher?: NativeMatcher): WebViewElement;
1160
+ }
1161
+
1162
+ interface Expect<R = Promise<void>> {
1163
+
1164
+ /**
1165
+ * Expect the view to be at least N% visible. If no number is provided then defaults to 75%. Negating this
1166
+ * expectation with a `not` expects the view's visible area to be smaller than N%.
1167
+ * @param pct optional integer ranging from 1 to 100, indicating how much percent of the view should be
1168
+ * visible to the user to be accepted.
1169
+ * @example await expect(element(by.id('mainTitle'))).toBeVisible(35);
1170
+ */
1171
+ toBeVisible(pct?: number): R;
1172
+
1173
+ /**
1174
+ * Negate the expectation.
1175
+ * @example await expect(element(by.id('cancelButton'))).not.toBeVisible();
1176
+ */
1177
+ not: this;
1178
+
1179
+ /**
1180
+ * Expect the view to not be visible.
1181
+ * @example await expect(element(by.id('cancelButton'))).toBeNotVisible();
1182
+ * @deprecated Use `.not.toBeVisible()` instead.
1183
+ */
1184
+ toBeNotVisible(): R;
1185
+
1186
+ /**
1187
+ * Expect the view to exist in the UI hierarchy.
1188
+ * @example await expect(element(by.id('okButton'))).toExist();
1189
+ */
1190
+ toExist(): R;
1191
+
1192
+ /**
1193
+ * Expect the view to not exist in the UI hierarchy.
1194
+ * @example await expect(element(by.id('cancelButton'))).toNotExist();
1195
+ * @deprecated Use `.not.toExist()` instead.
1196
+ */
1197
+ toNotExist(): R;
1198
+
1199
+ /**
1200
+ * Expect the view to be focused.
1201
+ * @example await expect(element(by.id('emailInput'))).toBeFocused();
1202
+ */
1203
+ toBeFocused(): R;
1204
+
1205
+ /**
1206
+ * Expect the view not to be focused.
1207
+ * @example await expect(element(by.id('passwordInput'))).toBeNotFocused();
1208
+ * @deprecated Use `.not.toBeFocused()` instead.
1209
+ */
1210
+ toBeNotFocused(): R;
1211
+
1212
+ /**
1213
+ * In React Native apps, expect UI component of type <Text> to have text.
1214
+ * In native iOS apps, expect UI elements of type UIButton, UILabel, UITextField or UITextViewIn to have inputText with text.
1215
+ * @example await expect(element(by.id('mainTitle'))).toHaveText('Welcome back!);
1216
+ */
1217
+ toHaveText(text: string): R;
1218
+
1219
+ /**
1220
+ * Expects a specific accessibilityLabel, as specified via the `accessibilityLabel` prop in React Native.
1221
+ * On the native side (in both React Native and pure-native apps), that is equivalent to `accessibilityLabel`
1222
+ * on iOS and contentDescription on Android. Refer to Detox's documentation in order to learn about caveats
1223
+ * with accessibility-labels in React Native apps.
1224
+ * @example await expect(element(by.id('submitButton'))).toHaveLabel('Submit');
1225
+ */
1226
+ toHaveLabel(label: string): R;
1227
+
1228
+ /**
1229
+ * In React Native apps, expect UI component to have testID with that id.
1230
+ * In native iOS apps, expect UI element to have accessibilityIdentifier with that id.
1231
+ * @example await expect(element(by.text('Submit'))).toHaveId('submitButton');
1232
+ */
1233
+ toHaveId(id: string): R;
1234
+
1235
+ /**
1236
+ * Expects a toggle-able element (e.g. a Switch or a Check-Box) to be on/checked or off/unchecked.
1237
+ * As a reference, in react-native, this is the equivalent switch component.
1238
+ * @example await expect(element(by.id('switch'))).toHaveToggleValue(true);
1239
+ */
1240
+ toHaveToggleValue(value: boolean): R;
1241
+
1242
+ /**
1243
+ * Expect components like a Switch to have a value ('0' for off, '1' for on).
1244
+ * @example await expect(element(by.id('temperatureDial'))).toHaveValue('25');
1245
+ */
1246
+ toHaveValue(value: any): R;
1247
+
1248
+ /**
1249
+ * Expect Slider to have a position (0 - 1).
1250
+ * Can have an optional tolerance to take into account rounding issues on ios
1251
+ * @example await expect(element(by.id('SliderId'))).toHavePosition(0.75);
1252
+ * @example await expect(element(by.id('SliderId'))).toHavePosition(0.74, 0.1);
1253
+ */
1254
+ toHaveSliderPosition(position: number, tolerance?: number): Promise<void>;
1255
+ }
1256
+
1257
+ interface WaitForFacade {
1258
+ /**
1259
+ * This API polls using the given expectation continuously until the expectation is met. Use manual synchronization with waitFor only as a last resort.
1260
+ * NOTE: Every waitFor call must set a timeout using withTimeout(). Calling waitFor without setting a timeout will do nothing.
1261
+ * @example await waitFor(element(by.id('bigButton'))).toExist().withTimeout(2000);
1262
+ */
1263
+ (element: NativeElement): Expect<WaitFor>;
1264
+ }
1265
+
1266
+ interface WaitFor {
1267
+ /**
1268
+ * Waits for the condition to be met until the specified time (millis) have elapsed.
1269
+ * @example await waitFor(element(by.id('bigButton'))).toExist().withTimeout(2000);
1270
+ */
1271
+ withTimeout(millis: number): Promise<void>;
1272
+
1273
+ /**
1274
+ * Performs the action repeatedly on the element until an expectation is met
1275
+ * @example await waitFor(element(by.text('Item #5'))).toBeVisible().whileElement(by.id('itemsList')).scroll(50, 'down');
1276
+ */
1277
+ whileElement(by: NativeMatcher): NativeElement & WaitFor;
1278
+
1279
+ // TODO: not sure about & WaitFor - check if we can chain whileElement multiple times
1280
+ }
1281
+
1282
+ interface NativeElementActions {
1283
+ /**
1284
+ * Simulate tap on an element
1285
+ * @param point relative coordinates to the matched element (the element size could changes on different devices or even when changing the device font size)
1286
+ * @example await element(by.id('tappable')).tap();
1287
+ * @example await element(by.id('tappable')).tap({ x:5, y:10 });
1288
+ */
1289
+ tap(point?: Point2D): Promise<void>;
1290
+
1291
+ /**
1292
+ * Simulate long press on an element
1293
+ * @param duration (iOS only) custom press duration time, in milliseconds. Optional (default is 1000ms).
1294
+ * @example await element(by.id('tappable')).longPress();
1295
+ */
1296
+ longPress(duration?: number): Promise<void>;
1297
+
1298
+ /**
1299
+ * Simulate long press on an element and then drag it to the position of the target element. (iOS Only)
1300
+ * @example await element(by.id('draggable')).longPressAndDrag(2000, NaN, NaN, element(by.id('target')), NaN, NaN, 'fast', 0);
1301
+ */
1302
+ longPressAndDrag(duration: number, normalizedPositionX: number, normalizedPositionY: number, targetElement: NativeElement,
1303
+ normalizedTargetPositionX: number, normalizedTargetPositionY: number, speed: Speed, holdDuration: number): Promise<void>;
1304
+
1305
+ /**
1306
+ * Simulate multiple taps on an element.
1307
+ * @param times number of times to tap
1308
+ * @example await element(by.id('tappable')).multiTap(3);
1309
+ */
1310
+ multiTap(times: number): Promise<void>;
1311
+
1312
+ /**
1313
+ * Simulate tap at a specific point on an element.
1314
+ * Note: The point coordinates are relative to the matched element and the element size could changes on different devices or even when changing the device font size.
1315
+ * @example await element(by.id('tappable')).tapAtPoint({ x:5, y:10 });
1316
+ * @deprecated Use `.tap()` instead.
1317
+ */
1318
+ tapAtPoint(point: Point2D): Promise<void>;
1319
+
1320
+ /**
1321
+ * Use the builtin keyboard to type text into a text field.
1322
+ * @example await element(by.id('textField')).typeText('passcode');
1323
+ */
1324
+ typeText(text: string): Promise<void>;
1325
+
1326
+ /**
1327
+ * Paste text into a text field.
1328
+ * @example await element(by.id('textField')).replaceText('passcode again');
1329
+ */
1330
+ replaceText(text: string): Promise<void>;
1331
+
1332
+ /**
1333
+ * Clear text from a text field.
1334
+ * @example await element(by.id('textField')).clearText();
1335
+ */
1336
+ clearText(): Promise<void>;
1337
+
1338
+ /**
1339
+ * Taps the backspace key on the built-in keyboard.
1340
+ * @example await element(by.id('textField')).tapBackspaceKey();
1341
+ */
1342
+ tapBackspaceKey(): Promise<void>;
1343
+
1344
+ /**
1345
+ * Taps the return key on the built-in keyboard.
1346
+ * @example await element(by.id('textField')).tapReturnKey();
1347
+ */
1348
+ tapReturnKey(): Promise<void>;
1349
+
1350
+ /**
1351
+ * Scrolls a given amount of pixels in the provided direction, starting from the provided start positions.
1352
+ * @param pixels - independent device pixels
1353
+ * @param direction - left/right/up/down
1354
+ * @param startPositionX - the X starting scroll position, in percentage; valid input: `[0.0, 1.0]`, `NaN`; default: `NaN`—choose the best value automatically
1355
+ * @param startPositionY - the Y starting scroll position, in percentage; valid input: `[0.0, 1.0]`, `NaN`; default: `NaN`—choose the best value automatically
1356
+ * @example await element(by.id('scrollView')).scroll(100, 'down', NaN, 0.85);
1357
+ * @example await element(by.id('scrollView')).scroll(100, 'up');
1358
+ */
1359
+ scroll(
1360
+ pixels: number,
1361
+ direction: Direction,
1362
+ startPositionX?: number,
1363
+ startPositionY?: number
1364
+ ): Promise<void>;
1365
+
1366
+ /**
1367
+ * Scroll to index.
1368
+ * @example await element(by.id('scrollView')).scrollToIndex(10);
1369
+ */
1370
+ scrollToIndex(
1371
+ index: Number
1372
+ ): Promise<void>;
1373
+
1374
+ /**
1375
+ * Scroll to edge.
1376
+ * @example await element(by.id('scrollView')).scrollTo('bottom');
1377
+ * @example await element(by.id('scrollView')).scrollTo('top');
1378
+ */
1379
+ scrollTo(edge: Direction): Promise<void>;
1380
+
1381
+ /**
1382
+ * Adjust slider to position.
1383
+ * @example await element(by.id('slider')).adjustSliderToPosition(0.75);
1384
+ */
1385
+ adjustSliderToPosition(newPosition: number): Promise<void>;
1386
+
1387
+ /**
1388
+ * Swipes in the provided direction at the provided speed, started from percentage.
1389
+ * @param speed default: `fast`
1390
+ * @param percentage screen percentage to swipe; valid input: `[0.0, 1.0]`
1391
+ * @param optional normalizedStartingPointX X coordinate of swipe starting point, relative to the view width; valid input: `[0.0, 1.0]`
1392
+ * @param normalizedStartingPointY Y coordinate of swipe starting point, relative to the view height; valid input: `[0.0, 1.0]`
1393
+ * @example await element(by.id('scrollView')).swipe('down');
1394
+ * @example await element(by.id('scrollView')).swipe('down', 'fast');
1395
+ * @example await element(by.id('scrollView')).swipe('down', 'fast', 0.5);
1396
+ * @example await element(by.id('scrollView')).swipe('down', 'fast', 0.5, 0.2);
1397
+ * @example await element(by.id('scrollView')).swipe('down', 'fast', 0.5, 0.2, 0.5);
1398
+ */
1399
+ swipe(direction: Direction, speed?: Speed, percentage?: number, normalizedStartingPointX?: number, normalizedStartingPointY?: number): Promise<void>;
1400
+
1401
+ /**
1402
+ * Sets a picker view’s column to the given value. This function supports both date pickers and general picker views. (iOS Only)
1403
+ * Note: When working with date pickers, you should always set an explicit locale when launching your app in order to prevent flakiness from different date and time styles.
1404
+ * See [here](https://wix.github.io/Detox/docs/api/device-object-api#9-launch-with-a-specific-language-ios-only) for more information.
1405
+ *
1406
+ * @param column number of datepicker column (starts from 0)
1407
+ * @param value string value in set column (must be correct)
1408
+ * @example
1409
+ * await expect(element(by.type('UIPickerView'))).toBeVisible();
1410
+ * await element(by.type('UIPickerView')).setColumnToValue(1,"6");
1411
+ * await element(by.type('UIPickerView')).setColumnToValue(2,"34");
1412
+ */
1413
+ setColumnToValue(column: number, value: string): Promise<void>;
1414
+
1415
+ /**
1416
+ * Sets the date of a date-picker according to the specified date-string and format.
1417
+ * @param dateString Textual representation of a date (e.g. '2023/01/01'). Should be in coherence with the format specified by `dateFormat`.
1418
+ * @param dateFormat Format of `dateString`: Generally either 'ISO8601' or an explicitly specified format (e.g. 'yyyy/MM/dd'); It should
1419
+ * follow the rules of NSDateFormatter for iOS and DateTimeFormatter for Android.
1420
+ * @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/toISOString
1421
+ * @example
1422
+ * await element(by.id('datePicker')).setDatePickerDate('2023-01-01T00:00:00Z', 'ISO8601');
1423
+ * await element(by.id('datePicker')).setDatePickerDate(new Date().toISOString(), 'ISO8601');
1424
+ * await element(by.id('datePicker')).setDatePickerDate('2023/01/01', 'yyyy/MM/dd');
1425
+ */
1426
+ setDatePickerDate(dateString: string, dateFormat: string): Promise<void>;
1427
+
1428
+ /**
1429
+ * Triggers a given [accessibility action]{@link https://reactnative.dev/docs/accessibility#accessibility-actions}.
1430
+ * @param actionName - name of the accessibility action
1431
+ * @example await element(by.id('view')).performAccessibilityAction('activate');
1432
+ */
1433
+ performAccessibilityAction(actionName: string): Promise<void>
1434
+
1435
+ /**
1436
+ * Pinches in the given direction with speed and angle. (iOS only)
1437
+ * @param angle value in radiant, default is `0`
1438
+ * @example
1439
+ * await expect(element(by.id('PinchableScrollView'))).toBeVisible();
1440
+ * await element(by.id('PinchableScrollView')).pinchWithAngle('outward', 'slow', 0);
1441
+ * @deprecated Use `.pinch()` instead.
1442
+ */
1443
+ pinchWithAngle(direction: PinchDirection, speed: Speed, angle: number): Promise<void>;
1444
+
1445
+ /**
1446
+ * Pinches with the given scale, speed, and angle. (iOS only)
1447
+ * @param speed default is `fast`
1448
+ * @param angle value in radiant, default is `0`
1449
+ * @example
1450
+ * await element(by.id('PinchableScrollView')).pinch(1.1);
1451
+ * await element(by.id('PinchableScrollView')).pinch(2.0);
1452
+ * await element(by.id('PinchableScrollView')).pinch(0.001);
1453
+ */
1454
+ pinch(scale: number, speed?: Speed, angle?: number): Promise<void>;
1455
+
1456
+ /**
1457
+ * Takes a screenshot of the element and schedules putting it in the artifacts folder upon completion of the current test.
1458
+ * For more information, see {@link https://wix.github.io/Detox/docs/api/screenshots#element-level-screenshots}
1459
+ * @param {string} name for the screenshot artifact
1460
+ * @returns {Promise<string>} a temporary path to the screenshot.
1461
+ * @example
1462
+ * test('Menu items should have logout', async () => {
1463
+ * const imagePath = await element(by.id('menuRoot')).takeScreenshot('tap on menu');
1464
+ * // The temporary path will remain valid until the test completion.
1465
+ * // Afterwards, the screenshot will be moved, e.g.:
1466
+ * // * on success, to: <artifacts-location>/✓ Menu items should have Logout/tap on menu.png
1467
+ * // * on failure, to: <artifacts-location>/✗ Menu items should have Logout/tap on menu.png
1468
+ * });
1469
+ */
1470
+ takeScreenshot(name: string): Promise<string>;
1471
+
1472
+ /**
1473
+ * Retrieves the OS-dependent attributes of an element.
1474
+ * If there are multiple matches, it returns an array of attributes for all matched elements.
1475
+ * For detailed information, refer to {@link https://wix.github.io/Detox/docs/api/actions-on-element/#getattributes}
1476
+ *
1477
+ * @example
1478
+ * test('Get the attributes for my text element', async () => {
1479
+ * const attributes = await element(by.id('myText')).getAttributes()
1480
+ * const jestExpect = require('expect');
1481
+ * // 'visible' attribute available on both iOS and Android
1482
+ * jestExpect(attributes.visible).toBe(true);
1483
+ * // 'activationPoint' attribute available on iOS only
1484
+ * jestExpect(attributes.activationPoint.x).toHaveValue(50);
1485
+ * // 'width' attribute available on Android only
1486
+ * jestExpect(attributes.width).toHaveValue(100);
1487
+ * })
1488
+ */
1489
+ getAttributes(): Promise<IosElementAttributes | AndroidElementAttributes | { elements: IosElementAttributes[] } | { elements: AndroidElementAttributes[] } >;
1490
+ }
1491
+
1492
+ interface WebExpect<R = Promise<void>> {
1493
+ /**
1494
+ * Negate the expectation.
1495
+ * @example await expect(web.element(by.web.id('sessionTimeout'))).not.toExist();
1496
+ */
1497
+ not: this;
1498
+
1499
+ /**
1500
+ * Expect the element content to have the `text` supplied
1501
+ * @param text expected to be on the element content
1502
+ * @example
1503
+ * await expect(web.element(by.web.id('checkoutButton'))).toHaveText('Proceed to check out');
1504
+ */
1505
+ toHaveText(text: string): R;
1506
+
1507
+ /**
1508
+ * Expect the view to exist in the webview DOM tree.
1509
+ * @example await expect(web.element(by.web.id('submitButton'))).toExist();
1510
+ */
1511
+ toExist(): R;
1512
+ }
1513
+
1514
+ interface IndexableWebElement extends WebElement {
1515
+ /**
1516
+ * Choose from multiple elements matching the same matcher using index
1517
+ * @example await web.element(by.web.hrefContains('Details')).atIndex(2).tap();
1518
+ */
1519
+ atIndex(index: number): WebElement;
1520
+ }
1521
+
1522
+ interface WebElement extends WebElementActions {
1523
+ }
1524
+
1525
+ interface WebElementActions {
1526
+ tap(): Promise<void>;
1527
+
1528
+ /**
1529
+ * @param text to type
1530
+ * @param isContentEditable whether its a ContentEditable element, default is false.
1531
+ */
1532
+ typeText(text: string, isContentEditable: boolean): Promise<void>;
1533
+
1534
+ /**
1535
+ * At the moment not working on content-editable
1536
+ * @param text to replace with the old content.
1537
+ */
1538
+ replaceText(text: string): Promise<void>;
1539
+
1540
+ /**
1541
+ * At the moment not working on content-editable
1542
+ */
1543
+ clearText(): Promise<void>;
1544
+
1545
+ /**
1546
+ * scrolling to the view, the element top position will be at the top of the screen.
1547
+ */
1548
+ scrollToView(): Promise<void>;
1549
+
1550
+ /**
1551
+ * Gets the input content
1552
+ */
1553
+ getText(): Promise<string>;
1554
+
1555
+ /**
1556
+ * Calls the focus function on the element
1557
+ */
1558
+ focus(): Promise<void>;
1559
+
1560
+ /**
1561
+ * Selects all the input content, works on ContentEditable at the moment.
1562
+ */
1563
+ selectAllText(): Promise<void>;
1564
+
1565
+ /**
1566
+ * Moves the input cursor / caret to the end of the content, works on ContentEditable at the moment.
1567
+ */
1568
+ moveCursorToEnd(): Promise<void>;
1569
+
1570
+ /**
1571
+ * Running a JavaScript function on the element.
1572
+ * The first argument to the function will be the element itself.
1573
+ * The rest of the arguments will be forwarded to the JavaScript function as is.
1574
+ *
1575
+ * @param script a callback function in stringified form, or a plain function reference
1576
+ * without closures, bindings etc. that will be converted to a string.
1577
+ * @param args optional args to pass to the script
1578
+ *
1579
+ * @example
1580
+ * await webElement.runScript('(el) => el.click()');
1581
+ * await webElement.runScript(function setText(element, text) {
1582
+ * element.textContent = text;
1583
+ * }, ['Custom Title']);
1584
+ */
1585
+ runScript(script: string, args?: unknown[]): Promise<any>;
1586
+ runScript<F>(script: (...args: any[]) => F, args?: unknown[]): Promise<F>;
1587
+
1588
+ /**
1589
+ * Gets the current page url
1590
+ */
1591
+ getCurrentUrl(): Promise<string>;
1592
+
1593
+ /**
1594
+ * Gets the current page title
1595
+ */
1596
+ getTitle(): Promise<string>;
1597
+ }
1598
+
1599
+ type Direction = 'left' | 'right' | 'top' | 'bottom' | 'up' | 'down';
1600
+
1601
+ type PinchDirection = 'outward' | 'inward'
1602
+
1603
+ type Orientation = 'portrait' | 'landscape';
1604
+
1605
+ type Speed = 'fast' | 'slow';
1606
+
1607
+ interface LanguageAndLocale {
1608
+ language?: string;
1609
+ locale?: string;
1610
+ }
1611
+
1612
+ /**
1613
+ * Source for string definitions is https://github.com/wix/AppleSimulatorUtils
1614
+ */
1615
+ interface DevicePermissions {
1616
+ location?: LocationPermission;
1617
+ notifications?: NotificationsPermission;
1618
+ calendar?: CalendarPermission;
1619
+ camera?: CameraPermission;
1620
+ contacts?: ContactsPermission;
1621
+ health?: HealthPermission;
1622
+ homekit?: HomekitPermission;
1623
+ medialibrary?: MediaLibraryPermission;
1624
+ microphone?: MicrophonePermission;
1625
+ motion?: MotionPermission;
1626
+ photos?: PhotosPermission;
1627
+ reminders?: RemindersPermission;
1628
+ siri?: SiriPermission;
1629
+ speech?: SpeechPermission;
1630
+ faceid?: FaceIDPermission;
1631
+ userTracking?: UserTrackingPermission;
1632
+ }
1633
+
1634
+ type LocationPermission = 'always' | 'inuse' | 'never' | 'unset';
1635
+ type PermissionState = 'YES' | 'NO' | 'unset';
1636
+ type CameraPermission = PermissionState;
1637
+ type ContactsPermission = PermissionState;
1638
+ type CalendarPermission = PermissionState;
1639
+ type HealthPermission = PermissionState;
1640
+ type HomekitPermission = PermissionState;
1641
+ type MediaLibraryPermission = PermissionState;
1642
+ type MicrophonePermission = PermissionState;
1643
+ type MotionPermission = PermissionState;
1644
+ type PhotosPermission = PermissionState;
1645
+ type RemindersPermission = PermissionState;
1646
+ type SiriPermission = PermissionState;
1647
+ type SpeechPermission = PermissionState;
1648
+ type NotificationsPermission = PermissionState;
1649
+ type FaceIDPermission = PermissionState;
1650
+ type UserTrackingPermission = PermissionState;
1651
+
1652
+ interface DeviceLaunchAppConfig {
1653
+ /**
1654
+ * Restart the app
1655
+ * Terminate the app and launch it again. If set to false, the simulator will try to bring app from background, if the app isn't running, it will launch a new instance. default is false
1656
+ */
1657
+ newInstance?: boolean;
1658
+ /**
1659
+ * Set runtime permissions
1660
+ * Grant or deny runtime permissions for your application.
1661
+ */
1662
+ permissions?: DevicePermissions;
1663
+ /**
1664
+ * Launch from URL
1665
+ * Mock opening the app from URL to test your app's deep link handling mechanism.
1666
+ */
1667
+ url?: any;
1668
+ /**
1669
+ * Launch with user notifications
1670
+ */
1671
+ userNotification?: any;
1672
+ /**
1673
+ * Launch with user activity
1674
+ */
1675
+ userActivity?: any;
1676
+ /**
1677
+ * Launch into a fresh installation
1678
+ * A flag that enables relaunching into a fresh installation of the app (it will uninstall and install the binary again), default is false.
1679
+ */
1680
+ delete?: boolean;
1681
+ /**
1682
+ * Arguments to pass-through into the app.
1683
+ * Refer to the [dedicated guide](https://wix.github.io/Detox/docs/api/launch-args) for complete details.
1684
+ */
1685
+ launchArgs?: Record<string, any>;
1686
+ /**
1687
+ * Launch config for specifying the native language and locale
1688
+ */
1689
+ languageAndLocale?: LanguageAndLocale;
1690
+ }
1691
+
1692
+ // Element Attributes Shared Among iOS and Android
1693
+ interface ElementAttributes {
1694
+ /**
1695
+ * Whether or not the element is enabled for user interaction.
1696
+ */
1697
+ enabled: boolean;
1698
+ /**
1699
+ * The identifier of the element. Matches accessibilityIdentifier on iOS, and the main view tag, on Android - both commonly holding the component's test ID in React Native apps.
1700
+ */
1701
+ identifier: string;
1702
+ /**
1703
+ * Whether the element is visible. On iOS, visibility is calculated for the activation point. On Android, the attribute directly holds the value returned by View.getLocalVisibleRect()).
1704
+ */
1705
+ visible: boolean;
1706
+ /**
1707
+ * The text value of any textual element.
1708
+ */
1709
+ text?: string;
1710
+ /**
1711
+ * The label of the element. Largely matches accessibilityLabel for ios, and contentDescription for android.
1712
+ * Refer to Detox's documentation (`toHaveLabel()` subsection) in order to learn about caveats associated with
1713
+ * this property in React Native apps.
1714
+ */
1715
+ label?: string;
1716
+ /**
1717
+ * The placeholder text value of the element. Matches hint on android.
1718
+ */
1719
+ placeholder?: string;
1720
+ /**
1721
+ * The value of the element, where applicable.
1722
+ * Matches accessibilityValue, on iOS.
1723
+ * For example: the position of a slider, or whether a checkbox has been marked (Android).
1724
+ */
1725
+ value?: unknown;
1726
+ }
1727
+
1728
+ interface IosElementAttributeFrame {
1729
+ y: number;
1730
+ x: number;
1731
+ width: number;
1732
+ height: number;
1733
+ }
1734
+
1735
+ interface IosElementAttributeInsets {
1736
+ right: number;
1737
+ top: number;
1738
+ left: number;
1739
+ bottom: number;
1740
+ }
1741
+
1742
+ // iOS Specific Attributes
1743
+ interface IosElementAttributes extends ElementAttributes {
1744
+ /**
1745
+ * The [activation point]{@link https://developer.apple.com/documentation/objectivec/nsobject/1615179-accessibilityactivationpoint} of the element, in element coordinate space.
1746
+ */
1747
+ activationPoint: Point2D;
1748
+ /**
1749
+ * The activation point of the element, in normalized percentage ([0.0, 1.0]).
1750
+ */
1751
+ normalizedActivationPoint: Point2D;
1752
+ /**
1753
+ * Whether the element is hittable at the activation point.
1754
+ */
1755
+ hittable: boolean;
1756
+ /**
1757
+ * The frame of the element, in screen coordinate space.
1758
+ */
1759
+ frame: IosElementAttributeFrame;
1760
+ /**
1761
+ * The frame of the element, in container coordinate space.
1762
+ */
1763
+ elementFrame: IosElementAttributeFrame;
1764
+ /**
1765
+ * The bounds of the element, in element coordinate space.
1766
+ */
1767
+ elementBounds: IosElementAttributeFrame;
1768
+ /**
1769
+ * The safe area insets of the element, in element coordinate space.
1770
+ */
1771
+ safeAreaInsets: IosElementAttributeInsets;
1772
+ /**
1773
+ * The safe area bounds of the element, in element coordinate space.
1774
+ */
1775
+ elementSafeBounds: IosElementAttributeFrame;
1776
+ /**
1777
+ * The date of the element (if it is a date picker).
1778
+ */
1779
+ date?: string;
1780
+ /**
1781
+ * The normalized slider position (if it is a slider).
1782
+ */
1783
+ normalizedSliderPosition?: number;
1784
+ /**
1785
+ * The content offset (if it is a scroll view).
1786
+ */
1787
+ contentOffset?: Point2D;
1788
+ /**
1789
+ * The content inset (if it is a scroll view).
1790
+ */
1791
+ contentInset?: IosElementAttributeInsets;
1792
+ /**
1793
+ * The adjusted content inset (if it is a scroll view).
1794
+ */
1795
+ adjustedContentInset?: IosElementAttributeInsets;
1796
+ /**
1797
+ * @example "<CALayer: 0x600003f759e0>"
1798
+ */
1799
+ layer: string;
1800
+ }
1801
+
1802
+ // Android Specific Attributes
1803
+ interface AndroidElementAttributes extends ElementAttributes {
1804
+ /**
1805
+ * The OS visibility type associated with the element: visible, invisible or gone.
1806
+ */
1807
+ visibility: 'visible' | 'invisible' | 'gone';
1808
+ /**
1809
+ * Width of the element, in pixels.
1810
+ */
1811
+ width: number;
1812
+ /**
1813
+ * Height of the element, in pixels.
1814
+ */
1815
+ height: number;
1816
+ /**
1817
+ * Elevation of the element.
1818
+ */
1819
+ elevation: number;
1820
+ /**
1821
+ * Alpha value for the element.
1822
+ */
1823
+ alpha: number;
1824
+ /**
1825
+ * Whether the element is the one currently in focus.
1826
+ */
1827
+ focused: boolean;
1828
+ /**
1829
+ * The text size for the text element.
1830
+ */
1831
+ textSize?: number;
1832
+ /**
1833
+ * The length of the text element (character count).
1834
+ */
1835
+ length?: number;
1836
+ }
1837
+ }
1838
+ }
1839
+
1840
+ export = Detox;