detox 20.12.1 → 20.13.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (141) hide show
  1. package/Detox-android/com/wix/detox/{20.12.1/detox-20.12.1-javadoc.jar → 20.13.0/detox-20.13.0-javadoc.jar} +0 -0
  2. package/Detox-android/com/wix/detox/20.13.0/detox-20.13.0-javadoc.jar.md5 +1 -0
  3. package/Detox-android/com/wix/detox/20.13.0/detox-20.13.0-javadoc.jar.sha1 +1 -0
  4. package/Detox-android/com/wix/detox/20.13.0/detox-20.13.0-javadoc.jar.sha256 +1 -0
  5. package/Detox-android/com/wix/detox/20.13.0/detox-20.13.0-javadoc.jar.sha512 +1 -0
  6. package/Detox-android/com/wix/detox/{20.12.1/detox-20.12.1-sources.jar → 20.13.0/detox-20.13.0-sources.jar} +0 -0
  7. package/Detox-android/com/wix/detox/20.13.0/detox-20.13.0-sources.jar.md5 +1 -0
  8. package/Detox-android/com/wix/detox/20.13.0/detox-20.13.0-sources.jar.sha1 +1 -0
  9. package/Detox-android/com/wix/detox/20.13.0/detox-20.13.0-sources.jar.sha256 +1 -0
  10. package/Detox-android/com/wix/detox/20.13.0/detox-20.13.0-sources.jar.sha512 +1 -0
  11. package/Detox-android/com/wix/detox/20.13.0/detox-20.13.0.aar +0 -0
  12. package/Detox-android/com/wix/detox/20.13.0/detox-20.13.0.aar.md5 +1 -0
  13. package/Detox-android/com/wix/detox/20.13.0/detox-20.13.0.aar.sha1 +1 -0
  14. package/Detox-android/com/wix/detox/20.13.0/detox-20.13.0.aar.sha256 +1 -0
  15. package/Detox-android/com/wix/detox/20.13.0/detox-20.13.0.aar.sha512 +1 -0
  16. package/Detox-android/com/wix/detox/{20.12.1/detox-20.12.1.pom → 20.13.0/detox-20.13.0.pom} +1 -7
  17. package/Detox-android/com/wix/detox/20.13.0/detox-20.13.0.pom.md5 +1 -0
  18. package/Detox-android/com/wix/detox/20.13.0/detox-20.13.0.pom.sha1 +1 -0
  19. package/Detox-android/com/wix/detox/20.13.0/detox-20.13.0.pom.sha256 +1 -0
  20. package/Detox-android/com/wix/detox/20.13.0/detox-20.13.0.pom.sha512 +1 -0
  21. package/Detox-android/com/wix/detox/maven-metadata.xml +4 -4
  22. package/Detox-android/com/wix/detox/maven-metadata.xml.md5 +1 -1
  23. package/Detox-android/com/wix/detox/maven-metadata.xml.sha1 +1 -1
  24. package/Detox-android/com/wix/detox/maven-metadata.xml.sha256 +1 -1
  25. package/Detox-android/com/wix/detox/maven-metadata.xml.sha512 +1 -1
  26. package/Detox-ios-src.tbz +0 -0
  27. package/Detox-ios.tbz +0 -0
  28. package/android/detox/build.gradle +4 -3
  29. package/android/detox/src/full/java/com/wix/detox/espresso/action/AdjustSliderToPositionAction.kt +2 -2
  30. package/android/detox/src/full/java/com/wix/detox/espresso/action/GetAttributesAction.kt +30 -31
  31. package/android/detox/src/full/java/com/wix/detox/espresso/common/MaterialSliderHelper.kt +21 -0
  32. package/android/detox/src/full/java/com/wix/detox/espresso/common/{SliderHelper.kt → ReactSliderHelper.kt} +6 -5
  33. package/android/detox/src/full/java/com/wix/detox/espresso/matcher/ViewMatchers.kt +2 -2
  34. package/android/detox/src/testFull/java/com/wix/detox/espresso/common/MaterialSliderHelperTest.kt +33 -0
  35. package/android/detox/src/testFull/java/com/wix/detox/espresso/common/{SliderHelperTest.kt → ReactSliderHelperTest.kt} +3 -3
  36. package/internals.d.ts +10 -1
  37. package/local-cli/reset-lock-file.js +5 -9
  38. package/package.json +5 -6
  39. package/runners/jest/reporters/DetoxReporter.js +127 -9
  40. package/runners/jest/testEnvironment/index.js +5 -0
  41. package/src/DetoxWorker.js +5 -11
  42. package/src/artifacts/providers/index.js +3 -3
  43. package/src/artifacts/screenshot/SimulatorScreenshotPlugin.js +0 -17
  44. package/src/configuration/composeLoggerConfig.js +1 -0
  45. package/src/devices/allocation/DeviceAllocator.js +66 -20
  46. package/src/devices/allocation/DeviceList.js +44 -0
  47. package/src/devices/allocation/DeviceRegistry.js +189 -0
  48. package/src/devices/allocation/drivers/AllocationDriverBase.d.ts +15 -0
  49. package/src/devices/{common/drivers/android/tools → allocation/drivers/android}/FreeDeviceFinder.js +11 -10
  50. package/src/devices/allocation/drivers/android/attached/AttachedAndroidAllocDriver.js +22 -17
  51. package/src/devices/allocation/drivers/android/emulator/EmulatorAllocDriver.js +97 -38
  52. package/src/devices/allocation/drivers/android/emulator/EmulatorLauncher.js +32 -45
  53. package/src/devices/allocation/drivers/android/emulator/FreeEmulatorFinder.js +1 -1
  54. package/src/devices/allocation/drivers/android/emulator/FreePortFinder.js +37 -0
  55. package/src/devices/allocation/drivers/android/emulator/launchEmulatorProcess.js +3 -3
  56. package/src/devices/allocation/drivers/android/genycloud/GenyAllocDriver.js +104 -32
  57. package/src/devices/allocation/drivers/android/genycloud/GenyInstanceLauncher.js +40 -31
  58. package/src/devices/allocation/drivers/android/genycloud/GenyRegistry.js +121 -0
  59. package/src/devices/allocation/drivers/android/genycloud/services/GenyInstanceLifecycleService.js +24 -0
  60. package/src/devices/{common → allocation}/drivers/android/genycloud/services/GenyRecipesService.js +1 -1
  61. package/src/devices/allocation/drivers/android/genycloud/services/dto/GenyInstance.js +83 -0
  62. package/src/devices/allocation/drivers/android/genycloud/services/dto/GenyRecipe.js +25 -0
  63. package/src/devices/allocation/drivers/ios/SimulatorAllocDriver.js +94 -51
  64. package/src/devices/allocation/drivers/ios/SimulatorLauncher.js +11 -7
  65. package/src/devices/allocation/drivers/ios/SimulatorQuery.js +24 -0
  66. package/src/devices/allocation/factories/android.js +29 -35
  67. package/src/devices/allocation/factories/ios.js +7 -5
  68. package/src/devices/common/drivers/DeviceCookie.d.ts +12 -0
  69. package/src/devices/common/drivers/android/cookies.d.ts +11 -0
  70. package/src/devices/common/drivers/android/emulator/exec/EmulatorExec.js +17 -5
  71. package/src/devices/common/drivers/android/exec/ADB.js +1 -0
  72. package/src/devices/common/drivers/ios/cookies.d.ts +9 -0
  73. package/src/devices/cookies/index.js +0 -6
  74. package/src/devices/runtime/drivers/android/genycloud/GenyCloudDriver.js +7 -6
  75. package/src/devices/runtime/factories/android.js +3 -11
  76. package/src/devices/runtime/factories/ios.js +3 -2
  77. package/src/{servicelocator → devices/servicelocator}/android/emulatorServiceLocator.js +1 -1
  78. package/src/devices/servicelocator/android/genycloudServiceLocator.js +17 -0
  79. package/src/devices/servicelocator/android/index.js +23 -0
  80. package/src/{validation → devices/validation}/EnvironmentValidatorBase.js +1 -0
  81. package/src/{validation → devices/validation}/android/GenycloudEnvValidator.js +2 -2
  82. package/src/{validation → devices/validation}/factories/index.js +1 -1
  83. package/src/{validation → devices/validation}/ios/IosSimulatorEnvValidator.js +2 -2
  84. package/src/environmentFactory.js +1 -11
  85. package/src/ipc/IPCClient.js +22 -1
  86. package/src/ipc/IPCServer.js +40 -1
  87. package/src/ipc/SessionState.js +1 -0
  88. package/src/logger/DetoxLogger.js +2 -2
  89. package/src/realms/DetoxContext.js +8 -0
  90. package/src/realms/DetoxInternalsFacade.js +1 -0
  91. package/src/realms/DetoxPrimaryContext.js +48 -42
  92. package/src/realms/DetoxSecondaryContext.js +27 -0
  93. package/src/realms/symbols.js +6 -0
  94. package/src/utils/PIDService.js +27 -0
  95. package/src/utils/environment.js +8 -15
  96. package/src/utils/errorUtils.js +3 -3
  97. package/tsconfig.json +5 -3
  98. package/Detox-android/com/wix/detox/20.12.1/detox-20.12.1-javadoc.jar.md5 +0 -1
  99. package/Detox-android/com/wix/detox/20.12.1/detox-20.12.1-javadoc.jar.sha1 +0 -1
  100. package/Detox-android/com/wix/detox/20.12.1/detox-20.12.1-javadoc.jar.sha256 +0 -1
  101. package/Detox-android/com/wix/detox/20.12.1/detox-20.12.1-javadoc.jar.sha512 +0 -1
  102. package/Detox-android/com/wix/detox/20.12.1/detox-20.12.1-sources.jar.md5 +0 -1
  103. package/Detox-android/com/wix/detox/20.12.1/detox-20.12.1-sources.jar.sha1 +0 -1
  104. package/Detox-android/com/wix/detox/20.12.1/detox-20.12.1-sources.jar.sha256 +0 -1
  105. package/Detox-android/com/wix/detox/20.12.1/detox-20.12.1-sources.jar.sha512 +0 -1
  106. package/Detox-android/com/wix/detox/20.12.1/detox-20.12.1.aar +0 -0
  107. package/Detox-android/com/wix/detox/20.12.1/detox-20.12.1.aar.md5 +0 -1
  108. package/Detox-android/com/wix/detox/20.12.1/detox-20.12.1.aar.sha1 +0 -1
  109. package/Detox-android/com/wix/detox/20.12.1/detox-20.12.1.aar.sha256 +0 -1
  110. package/Detox-android/com/wix/detox/20.12.1/detox-20.12.1.aar.sha512 +0 -1
  111. package/Detox-android/com/wix/detox/20.12.1/detox-20.12.1.pom.md5 +0 -1
  112. package/Detox-android/com/wix/detox/20.12.1/detox-20.12.1.pom.sha1 +0 -1
  113. package/Detox-android/com/wix/detox/20.12.1/detox-20.12.1.pom.sha256 +0 -1
  114. package/Detox-android/com/wix/detox/20.12.1/detox-20.12.1.pom.sha512 +0 -1
  115. package/src/devices/DeviceRegistry.js +0 -176
  116. package/src/devices/allocation/drivers/AllocationDriverBase.js +0 -30
  117. package/src/devices/allocation/drivers/android/attached/AttachedAndroidLauncher.js +0 -13
  118. package/src/devices/allocation/drivers/android/emulator/EmulatorAllocationHelper.js +0 -72
  119. package/src/devices/allocation/drivers/android/genycloud/GenyDeviceRegistryFactory.js +0 -16
  120. package/src/devices/allocation/drivers/android/genycloud/GenyInstanceAllocationHelper.js +0 -65
  121. package/src/devices/common/drivers/DeviceAllocationHelper.js +0 -20
  122. package/src/devices/common/drivers/DeviceLauncher.js +0 -19
  123. package/src/devices/common/drivers/android/genycloud/services/GenyInstanceLifecycleService.js +0 -25
  124. package/src/devices/common/drivers/android/genycloud/services/GenyInstanceLookupService.js +0 -38
  125. package/src/devices/common/drivers/android/genycloud/services/GenyInstanceNaming.js +0 -14
  126. package/src/devices/common/drivers/android/genycloud/services/dto/GenyInstance.js +0 -66
  127. package/src/devices/common/drivers/android/genycloud/services/dto/GenyRecipe.js +0 -13
  128. package/src/devices/cookies/AndroidDeviceCookie.js +0 -13
  129. package/src/devices/cookies/AndroidEmulatorCookie.js +0 -6
  130. package/src/devices/cookies/AttachedAndroidDeviceCookie.js +0 -12
  131. package/src/devices/cookies/DeviceCookie.js +0 -4
  132. package/src/devices/cookies/GenycloudEmulatorCookie.js +0 -20
  133. package/src/devices/cookies/IosCookie.js +0 -6
  134. package/src/devices/cookies/IosSimulatorCookie.js +0 -10
  135. package/src/devices/lifecycle/GenyGlobalLifecycleHandler.js +0 -71
  136. package/src/devices/lifecycle/factories/GenyGlobalLifecycleHandlerFactory.js +0 -18
  137. package/src/servicelocator/android/genycloudServiceLocator.js +0 -21
  138. package/src/servicelocator/android/index.js +0 -25
  139. package/src/servicelocator/ios.js +0 -7
  140. /package/src/devices/{common → allocation}/drivers/android/genycloud/exec/GenyCloudExec.js +0 -0
  141. /package/src/devices/{common → allocation}/drivers/android/genycloud/services/GenyAuthService.js +0 -0
