-
Notifications
You must be signed in to change notification settings - Fork 1.9k
/
Copy pathindex.d.ts
1628 lines (1449 loc) · 66.7 KB
/
index.d.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
// TypeScript definitions for Detox
// Original authors (from DefinitelyTyped):
// * Jane Smith <[email protected]>
// * Tareq El-Masri <https://github.com/TareqElMasri>
// * Steve Chun <https://github.com/stevechun>
// * Hammad Jutt <https://github.com/hammadj>
// * pera <https://github.com/santiagofm>
// * Max Komarychev <https://github.com/maxkomarychev>
// * Dor Ben Baruch <https://github.com/Dor256>
declare global {
const device: Detox.DetoxExportWrapper['device'];
const element: Detox.DetoxExportWrapper['element'];
const waitFor: Detox.DetoxExportWrapper['waitFor'];
const expect: Detox.DetoxExportWrapper['expect'];
const by: Detox.DetoxExportWrapper['by'];
const web: Detox.DetoxExportWrapper['web'];
const detoxCircus: Detox.DetoxCircus;
namespace NodeJS {
interface Global {
device: Detox.DetoxExportWrapper['device'];
element: Detox.DetoxExportWrapper['element'];
waitFor: Detox.DetoxExportWrapper['waitFor'];
expect: Detox.DetoxExportWrapper['expect'];
by: Detox.DetoxExportWrapper['by'];
web: Detox.DetoxExportWrapper['web'];
detoxCircus: Detox.DetoxCircus;
}
}
namespace Detox {
// region DetoxConfig
interface DetoxConfig {
/**
* @example extends: './relative/detox.config'
* @example extends: '@my-org/detox-preset'
*/
extends?: string;
/**
* @example testRunner: 'jest'
* @example testRunner: 'mocha'
*/
testRunner?: string;
/**
* Stops passing default `--maxWorkers 1` to the test runner,
* presuming that from now on you have that already configured
* in your test runner config as a default.
*/
skipLegacyWorkersInjection?: boolean;
/**
* @example runnerConfig: 'e2e/config.js'
*/
runnerConfig?: string;
/**
* Optional. A default glob pattern for a test runner to use when no test files are specified.
*
* @example specs: 'detoxE2E'
*/
specs?: string;
artifacts?: DetoxArtifactsConfig;
behavior?: DetoxBehaviorConfig;
session?: DetoxSessionConfig;
apps?: Record<string, DetoxAppConfig>;
devices?: Record<string, DetoxDeviceConfig>;
selectedConfiguration?: string;
configurations: Record<string, DetoxConfiguration>;
}
interface DetoxArtifactsConfig {
rootDir?: string;
pathBuilder?: string;
plugins?: {
log?: 'none' | 'failing' | 'all' | DetoxLogArtifactsPluginConfig;
screenshot?: 'none' | 'manual' | 'failing' | 'all' | DetoxScreenshotArtifactsPluginConfig;
video?: 'none' | 'failing' | 'all' | DetoxVideoArtifactsPluginConfig;
instruments?: 'none' | 'all' | DetoxInstrumentsArtifactsPluginConfig;
timeline?: 'none' | 'all' | DetoxTimelineArtifactsPluginConfig;
uiHierarchy?: 'disabled' | 'enabled' | DetoxUIHierarchyArtifactsPluginConfig;
[pluginId: string]: unknown;
};
}
interface DetoxBehaviorConfig {
init?: {
/**
* By default, Detox exports `device`, `expect`, `element`, `by` and `waitFor`
* as global variables. If you want to control their initialization manually,
* set this property to `false`.
*
* This is useful when during E2E tests you also need to run regular expectations
* in Node.js. Jest's `expect` for instance, will not be overridden by Detox when
* this option is used.
*/
exposeGlobals?: boolean;
/**
* By default, `await detox.init()` will uninstall and install the app.
* If you wish to reuse the existing app for a faster run, set the property to
* `false`.
*/
reinstallApp?: boolean;
};
/**
* Avoid installing the app on the device if it has been already installed there.
* Instead of reinstalling, it calls Device#resetAppState().
* By default, Detox will perform app reinstallation.
*
* Experimental and available for Android only.
*/
optimizeAppInstall?: boolean;
launchApp?: 'auto' | 'manual';
cleanup?: { shutdownDevice?: boolean; };
}
interface DetoxSessionConfig {
autoStart?: boolean;
debugSynchronization?: number;
server?: string;
sessionId?: string;
}
type DetoxAppConfig = (DetoxIosAppConfig | DetoxAndroidAppConfig) & {
/**
* App name to use with device.selectApp(appName) calls.
* Can be omitted if you have a single app under the test.
*
* @see Device#selectApp
*/
name?: string;
};
type DetoxDeviceConfig = DetoxBuiltInDeviceConfig | DetoxCustomDriverConfig;
type DetoxConfiguration = DetoxPlainConfiguration | DetoxAliasedConfiguration;
interface DetoxLogArtifactsPluginConfig {
enabled?: boolean;
keepOnlyFailedTestsArtifacts?: boolean;
}
interface DetoxScreenshotArtifactsPluginConfig {
enabled?: boolean;
keepOnlyFailedTestsArtifacts?: boolean;
shouldTakeAutomaticSnapshots?: boolean;
takeWhen?: {
testStart?: boolean;
testFailure?: boolean;
testDone?: boolean;
appNotReady?: boolean;
};
}
interface DetoxVideoArtifactsPluginConfig {
enabled?: boolean;
keepOnlyFailedTestsArtifacts?: boolean;
android?: Partial<{
size: [number, number];
bitRate: number;
timeLimit: number;
verbose: boolean;
}>;
simulator?: Partial<{
codec: string;
}>;
}
interface DetoxInstrumentsArtifactsPluginConfig {
enabled?: boolean;
}
interface DetoxUIHierarchyArtifactsPluginConfig {
enabled?: boolean;
}
interface DetoxTimelineArtifactsPluginConfig {
enabled?: boolean;
}
interface DetoxIosAppConfig {
type: 'ios.app';
binaryPath: string;
bundleId?: string;
build?: string;
launchArgs?: Record<string, any>;
permissions?: DevicePermissions;
}
interface DetoxAndroidAppConfig {
type: 'android.apk';
binaryPath: string;
bundleId?: string;
build?: string;
testBinaryPath?: string;
launchArgs?: Record<string, any>;
}
interface _DetoxAppConfigFragment {
binaryPath: string;
bundleId?: string;
build?: string;
testBinaryPath?: string;
launchArgs?: Record<string, any>;
permissions?: DevicePermissions;
}
type DetoxBuiltInDeviceConfig =
| DetoxIosSimulatorDriverConfig
| DetoxIosNoneDriverConfig
| DetoxAttachedAndroidDriverConfig
| DetoxAndroidEmulatorDriverConfig
| DetoxGenymotionCloudDriverConfig;
type DetoxPlainConfiguration = DetoxConfigurationOverrides & (
| (DetoxIosSimulatorDriverConfig & _DetoxAppConfigFragment)
| (DetoxIosNoneDriverConfig & _DetoxAppConfigFragment)
| (DetoxAttachedAndroidDriverConfig & _DetoxAppConfigFragment)
| (DetoxAndroidEmulatorDriverConfig & _DetoxAppConfigFragment)
| (DetoxGenymotionCloudDriverConfig & _DetoxAppConfigFragment)
| (DetoxCustomDriverConfig)
);
interface DetoxIosSimulatorDriverConfig {
type: 'ios.simulator';
device: string | Partial<IosSimulatorQuery>;
bootArgs?: string;
}
interface DetoxIosNoneDriverConfig {
type: 'ios.none';
// TODO: check if we need it at all?
device?: string | Partial<IosSimulatorQuery>;
}
interface DetoxSharedAndroidDriverConfig {
forceAdbInstall?: boolean;
utilBinaryPaths?: string[];
}
interface DetoxAttachedAndroidDriverConfig extends DetoxSharedAndroidDriverConfig {
type: 'android.attached';
device: string | { adbName: string };
}
interface DetoxAndroidEmulatorDriverConfig extends DetoxSharedAndroidDriverConfig {
type: 'android.emulator';
device: string | { avdName: string };
bootArgs?: string;
gpuMode?: 'auto' | 'host' | 'swiftshader_indirect' | 'angle_indirect' | 'guest';
headless?: boolean;
readonly?: boolean;
}
interface DetoxGenymotionCloudDriverConfig extends DetoxSharedAndroidDriverConfig {
type: 'android.genycloud';
device: string | { recipeUUID: string; } | { recipeName: string; };
}
interface DetoxCustomDriverConfig {
type: string;
[prop: string]: unknown;
}
interface IosSimulatorQuery {
id: string;
type: string;
name: string;
os: string;
}
type DetoxKnownDeviceType = DetoxBuiltInDeviceConfig['type'];
type DetoxConfigurationOverrides = {
artifacts?: false | DetoxArtifactsConfig;
behavior?: DetoxBehaviorConfig;
session?: DetoxSessionConfig;
};
type DetoxAliasedConfiguration =
| DetoxAliasedConfigurationSingleApp
| DetoxAliasedConfigurationMultiApps;
interface DetoxAliasedConfigurationSingleApp {
type?: never;
device: DetoxAliasedDevice;
app: string | DetoxAppConfig;
}
interface DetoxAliasedConfigurationMultiApps {
type?: never;
device: DetoxAliasedDevice;
apps: string[];
}
type DetoxAliasedDevice = string | DetoxDeviceConfig;
// endregion DetoxConfig
// Detox exports all methods from detox global and all of the global constants.
interface DetoxInstance {
device: Device;
element: ElementFacade;
waitFor: WaitForFacade;
expect: ExpectFacade;
by: ByFacade;
web: WebFacade;
}
interface DetoxExportWrapper extends DetoxInstance {
/**
* The setup phase happens inside detox.init(). This is the phase where detox reads its configuration, starts a server, loads its expection library and starts a simulator
*
* @param configOverride - this object is deep-merged with the selected Detox configuration from .detoxrc
* @example
* beforeAll(async () => {
* await detox.init();
* });
*/
init(configOverride?: Partial<DetoxConfig>, options?: DetoxInitOptions): Promise<void>;
beforeEach(...args: any[]): Promise<void>;
afterEach(...args: any[]): Promise<void>;
/**
* The cleanup phase should happen after all the tests have finished.
* This is the phase where the Detox server shuts down.
*
* @example
* after(async () => {
* await detox.cleanup();
* });
*/
cleanup(): Promise<void>;
/**
* Unstable. API to access an assembled detox config before it gets passed to testRunner
* or detox.init(). Use it only if you don't have another option.
* @internal
*/
hook(event: 'UNSAFE_configReady', listener: (config: unknown) => void): void;
}
interface DetoxInitOptions {
/**
* By default, Detox exports `device`, `expect`, `element`, `by` and `waitFor`
* as global variables. If you want to control their initialization manually,
* set this property to `false`.
*
* This is useful when during E2E tests you also need to run regular expectations
* in Node.js. Jest's `expect` for instance, will not be overridden by Detox when
* this option is used.
*/
initGlobals?: boolean;
/**
* By default, `await detox.init()` will uninstall and install the app.
* If you wish to reuse the existing app for a faster run, set the property to
* `false`.
*/
reuse?: boolean;
}
type Point2D = {
x: number,
y: number,
}
/**
* @deprecated
*/
type AppLaunchArgsOperationOptions = Partial<{
/** Changes the scope of the operation: transient or permanent app launch args */
permanent: boolean;
}>;
/**
* A construct allowing for the querying and modification of user arguments passed to an app upon launch by Detox.
*
* @see AppLaunchArgs#modify
* @see AppLaunchArgs#reset
* @see AppLaunchArgs#get
*/
interface AppLaunchArgs {
/**
* Shared (global) arguments that are not specific to a particular application.
* Selecting another app does not reset them, yet they still can be overridden
* by configuring app-specific launch args.
* @see Device#selectApp
* @see AppLaunchArgs
*/
readonly shared: ScopedAppLaunchArgs;
/**
* Modify the launch-arguments via a modifier object, according to the following logic:
* - Non-nullish modifier properties would set a new value or override the previous value of
* existing properties with the same name.
* - Modifier properties set to either `undefined` or `null` would delete the corresponding property
* if it existed.
* These custom app launch arguments get erased whenever you select a different application.
* If you need to share them between all the applications, use {@link AppLaunchArgs#shared} property.
* Note: app-specific launch args have a priority over shared ones.
*
* @param modifier The modifier object.
* @example
* // With current launch arguments set to:
* // {
* // mockServerPort: 1234,
* // mockServerCredentials: 'user@test.com:12345678',
* // }
* device.appLaunchArgs.modify({
* mockServerPort: 4321,
* mockServerCredentials: null,
* mockServerToken: 'abcdef',
* });
* await device.launchApp();
* // ==> launch-arguments become:
* // {
* // mockServerPort: 4321,
* // mockServerToken: 'abcdef',
* // }
*/
modify(modifier: object): this;
/**
* @deprecated Use {@link AppLaunchArgs#shared} instead.
*/
modify(modifier: object, options: AppLaunchArgsOperationOptions): this;
/**
* Reset all app-specific launch arguments (back to an empty object).
* If you need to reset the shared launch args, use {@link AppLaunchArgs#shared}.
*/
reset(): this;
/**
* @deprecated Use {@link AppLaunchArgs#shared} instead.
*/
reset(options: AppLaunchArgsOperationOptions): this;
/**
* Get all currently set launch arguments (including shared ones).
* @returns An object containing all launch-arguments.
* Note: mutating the values inside the result object is pointless, as it is immutable.
*/
get(): object;
/**
* @deprecated Use {@link AppLaunchArgs#shared} instead.
*/
get(options: AppLaunchArgsOperationOptions): object;
}
/**
* Shared (global) arguments that are not specific to a particular application.
*/
interface ScopedAppLaunchArgs {
/** @see AppLaunchArgs#modify */
modify(modifier: object): this;
/** @see AppLaunchArgs#reset */
reset(): this;
/** @see AppLaunchArgs#get */
get(): object;
}
interface Device {
/**
* 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,
* as used by simctl (e.g. AAAAAAAA-BBBB-CCCC-DDDD-EEEEEEEEEEEE).
*
* The value will be undefined until the device is properly prepared (i.e. in detox.init())
*/
id: string;
/**
* Holds a descriptive name of the device. Example: emulator-5554 (Pixel_API_29)
* The value will be undefined until the device is properly prepared (i.e. in detox.init()).
*/
name: string;
/**
* Select the current app (relevant only to multi-app configs) by its name.
* After execution, all app-specific device methods will target the selected app.
*
* @see DetoxAppConfig#name
* @example
* await device.selectApp('passenger');
* await device.launchApp(); // passenger
* // ... run tests for the passenger app
* await device.uninstallApp(); // passenger
* await device.selectApp('driver');
* await device.installApp(); // driver
* await device.launchApp(); // driver
* // ... run tests for the driver app
* await device.terminateApp(); // driver
*/
selectApp(app: string): Promise<void>;
/**
* Launch the app.
*
* <p>For info regarding launch arguments, refer to the [dedicated guide](https://wix.github.io/Detox/docs/api/launch-args).
*
* @example
* // 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
* await device.launchApp({newInstance: true});
* @example
* // Grant or deny runtime permissions for your application.
* await device.launchApp({permissions: {calendar: 'YES'}});
* @example
* // Mock opening the app from URL to test your app's deep link handling mechanism.
* await device.launchApp({url: url});
* @example
* // Start the app with some custom arguments.
* await device.launchApp({
* launchArgs: {arg1: 1, arg2: "2"},
* });
*/
launchApp(config?: DeviceLaunchAppConfig): Promise<void>;
/**
* Access the user-defined launch-arguments predefined through static scopes such as the Detox configuration file and
* command-line arguments. This access allows - through dedicated methods, for both value-querying and
* modification (see {@link AppLaunchArgs}).
* Refer to the [dedicated guide](https://wix.github.io/Detox/docs/api/launch-args) for complete details.
*
* @example
* // With Detox being preconfigured statically to use these arguments in app launch:
* // {
* // mockServerPort: 1234,
* // }
* // The following code would result in these arguments eventually passed into the launched app:
* // {
* // mockServerPort: 4321,
* // mockServerToken: 'uvwxyz',
* // }
* device.appLaunchArgs.modify({
* mockServerPort: 4321,
* mockServerToken: 'abcdef',
* });
* await device.launchApp({ launchArgs: { mockServerToken: 'uvwxyz' } }};
*
* @see AppLaunchArgs
*/
appLaunchArgs: AppLaunchArgs;
/**
* Terminate the app.
*
* @example
* // By default, terminateApp() with no params will terminate the app
* await device.terminateApp();
* @example
* // To terminate another app, specify its bundle id
* await device.terminateApp('other.bundle.id');
*/
terminateApp(bundle?: string): Promise<void>;
/**
* Send application to background by bringing com.apple.springboard to the foreground.
* Combining sendToHome() with launchApp({newInstance: false}) will simulate app coming back from background.
* @example
* await device.sendToHome();
* await device.launchApp({newInstance: false});
*/
sendToHome(): Promise<void>;
/**
* 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.
*
* @example await device.reloadReactNative()
*/
reloadReactNative(): Promise<void>;
/**
* By default, installApp() with no params will install the app file defined in the current configuration.
* To install another app, specify its path
* @example await device.installApp();
* @example await device.installApp('path/to/other/app');
*/
installApp(path?: any): Promise<void>;
/**
* By default, uninstallApp() with no params will uninstall the app defined in the current configuration.
* To uninstall another app, specify its bundle id
* @example await device.installApp('other.bundle.id');
*/
uninstallApp(bundle?: string): Promise<void>;
/**
* Reinstall the application if the APK has changed, or reset the user data otherwise (without reinstalling).
* Available for Android only.
*/
resetAppState(): Promise<void>;
/**
* Mock opening the app from URL. sourceApp is an optional parameter to specify source application bundle id.
*/
openURL(url: { url: string; sourceApp?: string }): Promise<void>;
/**
* Mock handling of received user notification when app is in foreground.
*/
sendUserNotification(...params: any[]): Promise<void>;
/**
* Mock handling of received user activity when app is in foreground.
*/
sendUserActivity(...params: any[]): Promise<void>;
/**
* Takes "portrait" or "landscape" and rotates the device to the given orientation. Currently only available in the iOS Simulator.
*/
setOrientation(orientation: Orientation): Promise<void>;
/**
* Sets the simulator/emulator location to the given latitude and longitude.
*
* <p/>On iOS `setLocation` is dependent on [fbsimctl](https://github.com/facebook/idb/tree/4b7929480c3c0f158f33f78a5b802c1d0e7030d2/fbsimctl)
* which [is now deprecated](https://github.com/wix/Detox/issues/1371).
* If `fbsimctl` is not installed, the command will fail, asking for it to be installed.
*
* <p/>On Android `setLocation` will work with both Android Emulator (bundled with Android development tools) and Genymotion.
* The correct permissions must be set in your app manifest.
*
* @example await device.setLocation(32.0853, 34.7818);
*/
setLocation(lat: number, lon: number): Promise<void>;
/**
* Disable EarlGrey's network synchronization mechanism on preferred endpoints. Useful if you want to on skip over synchronizing on certain URLs.
*
* @example await device.setURLBlacklist(['.*127.0.0.1.*']);
*/
setURLBlacklist(urls: string[]): Promise<void>;
/**
* 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.
*
* <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
* 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
* that area, **which is not recommended and can never be 100% stable.
* **Therefore, as a rule of thumb, test code running "inside" a sync-disabled mode must be reduced to the bare minimum.
*
* <p/>Note: Synchronization is enabled by default, and it gets **reenabled on every launch of a new instance of the app.**
*
* @example await device.disableSynchronization();
*/
disableSynchronization(): Promise<void>;
/**
* 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
* previous disabling of it through a call to `device.disableSynchronization()`.
*
* <p/>Warning: Making this call would resume synchronization **instantly**, having its returned promise only resolve when the app becomes idle again.
* 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
* remain suspended "forever" (i.e. until a safeguard time-out expires).
*
* @example await device.enableSynchronization();
*/
enableSynchronization(): Promise<void>;
/**
* Resets the Simulator to clean state (like the Simulator > Reset Content and Settings... menu item), especially removing previously set permissions.
*
* @example await device.resetContentAndSettings();
*/
resetContentAndSettings(): Promise<void>;
/**
* Returns the current device, ios or android.
*
* @example
* if (device.getPlatform() === 'ios') {
* await expect(loopSwitch).toHaveValue('1');
* }
*/
getPlatform(): 'ios' | 'android';
/**
* Takes a screenshot on the device and schedules putting it in the artifacts folder upon completion of the current test.
* @param name for the screenshot artifact
* @returns a temporary path to the screenshot.
* @example
* test('Menu items should have logout', async () => {
* const tempPath = await device.takeScreenshot('tap on menu');
* // The temporary path will remain valid until the test completion.
* // Afterwards, the screenshot will be moved, e.g.:
* // * on success, to: <artifacts-location>/✓ Menu items should have Logout/tap on menu.png
* // * on failure, to: <artifacts-location>/✗ Menu items should have Logout/tap on menu.png
* });
*/
takeScreenshot(name: string): Promise<string>;
/**
* (iOS only) Saves a view hierarchy snapshot (*.viewhierarchy) of the currently opened application
* to a temporary folder and schedules putting it to the artifacts folder upon the completion of
* the current test. The file can be opened later in Xcode 12.0 and above.
* @see https://developer.apple.com/documentation/xcode-release-notes/xcode-12-release-notes#:~:text=57933113
* @param [name="capture"] optional name for the *.viewhierarchy artifact
* @returns a temporary path to the captured view hierarchy snapshot.
* @example
* test('Menu items should have logout', async () => {
* await device.captureViewHierarchy('myElements');
* // The temporary path will remain valid until the test completion.
* // Afterwards, the artifact will be moved, e.g.:
* // * on success, to: <artifacts-location>/✓ Menu items should have Logout/myElements.viewhierarchy
* // * on failure, to: <artifacts-location>/✗ Menu items should have Logout/myElements.viewhierarchy
* });
*/
captureViewHierarchy(name?: string): Promise<string>;
/**
* Simulate shake (iOS Only)
*/
shake(): Promise<void>;
/**
* Toggles device enrollment in biometric auth (TouchID or FaceID) (iOS Only)
* @example await device.setBiometricEnrollment(true);
* @example await device.setBiometricEnrollment(false);
*/
setBiometricEnrollment(enabled: boolean): Promise<void>;
/**
* Simulates the success of a face match via FaceID (iOS Only)
*/
matchFace(): Promise<void>;
/**
* Simulates the failure of a face match via FaceID (iOS Only)
*/
unmatchFace(): Promise<void>;
/**
* Simulates the success of a finger match via TouchID (iOS Only)
*/
matchFinger(): Promise<void>;
/**
* Simulates the failure of a finger match via TouchID (iOS Only)
*/
unmatchFinger(): Promise<void>;
/**
* Clears the simulator keychain (iOS Only)
*/
clearKeychain(): Promise<void>;
/**
* Simulate press back button (Android Only)
* @example await device.pressBack();
*/
pressBack(): Promise<void>;
/**
* (Android Only)
* Exposes UiAutomator's UiDevice API (https://developer.android.com/reference/android/support/test/uiautomator/UiDevice).
* This is not a part of the official Detox API,
* it may break and change whenever an update to UiDevice or UiAutomator gradle dependencies ('androidx.test.uiautomator:uiautomator') is introduced.
* UIDevice's autogenerated code reference: https://github.com/wix/Detox/blob/master/detox/src/android/espressoapi/UIDevice.js
*/
getUiDevice(): Promise<void>;
/**
* (Android Only)
* Runs `adb reverse tcp:PORT tcp:PORT` for the current device
* to enable network requests forwarding on localhost:PORT (computer<->device).
* For more information, see {@link https://www.reddit.com/r/reactnative/comments/5etpqw/what_do_you_call_what_adb_reverse_is_doing|here}.
* This is a no-op when running on iOS.
*/
reverseTcpPort(port: number): Promise<void>;
/**
* (Android Only)
* Runs `adb reverse --remove tcp:PORT tcp:PORT` for the current device
* to disable network requests forwarding on localhost:PORT (computer<->device).
* For more information, see {@link https://www.reddit.com/r/reactnative/comments/5etpqw/what_do_you_call_what_adb_reverse_is_doing|here}.
* This is a no-op when running on iOS.
*/
unreverseTcpPort(port: number): Promise<void>;
}
/**
* @deprecated
*/
type DetoxAny = NativeElement & WaitFor;
interface ElementFacade {
(by: NativeMatcher): IndexableNativeElement;
}
interface IndexableNativeElement extends NativeElement {
/**
* Choose from multiple elements matching the same matcher using index
* @example await element(by.text('Product')).atIndex(2).tap();
*/
atIndex(index: number): NativeElement;
}
interface NativeElement extends NativeElementActions {
}
interface ByFacade {
/**
* by.id will match an id that is given to the view via testID prop.
* @example
* // In a React Native component add testID like so:
* <TouchableOpacity testID={'tap_me'}>
* // Then match with by.id:
* await element(by.id('tap_me'));
*/
id(id: string): NativeMatcher;
/**
* Find an element by text, useful for text fields, buttons.
* @example await element(by.text('Tap Me'));
*/
text(text: string): NativeMatcher;
/**
* Find an element by accessibilityLabel on iOS, or by contentDescription on Android.
* @example await element(by.label('Welcome'));
*/
label(label: string): NativeMatcher;
/**
* Find an element by native view type.
* @example await element(by.type('RCTImageView'));
*/
type(nativeViewType: string): NativeMatcher;
/**
* Find an element with an accessibility trait. (iOS only)
* @example await element(by.traits(['button']));
*/
traits(traits: string[]): NativeMatcher;
/**
* Collection of web matchers
*/
readonly web: ByWebFacade;
}
interface ByWebFacade {
/**
* Find an element on the DOM tree by its id
* @param id
* @example
* web.element(by.web.id('testingh1'))
*/
id(id: string): WebMatcher;
/**
* Find an element on the DOM tree by its CSS class
* @param className
* @example
* web.element(by.web.className('a'))
*/
className(className: string): WebMatcher;
/**
* Find an element on the DOM tree matching the given CSS selector
* @param cssSelector
* @example
* web.element(by.web.cssSelector('#cssSelector'))
*/
cssSelector(cssSelector: string): WebMatcher;
/**
* Find an element on the DOM tree by its "name" attribute
* @param name
* @example
* web.element(by.web.name('sec_input'))
*/
name(name: string): WebMatcher;
/**
* Find an element on the DOM tree by its XPath
* @param xpath
* @example
* web.element(by.web.xpath('//*[@id="testingh1-1"]'))
*/
xpath(xpath: string): WebMatcher;
/**
* Find an <a> element on the DOM tree by its link text (href content)
* @param linkText
* @example
* web.element(by.web.href('disney.com'))
*/
href(linkText: string): WebMatcher;
/**
* Find an <a> element on the DOM tree by its partial link text (href content)
* @param linkTextFragment
* @example
* web.element(by.web.hrefContains('disney'))
*/
hrefContains(linkTextFragment: string): WebMatcher;
/**
* Find an element on the DOM tree by its tag name
* @param tag
* @example
* web.element(by.web.tag('mark'))
*/
tag(tagName: string): WebMatcher;
}
interface NativeMatcher {
/**
* Find an element satisfying all the matchers
* @example await element(by.text('Product').and(by.id('product_name'));
*/
and(by: NativeMatcher): NativeMatcher;
/**
* Find an element by a matcher with a parent matcher
* @example await element(by.id('Grandson883').withAncestor(by.id('Son883')));
*/
withAncestor(parentBy: NativeMatcher): NativeMatcher;
/**
* Find an element by a matcher with a child matcher
* @example await element(by.id('Son883').withDescendant(by.id('Grandson883')));
*/
withDescendant(childBy: NativeMatcher): NativeMatcher;
}
interface WebMatcher {
__web__: any; // prevent type coersion
}
interface ExpectFacade {
(element: NativeElement): Expect;
(webElement: WebElement): WebExpect;
}
interface WebViewElement {
element(webMatcher: WebMatcher): IndexableWebElement;
}
interface WebFacade extends WebViewElement {
/**
* Gets the webview element as a testing element.
* @param matcher a simple view matcher for the webview element in th UI hierarchy.
* If there is only ONE webview element in the UI hierarchy, its NOT a must to supply it.
* If there are MORE then one webview element in the UI hierarchy you MUST supply are view matcher.
*/
(matcher?: NativeMatcher): WebViewElement;
}
interface Expect<R = Promise<void>> {
/**
* Expect the view to be at least N% visible. If no number is provided then defaults to 75%. Negating this
* expectation with a `not` expects the view's visible area to be smaller than N%.
* @param pct optional integer ranging from 1 to 100, indicating how much percent of the view should be
* visible to the user to be accepted.
* @example await expect(element(by.id('UniqueId204'))).toBeVisible(35);
*/
toBeVisible(pct?: number): R;
/**
* Negate the expectation.
* @example await expect(element(by.id('UniqueId205'))).not.toBeVisible();
*/
not: this;
/**
* Expect the view to not be visible.
* @example await expect(element(by.id('UniqueId205'))).toBeNotVisible();
* @deprecated Use `.not.toBeVisible()` instead.
*/
toBeNotVisible(): R;
/**
* Expect the view to exist in the UI hierarchy.
* @example await expect(element(by.id('UniqueId205'))).toExist();
*/
toExist(): R;
/**
* Expect the view to not exist in the UI hierarchy.
* @example await expect(element(by.id('RandomJunk959'))).toNotExist();
* @deprecated Use `.not.toExist()` instead.
*/
toNotExist(): R;
/**
* Expect the view to be focused.
* @example await expect(element(by.id('loginInput'))).toBeFocused();
*/
toBeFocused(): R;
/**
* Expect the view not to be focused.
* @example await expect(element(by.id('passwordInput'))).toBeNotFocused();
* @deprecated Use `.not.toBeFocused()` instead.
*/
toBeNotFocused(): R;