@@ -2,11 +2,12 @@
2
2
  const DeviceAllocatorFactory = require('./base');
3
3
 
4
4
  class AndroidEmulator extends DeviceAllocatorFactory {
5
- _createDriver({ eventEmitter }) {
6
- const serviceLocator = require('../../../servicelocator/android');
5
+ _createDriver({ detoxSession, detoxConfig }) {
6
+ const serviceLocator = require('../../servicelocator/android');
7
7
  const adb = serviceLocator.adb;
8
8
  const emulatorExec = serviceLocator.emulator.exec;
9
- const deviceRegistry = serviceLocator.deviceRegistry;
9
+ const DeviceRegistry = require('../../allocation/DeviceRegistry');
10
+ const deviceRegistry = new DeviceRegistry({ sessionId: detoxSession.id });
10
11
 
11
12
  const AVDsResolver = require('../drivers/android/emulator/AVDsResolver');
12
13
  const avdsResolver = new AVDsResolver(emulatorExec);
@@ -20,74 +21,67 @@ class AndroidEmulator extends DeviceAllocatorFactory {
20
21
  const FreeEmulatorFinder = require('../drivers/android/emulator/FreeEmulatorFinder');
21
22
  const freeEmulatorFinder = new FreeEmulatorFinder(adb, deviceRegistry);
22
23
 
23
- const EmulatorLauncher = require('../drivers/android/emulator/EmulatorLauncher');
24
- const emulatorLauncher = new EmulatorLauncher({ adb, emulatorExec, eventEmitter });
24
+ const FreePortFinder = require('../drivers/android/emulator/FreePortFinder');
25
+ const freePortFinder = new FreePortFinder();
25
26
 
26
- const EmulatorAllocationHelper = require('../drivers/android/emulator/EmulatorAllocationHelper');
27
- const allocationHelper = new EmulatorAllocationHelper(deviceRegistry, freeEmulatorFinder);
27
+ const EmulatorLauncher = require('../drivers/android/emulator/EmulatorLauncher');
28
+ const emulatorLauncher = new EmulatorLauncher({ adb, emulatorExec });
28
29
 
29
30
  const EmulatorAllocDriver = require('../drivers/android/emulator/EmulatorAllocDriver');
30
31
  return new EmulatorAllocDriver({
31
32
  adb,
32
33
  avdValidator,
34
+ detoxConfig,
35
+ deviceRegistry,
33
36
  emulatorVersionResolver,
34
37
  emulatorLauncher,
35
- allocationHelper,
38
+ freeDeviceFinder: freeEmulatorFinder,
39
+ freePortFinder,
36
40
  });
37
41
  }
38
42
  }
39
43
 
40
44
  class AndroidAttached extends DeviceAllocatorFactory {
41
- _createDriver({ eventEmitter }) {
42
- const serviceLocator = require('../../../servicelocator/android');
45
+ _createDriver({ detoxSession, detoxConfig }) {
46
+ const serviceLocator = require('../../servicelocator/android');
43
47
  const adb = serviceLocator.adb;
44
- const deviceRegistry = serviceLocator.deviceRegistry;
48
+ const DeviceRegistry = require('../../allocation/DeviceRegistry');
49
+ const deviceRegistry = new DeviceRegistry({ sessionId: detoxSession.id });
45
50
 
46
- const FreeDeviceFinder = require('../../common/drivers/android/tools/FreeDeviceFinder');
51
+ const FreeDeviceFinder = require('../drivers/android/FreeDeviceFinder');
47
52
  const freeDeviceFinder = new FreeDeviceFinder(adb, deviceRegistry);
48
53
 
49
- const AttachedAndroidLauncher = require('../drivers/android/attached/AttachedAndroidLauncher');
50
- const attachedAndroidLauncher = new AttachedAndroidLauncher(eventEmitter);
51
-
52
54
  const AttachedAndroidAllocDriver = require('../drivers/android/attached/AttachedAndroidAllocDriver');
53
- return new AttachedAndroidAllocDriver({ adb, deviceRegistry, freeDeviceFinder, attachedAndroidLauncher });
55
+ return new AttachedAndroidAllocDriver({ adb, deviceRegistry, freeDeviceFinder });
54
56
  }
55
57
  }
56
58
 
57
59
  class Genycloud extends DeviceAllocatorFactory {
58
- _createDriver({ eventEmitter }) {
59
- const serviceLocator = require('../../../servicelocator/android');
60
+ _createDriver(deps) {
61
+ const serviceLocator = require('../../servicelocator/android');
60
62
  const adb = serviceLocator.adb;
61
63
  const exec = serviceLocator.genycloud.exec;
62
- const deviceRegistry = serviceLocator.genycloud.runtimeDeviceRegistry;
63
- const deviceCleanupRegistry = serviceLocator.genycloud.cleanupDeviceRegistry;
64
64
 
65
- const InstanceNaming = require('../../common/drivers/android/genycloud/services/GenyInstanceNaming');
66
- const instanceNaming = new InstanceNaming(); // TODO should consider a permissive impl for debug/dev mode. Maybe even a custom arg in package.json (Detox > ... > genycloud > sharedAccount: false)
67
-
68
- const RecipesService = require('../../common/drivers/android/genycloud/services/GenyRecipesService');
65
+ const RecipesService = require('../drivers/android/genycloud/services/GenyRecipesService');
69
66
  const recipeService = new RecipesService(exec);
70
67
 
71
- const InstanceLookupService = require('../../common/drivers/android/genycloud/services/GenyInstanceLookupService');
72
- const instanceLookupService = new InstanceLookupService(exec, instanceNaming, deviceRegistry);
73
-
74
- const InstanceLifecycleService = require('../../common/drivers/android/genycloud/services/GenyInstanceLifecycleService');
75
- const instanceLifecycleService = new InstanceLifecycleService(exec, instanceNaming);
68
+ const InstanceLifecycleService = require('../drivers/android/genycloud/services/GenyInstanceLifecycleService');
69
+ const instanceLifecycleService = new InstanceLifecycleService(exec);
76
70
 
77
71
  const RecipeQuerying = require('../drivers/android/genycloud/GenyRecipeQuerying');
78
72
  const recipeQuerying = new RecipeQuerying(recipeService);
79
73
 
80
- const InstanceAllocationHelper = require('../drivers/android/genycloud/GenyInstanceAllocationHelper');
81
- const allocationHelper = new InstanceAllocationHelper({ deviceRegistry, instanceLookupService, instanceLifecycleService });
82
-
83
74
  const InstanceLauncher = require('../drivers/android/genycloud/GenyInstanceLauncher');
75
+ const instanceLauncher = new InstanceLauncher({ genyCloudExec: exec, instanceLifecycleService });
76
+
84
77
  const GenyAllocDriver = require('../drivers/android/genycloud/GenyAllocDriver');
85
- const instanceLauncher = new InstanceLauncher({ instanceLifecycleService, instanceLookupService, deviceCleanupRegistry, eventEmitter });
78
+
86
79
  return new GenyAllocDriver({
87
80
  adb,
88
- recipeQuerying,
89
- allocationHelper,
90
81
  instanceLauncher,
82
+ instanceLifecycleService,
83
+ recipeQuerying,
84
+ ...deps,
91
85
  });
92
86
  }
93
87
  }
@@ -2,16 +2,18 @@
2
2
  const DeviceAllocatorFactory = require('./base');
3
3
 
4
4
  class IosSimulator extends DeviceAllocatorFactory {
5
- _createDriver({ eventEmitter }) {
6
- const serviceLocator = require('../../../servicelocator/ios');
7
- const applesimutils = serviceLocator.appleSimUtils;
8
- const deviceRegistry = serviceLocator.deviceRegistry;
5
+ _createDriver({ detoxConfig, detoxSession, eventEmitter }) {
6
+ const AppleSimUtils = require('../../../devices/common/drivers/ios/tools/AppleSimUtils');
7
+ const applesimutils = new AppleSimUtils();
8
+
9
+ const DeviceRegistry = require('../../../devices/allocation/DeviceRegistry');
10
+ const deviceRegistry = new DeviceRegistry({ sessionId: detoxSession.id });
9
11
 
10
12
  const SimulatorLauncher = require('../drivers/ios/SimulatorLauncher');
11
13
  const simulatorLauncher = new SimulatorLauncher({ applesimutils, eventEmitter });
12
14
 
13
15
  const SimulatorAllocDriver = require('../drivers/ios/SimulatorAllocDriver');
14
- return new SimulatorAllocDriver({ deviceRegistry, applesimutils, simulatorLauncher });
16
+ return new SimulatorAllocDriver({ detoxConfig, deviceRegistry, applesimutils, simulatorLauncher });
15
17
  }
16
18
  }
17
19
 
@@ -0,0 +1,12 @@
1
+ /* eslint-disable import/no-unresolved,node/no-missing-import,node/no-unsupported-features/es-syntax */
2
+
3
+ /**
4
+ * A serializable object that represents a device.
5
+ */
6
+ export interface DeviceCookie {
7
+ /** The device's unique identifier. */
8
+ id: string;
9
+ /** The display name of the device. */
10
+ name?: string;
11
+ }
12
+
@@ -0,0 +1,11 @@
1
+ /* eslint-disable import/no-unresolved,node/no-missing-import,node/no-unsupported-features/es-syntax */
2
+ import GenyInstance from '../../../allocation/drivers/android/genycloud/services/dto/GenyInstance';
3
+ import { DeviceCookie } from '../DeviceCookie';
4
+
5
+ interface AndroidDeviceCookie extends DeviceCookie {
6
+ adbName: string;
7
+ }
8
+
9
+ interface GenycloudEmulatorCookie extends AndroidDeviceCookie {
10
+ instance: GenyInstance;
11
+ }
@@ -32,19 +32,31 @@ class QueryVersionCommand extends ExecCommand {
32
32
  }
33
33
 
34
34
  class LaunchCommand extends ExecCommand {
35
- constructor(emulatorName, options) {
35
+ constructor(options) {
36
36
  super();
37
37
  this._options = options;
38
- this._args = this._getEmulatorArgs(emulatorName);
39
- this.port = options.port;
38
+ this._args = this._getEmulatorArgs();
39
+ }
40
+
41
+ get adbName() {
42
+ return this._options.adbName;
43
+ }
44
+
45
+ get avdName() {
46
+ return this._options.avdName;
47
+ }
48
+
49
+ get port() {
50
+ return this._options.port;
40
51
  }
41
52
 
42
53
  _getArgs() {
43
54
  return this._args;
44
55
  }
45
56
 
46
- _getEmulatorArgs(emulatorName) {
57
+ _getEmulatorArgs() {
47
58
  const {
59
+ avdName,
48
60
  bootArgs,
49
61
  gpuMode = this._getDefaultGPUMode(),
50
62
  headless,
@@ -64,7 +76,7 @@ class LaunchCommand extends ExecCommand {
64
76
  port ? '-port' : '',
65
77
  port ? `${port}` : '',
66
78
  ...deviceBootArgs,
67
- `@${emulatorName}`
79
+ `@${avdName}`
68
80
  ]);
69
81
 
70
82
  return emulatorArgs;
@@ -18,6 +18,7 @@ class ADB {
18
18
 
19
19
  async devices() {
20
20
  const { stdout } = await this.adbCmd('', 'devices', { verbosity: 'high' });
21
+ /** @type {DeviceHandle[]} */
21
22
  const devices = _.chain(stdout)
22
23
  .trim()
23
24
  .split('\n')
@@ -0,0 +1,9 @@
1
+ /* eslint-disable import/no-unresolved,node/no-missing-import,node/no-unsupported-features/es-syntax */
2
+ import { DeviceCookie } from '../DeviceCookie';
3
+
4
+ interface IosSimulatorCookie extends DeviceCookie {
5
+ udid: string;
6
+ type?: string;
7
+ bootArgs?: string;
8
+ headless?: boolean;
9
+ }
@@ -1,6 +0,0 @@
1
- module.exports = {
2
- IosSimulatorCookie: require('./IosSimulatorCookie'),
3
- AttachedAndroidDeviceCookie: require('./AttachedAndroidDeviceCookie'),
4
- AndroidEmulatorCookie: require('./AndroidEmulatorCookie'),
5
- GenycloudEmulatorCookie: require('./GenycloudEmulatorCookie'),
6
- };
@@ -8,21 +8,22 @@ const AndroidDriver = require('../AndroidDriver');
8
8
 
9
9
  /**
10
10
  * @typedef GenycloudDriverProps
11
- * @property instance { GenyInstance } The DTO associated with the cloud instance
11
+ * @property adbName { GenyInstance } The DTO associated with the cloud instance
12
12
  */
13
13
 
14
14
  class GenyCloudDriver extends AndroidDriver {
15
15
  /**
16
16
  * @param deps { GenycloudDriverDeps }
17
- * @param props { GenycloudDriverProps }
17
+ * @param props { GenycloudEmulatorCookie }
18
18
  */
19
- constructor(deps, { instance }) {
20
- super(deps, { adbName: instance.adbName });
21
- this.instance = instance;
19
+ constructor(deps, { adbName, name }) {
20
+ super(deps, { adbName });
21
+
22
+ this._instanceName = name;
22
23
  }
23
24
 
24
25
  getDeviceName() {
25
- return this.instance.toString();
26
+ return this._instanceName;
26
27
  }
27
28
 
28
29
  async setLocation(lat, lon) {
@@ -3,7 +3,7 @@ const RuntimeDeviceFactory = require('./base');
3
3
 
4
4
  class RuntimeDriverFactoryAndroid extends RuntimeDeviceFactory {
5
5
  _createDriverDependencies(commonDeps) {
6
- const serviceLocator = require('../../../servicelocator/android');
6
+ const serviceLocator = require('../../servicelocator/android');
7
7
  const adb = serviceLocator.adb;
8
8
  const aapt = serviceLocator.aapt;
9
9
  const apkValidator = serviceLocator.apkValidator;
@@ -43,23 +43,15 @@ class AndroidEmulator extends RuntimeDriverFactoryAndroid {
43
43
 
44
44
  class AndroidAttached extends RuntimeDriverFactoryAndroid {
45
45
  _createDriver(deviceCookie, deps, configs) {
46
- const props = {
47
- adbName: deviceCookie.adbName,
48
- };
49
-
50
46
  const { AttachedAndroidRuntimeDriver } = require('../drivers');
51
- return new AttachedAndroidRuntimeDriver(deps, props);
47
+ return new AttachedAndroidRuntimeDriver(deps, deviceCookie);
52
48
  }
53
49
  }
54
50
 
55
51
  class Genycloud extends RuntimeDriverFactoryAndroid {
56
52
  _createDriver(deviceCookie, deps, configs) {
57
- const props = {
58
- instance: deviceCookie.instance,
59
- };
60
-
61
53
  const { GenycloudRuntimeDriver } = require('../drivers');
62
- return new GenycloudRuntimeDriver(deps, props);
54
+ return new GenycloudRuntimeDriver(deps, deviceCookie);
63
55
  }
64
56
  }
65
57
 
@@ -2,10 +2,11 @@ const RuntimeDeviceFactory = require('./base');
2
2
 
3
3
  class RuntimeDriverFactoryIos extends RuntimeDeviceFactory {
4
4
  _createDriverDependencies(commonDeps) {
5
- const serviceLocator = require('../../../servicelocator/ios');
6
- const applesimutils = serviceLocator.appleSimUtils;
7
5
  const { eventEmitter } = commonDeps;
8
6
 
7
+ const AppleSimUtils = require('../../../devices/common/drivers/ios/tools/AppleSimUtils');
8
+ const applesimutils = new AppleSimUtils();
9
+
9
10
  const SimulatorLauncher = require('../../allocation/drivers/ios/SimulatorLauncher');
10
11
  return {
11
12
  ...commonDeps,
@@ -1,4 +1,4 @@
1
- const { EmulatorExec } = require('../../devices/common/drivers/android/emulator/exec/EmulatorExec');
1
+ const { EmulatorExec } = require('../../common/drivers/android/emulator/exec/EmulatorExec');
2
2
 
3
3
  class EmulatorServiceLocator {
4
4
  constructor() {
@@ -0,0 +1,17 @@
1
+ class GenycloudServiceLocator {
2
+ constructor() {
3
+ this._exec = null;
4
+ }
5
+
6
+ // Note: important to keep lazy because of implicit validations that are sensitive (inside environment, in particular).
7
+ get exec() {
8
+ if (!this._exec) {
9
+ const Exec = require('../../allocation/drivers/android/genycloud/exec/GenyCloudExec');
10
+ const environment = require('../../../utils/environment');
11
+ this._exec = new Exec(environment.getGmsaasPath());
12
+ }
13
+ return this._exec;
14
+ }
15
+ }
16
+
17
+ module.exports = new GenycloudServiceLocator();
@@ -0,0 +1,23 @@
1
+ const AndroidDevicePathBuilder = require('../../../artifacts/utils/AndroidDevicePathBuilder');
2
+ const AAPT = require('../../common/drivers/android/exec/AAPT');
3
+ const ADB = require('../../common/drivers/android/exec/ADB');
4
+ const ApkValidator = require('../../common/drivers/android/tools/ApkValidator');
5
+ const { TempFileTransfer } = require('../../common/drivers/android/tools/TempFileTransfer');
6
+
7
+ const AndroidServiceLocator = {
8
+ get emulator() {
9
+ return require('./emulatorServiceLocator');
10
+ },
11
+
12
+ get genycloud() {
13
+ return require('./genycloudServiceLocator');
14
+ },
15
+ };
16
+
17
+ AndroidServiceLocator.adb = new ADB();
18
+ AndroidServiceLocator.aapt = new AAPT();
19
+ AndroidServiceLocator.apkValidator = new ApkValidator(AndroidServiceLocator.aapt);
20
+ AndroidServiceLocator.fileTransfer = new TempFileTransfer(AndroidServiceLocator.adb);
21
+ AndroidServiceLocator.devicePathBuilder = new AndroidDevicePathBuilder();
22
+
23
+ module.exports = AndroidServiceLocator;
@@ -1,4 +1,5 @@
1
1
  class EnvironmentValidatorBase {
2
+ /* istanbul ignore next */
2
3
  validate() {}
3
4
  }
4
5
 
@@ -1,8 +1,8 @@
1
1
  // @ts-nocheck
2
2
  const semver = require('semver');
3
3
 
4
- const DetoxRuntimeError = require('../../errors/DetoxRuntimeError');
5
- const environment = require('../../utils/environment');
4
+ const { DetoxRuntimeError } = require('../../../errors');
5
+ const environment = require('../../../utils/environment');
6
6
  const EnvironmentValidatorBase = require('../EnvironmentValidatorBase');
7
7
 
8
8
  const MIN_GMSAAS_VERSION = '1.6.0';
@@ -7,7 +7,7 @@ class Genycloud extends EnvValidatorFactory {
7
7
  const serviceLocator = require('../../servicelocator/android');
8
8
  const exec = serviceLocator.genycloud.exec;
9
9
 
10
- const GenyAuthService = require('../../devices/common/drivers/android/genycloud/services/GenyAuthService');
10
+ const GenyAuthService = require('../../allocation/drivers/android/genycloud/services/GenyAuthService');
11
11
  const authService = new GenyAuthService(exec);
12
12
 
13
13
  const GenycloudEnvValidator = require('../android/GenycloudEnvValidator');
@@ -1,7 +1,7 @@
1
1
  const fs = require('fs');
2
2
 
3
- const DetoxRuntimeError = require('../../errors/DetoxRuntimeError');
4
- const environment = require('../../utils/environment');
3
+ const DetoxRuntimeError = require('../../../errors/DetoxRuntimeError');
4
+ const environment = require('../../../utils/environment');
5
5
  const EnvironmentValidatorBase = require('../EnvironmentValidatorBase');
6
6
 
7
7
  class IosSimulatorEnvValidator extends EnvironmentValidatorBase {
@@ -2,9 +2,9 @@
2
2
  const artifactsManagerFactories = require('./artifacts/factories');
3
3
  const deviceAllocationFactories = require('./devices/allocation/factories');
4
4
  const runtimeDeviceFactories = require('./devices/runtime/factories');
5
+ const envValidationFactories = require('./devices/validation/factories');
5
6
  const matchersFactories = require('./matchers/factories');
6
7
  const resolveModuleFromPath = require('./utils/resolveModuleFromPath');
7
- const envValidationFactories = require('./validation/factories');
8
8
 
9
9
  function validateConfig(deviceConfig) {
10
10
  const classes = _getFactoryClasses(deviceConfig);
@@ -36,15 +36,6 @@ function createFactories(deviceConfig) {
36
36
  return _getExternalModuleFactories(deviceConfig);
37
37
  }
38
38
 
39
- function createGlobalLifecycleHandler(deviceConfig) {
40
- if (deviceConfig.type === 'android.genycloud') {
41
- const FactoryClass = require('./devices/lifecycle/factories/GenyGlobalLifecycleHandlerFactory');
42
- const factory = new FactoryClass();
43
- return factory.createHandler();
44
- }
45
- return null;
46
- }
47
-
48
39
  function _getFactoryClasses(deviceConfig) {
49
40
  let envValidatorFactoryClass;
50
41
  let artifactsManagerFactoryClass;
@@ -115,5 +106,4 @@ function _getExternalModuleFactories(deviceConfig) {
115
106
  module.exports = {
116
107
  validateConfig,
117
108
  createFactories,
118
- createGlobalLifecycleHandler,
119
109
  };
@@ -1,7 +1,7 @@
1
1
  const { IPC } = require('node-ipc');
2
2
 
3
3
  const { DetoxInternalError } = require('../errors');
4
- const { serializeObjectWithError } = require('../utils/errorUtils');
4
+ const { serializeObjectWithError, deserializeObjectWithError } = require('../utils/errorUtils');
5
5
 
6
6
  class IPCClient {
7
7
  constructor({ id, logger, sessionState }) {
@@ -60,6 +60,22 @@ class IPCClient {
60
60
  this._sessionState.patch(sessionState);
61
61
  }
62
62
 
63
+ async allocateDevice() {
64
+ const { deviceCookie, error } = deserializeObjectWithError(await this._emit('allocateDevice', {}));
65
+ if (error) {
66
+ throw error;
67
+ }
68
+
69
+ return deviceCookie;
70
+ }
71
+
72
+ async deallocateDevice(deviceCookie) {
73
+ const { error } = deserializeObjectWithError(await this._emit('deallocateDevice', { deviceCookie }));
74
+ if (error) {
75
+ throw error;
76
+ }
77
+ }
78
+
63
79
  /**
64
80
  * @param {DetoxInternals.DetoxTestFileReport[]} testResults
65
81
  */
@@ -70,6 +86,11 @@ class IPCClient {
70
86
  this._sessionState.patch(sessionState);
71
87
  }
72
88
 
89
+ async conductEarlyTeardown() {
90
+ const sessionState = await this._emit('conductEarlyTeardown', {});
91
+ this._sessionState.patch(sessionState);
92
+ }
93
+
73
94
  async _connectToServer() {
74
95
  const serverId = this.serverId;
75
96
 
@@ -8,11 +8,15 @@ class IPCServer {
8
8
  * @param {object} options
9
9
  * @param {import('./SessionState')} options.sessionState
10
10
  * @param {Detox.Logger} options.logger
11
+ * @param {object} options.callbacks
12
+ * @param {() => Promise<any>} options.callbacks.onAllocateDevice
13
+ * @param {(cookie: any) => Promise<void>} options.callbacks.onDeallocateDevice
11
14
  */
12
- constructor({ sessionState, logger }) {
15
+ constructor({ sessionState, logger, callbacks }) {
13
16
  this._sessionState = sessionState;
14
17
  this._logger = logger.child({ cat: 'ipc,ipc-server' });
15
18
  this._ipc = null;
19
+ this._callbacks = callbacks;
16
20
  this._workers = new Set();
17
21
  this._contexts = new Set();
18
22
  }
@@ -38,9 +42,12 @@ class IPCServer {
38
42
  await new Promise((resolve) => {
39
43
  // TODO: handle reject
40
44
  this._ipc.serve(() => resolve());
45
+ this._ipc.server.on('conductEarlyTeardown', this.onConductEarlyTeardown.bind(this));
41
46
  this._ipc.server.on('registerContext', this.onRegisterContext.bind(this));
42
47
  this._ipc.server.on('registerWorker', this.onRegisterWorker.bind(this));
43
48
  this._ipc.server.on('reportTestResults', this.onReportTestResults.bind(this));
49
+ this._ipc.server.on('allocateDevice', this.onAllocateDevice.bind(this));
50
+ this._ipc.server.on('deallocateDevice', this.onDeallocateDevice.bind(this));
44
51
  this._ipc.server.start();
45
52
  });
46
53
  }
@@ -83,6 +90,38 @@ class IPCServer {
83
90
  }
84
91
  }
85
92
 
93
+ onConductEarlyTeardown(_data = null, socket = null) {
94
+ // Note that we don't save `unsafe_earlyTeardown` in the primary session state
95
+ // because it's transient and needed only to make the workers quit early.
96
+ const newState = { unsafe_earlyTeardown: true };
97
+
98
+ if (socket) {
99
+ this._ipc.server.emit(socket, 'conductEarlyTeardownDone', newState);
100
+ }
101
+
102
+ this._ipc.server.broadcast('sessionStateUpdate', newState);
103
+ }
104
+
105
+ async onAllocateDevice(_payload, socket) {
106
+ let deviceCookie;
107
+
108
+ try {
109
+ deviceCookie = await this._callbacks.onAllocateDevice();
110
+ this._ipc.server.emit(socket, 'allocateDeviceDone', { deviceCookie });
111
+ } catch (error) {
112
+ this._ipc.server.emit(socket, 'allocateDeviceDone', serializeObjectWithError({ error }));
113
+ }
114
+ }
115
+
116
+ async onDeallocateDevice({ deviceCookie }, socket) {
117
+ try {
118
+ await this._callbacks.onDeallocateDevice(deviceCookie);
119
+ this._ipc.server.emit(socket, 'deallocateDeviceDone', {});
120
+ } catch (error) {
121
+ this._ipc.server.emit(socket, 'deallocateDeviceDone', serializeObjectWithError({ error }));
122
+ }
123
+ }
124
+
86
125
  onReportTestResults({ testResults }, socket = null) {
87
126
  const merged = uniqBy([
88
127
  ...testResults.map(r => serializeObjectWithError(r, 'testExecError')),
@@ -20,6 +20,7 @@ class SessionState {
20
20
  this.detoxIPCServer = detoxIPCServer;
21
21
  this.testResults = testResults;
22
22
  this.testSessionIndex = testSessionIndex;
23
+ this.unsafe_earlyTeardown = undefined;
23
24
  this.workersCount = workersCount;
24
25
  }
25
26
 
@@ -249,7 +249,7 @@ class DetoxLogger {
249
249
  _complete(level, maybeContext, maybeMessage, maybeAction) {
250
250
  const action = typeof maybeContext !== 'string' ? maybeAction : maybeMessage;
251
251
  const args = maybeAction === action ? [maybeContext, maybeMessage] : [maybeContext];
252
- const { context, msg } = this._parseArgs(null, args);
252
+ const { context, msg } = this._parseArgs({ ph: 'B' }, args);
253
253
  const end = (ctx) => this[level].end({
254
254
  id: context.id,
255
255
  cat: context.cat,
@@ -257,7 +257,7 @@ class DetoxLogger {
257
257
  });
258
258
 
259
259
  let result;
260
- this._beginInternal(level, { ...context, ph: 'B' }, msg);
260
+ this._beginInternal(level, context, msg);
261
261
  try {
262
262
  result = typeof action === 'function'
263
263
  ? action()
@@ -101,6 +101,8 @@ class DetoxContext {
101
101
  });
102
102
  /** @abstract */
103
103
  [symbols.reportTestResults](_testResults) {}
104
+ /** @abstract */
105
+ [symbols.conductEarlyTeardown]() {}
104
106
  /**
105
107
  * @abstract
106
108
  * @param {Partial<DetoxInternals.DetoxInitOptions>} _opts
@@ -149,6 +151,12 @@ class DetoxContext {
149
151
  await this[$worker].init();
150
152
  }
151
153
 
154
+ /** @abstract */
155
+ async [symbols.allocateDevice]() {}
156
+
157
+ /** @abstract */
158
+ async [symbols.deallocateDevice]() {}
159
+
152
160
  async [symbols.uninstallWorker]() {
153
161
  try {
154
162
  if (this[$worker]) {
@@ -24,6 +24,7 @@ class DetoxInternalsFacade {
24
24
  this.resolveConfig = context[symbols.resolveConfig];
25
25
  this.session = context[symbols.session];
26
26
  this.tracing = context[symbols.tracing];
27
+ this.unsafe_conductEarlyTeardown = context[symbols.conductEarlyTeardown];
27
28
  this.worker = funpermaproxy(() => context[symbols.worker]);
28
29
  }
29
30
  }