detox 20.11.4 → 20.12.0-smoke.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (110) hide show
  1. package/Detox-android/com/wix/detox/{20.11.4/detox-20.11.4-javadoc.jar → 20.12.0-smoke.0/detox-20.12.0-smoke.0-javadoc.jar} +0 -0
  2. package/Detox-android/com/wix/detox/20.12.0-smoke.0/detox-20.12.0-smoke.0-javadoc.jar.md5 +1 -0
  3. package/Detox-android/com/wix/detox/20.12.0-smoke.0/detox-20.12.0-smoke.0-javadoc.jar.sha1 +1 -0
  4. package/Detox-android/com/wix/detox/20.12.0-smoke.0/detox-20.12.0-smoke.0-javadoc.jar.sha256 +1 -0
  5. package/Detox-android/com/wix/detox/20.12.0-smoke.0/detox-20.12.0-smoke.0-javadoc.jar.sha512 +1 -0
  6. package/Detox-android/com/wix/detox/{20.11.4/detox-20.11.4-sources.jar → 20.12.0-smoke.0/detox-20.12.0-smoke.0-sources.jar} +0 -0
  7. package/Detox-android/com/wix/detox/20.12.0-smoke.0/detox-20.12.0-smoke.0-sources.jar.md5 +1 -0
  8. package/Detox-android/com/wix/detox/20.12.0-smoke.0/detox-20.12.0-smoke.0-sources.jar.sha1 +1 -0
  9. package/Detox-android/com/wix/detox/20.12.0-smoke.0/detox-20.12.0-smoke.0-sources.jar.sha256 +1 -0
  10. package/Detox-android/com/wix/detox/20.12.0-smoke.0/detox-20.12.0-smoke.0-sources.jar.sha512 +1 -0
  11. package/Detox-android/com/wix/detox/{20.11.4/detox-20.11.4.pom → 20.12.0-smoke.0/detox-20.12.0-smoke.0.pom} +1 -1
  12. package/Detox-android/com/wix/detox/20.12.0-smoke.0/detox-20.12.0-smoke.0.pom.md5 +1 -0
  13. package/Detox-android/com/wix/detox/20.12.0-smoke.0/detox-20.12.0-smoke.0.pom.sha1 +1 -0
  14. package/Detox-android/com/wix/detox/20.12.0-smoke.0/detox-20.12.0-smoke.0.pom.sha256 +1 -0
  15. package/Detox-android/com/wix/detox/20.12.0-smoke.0/detox-20.12.0-smoke.0.pom.sha512 +1 -0
  16. package/Detox-android/com/wix/detox/maven-metadata.xml +4 -4
  17. package/Detox-android/com/wix/detox/maven-metadata.xml.md5 +1 -1
  18. package/Detox-android/com/wix/detox/maven-metadata.xml.sha1 +1 -1
  19. package/Detox-android/com/wix/detox/maven-metadata.xml.sha256 +1 -1
  20. package/Detox-android/com/wix/detox/maven-metadata.xml.sha512 +1 -1
  21. package/Detox-ios-src.tbz +0 -0
  22. package/Detox-ios.tbz +0 -0
  23. package/local-cli/reset-lock-file.js +5 -9
  24. package/package.json +6 -6
  25. package/src/DetoxWorker.js +5 -9
  26. package/src/artifacts/providers/index.js +3 -3
  27. package/src/artifacts/screenshot/SimulatorScreenshotPlugin.js +0 -17
  28. package/src/devices/allocation/DeviceAllocator.js +50 -15
  29. package/src/devices/allocation/DeviceList.js +44 -0
  30. package/src/devices/allocation/DeviceRegistry.js +186 -0
  31. package/src/devices/allocation/drivers/AllocationDriverBase.js +10 -4
  32. package/src/devices/{common/drivers/android/tools → allocation/drivers/android}/FreeDeviceFinder.js +11 -10
  33. package/src/devices/allocation/drivers/android/attached/AttachedAndroidAllocDriver.js +7 -6
  34. package/src/devices/allocation/drivers/android/emulator/EmulatorAllocDriver.js +108 -26
  35. package/src/devices/allocation/drivers/android/emulator/EmulatorLauncher.js +33 -43
  36. package/src/devices/allocation/drivers/android/emulator/FreeEmulatorFinder.js +1 -1
  37. package/src/devices/allocation/drivers/android/emulator/FreePortFinder.js +16 -0
  38. package/src/devices/allocation/drivers/android/emulator/launchEmulatorProcess.js +3 -3
  39. package/src/devices/allocation/drivers/android/genycloud/GenyAllocDriver.js +87 -27
  40. package/src/devices/allocation/drivers/android/genycloud/GenyInstanceLauncher.js +39 -28
  41. package/src/devices/allocation/drivers/android/genycloud/GenyRegistry.js +93 -0
  42. package/src/devices/allocation/drivers/android/genycloud/services/GenyInstanceLifecycleService.js +24 -0
  43. package/src/devices/{common → allocation}/drivers/android/genycloud/services/GenyRecipesService.js +1 -1
  44. package/src/devices/{common → allocation}/drivers/android/genycloud/services/dto/GenyInstance.js +6 -1
  45. package/src/devices/allocation/drivers/ios/SimulatorAllocDriver.js +70 -40
  46. package/src/devices/allocation/drivers/ios/SimulatorLauncher.js +11 -7
  47. package/src/devices/allocation/drivers/ios/SimulatorQuery.js +24 -0
  48. package/src/devices/allocation/factories/android.js +29 -35
  49. package/src/devices/allocation/factories/ios.js +7 -5
  50. package/src/devices/common/drivers/android/emulator/exec/EmulatorExec.js +17 -5
  51. package/src/devices/common/drivers/android/exec/ADB.js +1 -0
  52. package/src/devices/common/drivers/ios/tools/AppleSimUtils.js +1 -1
  53. package/src/devices/cookies/AndroidDeviceCookie.js +4 -0
  54. package/src/devices/cookies/GenycloudEmulatorCookie.js +3 -5
  55. package/src/devices/cookies/IosSimulatorCookie.js +4 -0
  56. package/src/devices/runtime/drivers/android/genycloud/GenyCloudDriver.js +2 -2
  57. package/src/devices/runtime/factories/android.js +1 -1
  58. package/src/devices/runtime/factories/ios.js +3 -2
  59. package/src/{servicelocator → devices/servicelocator}/android/emulatorServiceLocator.js +1 -1
  60. package/src/devices/servicelocator/android/genycloudServiceLocator.js +17 -0
  61. package/src/devices/servicelocator/android/index.js +23 -0
  62. package/src/{validation → devices/validation}/android/GenycloudEnvValidator.js +2 -2
  63. package/src/{validation → devices/validation}/factories/index.js +1 -1
  64. package/src/{validation → devices/validation}/ios/IosSimulatorEnvValidator.js +2 -2
  65. package/src/environmentFactory.js +1 -11
  66. package/src/ipc/IPCClient.js +17 -1
  67. package/src/ipc/IPCServer.js +25 -1
  68. package/src/realms/DetoxContext.js +6 -0
  69. package/src/realms/DetoxPrimaryContext.js +42 -42
  70. package/src/realms/DetoxSecondaryContext.js +19 -0
  71. package/src/realms/symbols.js +4 -0
  72. package/src/utils/PIDService.js +27 -0
  73. package/src/utils/environment.js +8 -15
  74. package/src/utils/errorUtils.js +2 -2
  75. package/Detox-android/com/wix/detox/20.11.4/detox-20.11.4-javadoc.jar.md5 +0 -1
  76. package/Detox-android/com/wix/detox/20.11.4/detox-20.11.4-javadoc.jar.sha1 +0 -1
  77. package/Detox-android/com/wix/detox/20.11.4/detox-20.11.4-javadoc.jar.sha256 +0 -1
  78. package/Detox-android/com/wix/detox/20.11.4/detox-20.11.4-javadoc.jar.sha512 +0 -1
  79. package/Detox-android/com/wix/detox/20.11.4/detox-20.11.4-sources.jar.md5 +0 -1
  80. package/Detox-android/com/wix/detox/20.11.4/detox-20.11.4-sources.jar.sha1 +0 -1
  81. package/Detox-android/com/wix/detox/20.11.4/detox-20.11.4-sources.jar.sha256 +0 -1
  82. package/Detox-android/com/wix/detox/20.11.4/detox-20.11.4-sources.jar.sha512 +0 -1
  83. package/Detox-android/com/wix/detox/20.11.4/detox-20.11.4.pom.md5 +0 -1
  84. package/Detox-android/com/wix/detox/20.11.4/detox-20.11.4.pom.sha1 +0 -1
  85. package/Detox-android/com/wix/detox/20.11.4/detox-20.11.4.pom.sha256 +0 -1
  86. package/Detox-android/com/wix/detox/20.11.4/detox-20.11.4.pom.sha512 +0 -1
  87. package/src/devices/DeviceRegistry.js +0 -176
  88. package/src/devices/allocation/drivers/android/attached/AttachedAndroidLauncher.js +0 -13
  89. package/src/devices/allocation/drivers/android/emulator/EmulatorAllocationHelper.js +0 -72
  90. package/src/devices/allocation/drivers/android/genycloud/GenyDeviceRegistryFactory.js +0 -16
  91. package/src/devices/allocation/drivers/android/genycloud/GenyInstanceAllocationHelper.js +0 -65
  92. package/src/devices/common/drivers/DeviceAllocationHelper.js +0 -20
  93. package/src/devices/common/drivers/DeviceLauncher.js +0 -19
  94. package/src/devices/common/drivers/android/genycloud/services/GenyInstanceLifecycleService.js +0 -25
  95. package/src/devices/common/drivers/android/genycloud/services/GenyInstanceLookupService.js +0 -38
  96. package/src/devices/common/drivers/android/genycloud/services/GenyInstanceNaming.js +0 -14
  97. package/src/devices/lifecycle/GenyGlobalLifecycleHandler.js +0 -71
  98. package/src/devices/lifecycle/factories/GenyGlobalLifecycleHandlerFactory.js +0 -18
  99. package/src/servicelocator/android/genycloudServiceLocator.js +0 -21
  100. package/src/servicelocator/android/index.js +0 -25
  101. package/src/servicelocator/ios.js +0 -7
  102. /package/Detox-android/com/wix/detox/{20.11.4/detox-20.11.4.aar → 20.12.0-smoke.0/detox-20.12.0-smoke.0.aar} +0 -0
  103. /package/Detox-android/com/wix/detox/{20.11.4/detox-20.11.4.aar.md5 → 20.12.0-smoke.0/detox-20.12.0-smoke.0.aar.md5} +0 -0
  104. /package/Detox-android/com/wix/detox/{20.11.4/detox-20.11.4.aar.sha1 → 20.12.0-smoke.0/detox-20.12.0-smoke.0.aar.sha1} +0 -0
  105. /package/Detox-android/com/wix/detox/{20.11.4/detox-20.11.4.aar.sha256 → 20.12.0-smoke.0/detox-20.12.0-smoke.0.aar.sha256} +0 -0
  106. /package/Detox-android/com/wix/detox/{20.11.4/detox-20.11.4.aar.sha512 → 20.12.0-smoke.0/detox-20.12.0-smoke.0.aar.sha512} +0 -0
  107. /package/src/devices/{common → allocation}/drivers/android/genycloud/exec/GenyCloudExec.js +0 -0
  108. /package/src/devices/{common → allocation}/drivers/android/genycloud/services/GenyAuthService.js +0 -0
  109. /package/src/devices/{common → allocation}/drivers/android/genycloud/services/dto/GenyRecipe.js +0 -0
  110. /package/src/{validation → devices/validation}/EnvironmentValidatorBase.js +0 -0
@@ -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,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
  */
@@ -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
  }
@@ -41,6 +45,8 @@ class IPCServer {
41
45
  this._ipc.server.on('registerContext', this.onRegisterContext.bind(this));
42
46
  this._ipc.server.on('registerWorker', this.onRegisterWorker.bind(this));
43
47
  this._ipc.server.on('reportTestResults', this.onReportTestResults.bind(this));
48
+ this._ipc.server.on('allocateDevice', this.onAllocateDevice.bind(this));
49
+ this._ipc.server.on('deallocateDevice', this.onDeallocateDevice.bind(this));
44
50
  this._ipc.server.start();
45
51
  });
46
52
  }
@@ -83,6 +89,24 @@ class IPCServer {
83
89
  }
84
90
  }
85
91
 
92
+ async onAllocateDevice(_payload, socket) {
93
+ try {
94
+ const deviceCookie = await this._callbacks.onAllocateDevice();
95
+ this._ipc.server.emit(socket, 'allocateDeviceDone', { deviceCookie });
96
+ } catch (error) {
97
+ this._ipc.server.emit(socket, 'allocateDeviceDone', serializeObjectWithError({ error }));
98
+ }
99
+ }
100
+
101
+ async onDeallocateDevice({ deviceCookie }, socket) {
102
+ try {
103
+ await this._callbacks.onDeallocateDevice(deviceCookie);
104
+ this._ipc.server.emit(socket, 'deallocateDeviceDone', {});
105
+ } catch (error) {
106
+ this._ipc.server.emit(socket, 'deallocateDeviceDone', serializeObjectWithError({ error }));
107
+ }
108
+ }
109
+
86
110
  onReportTestResults({ testResults }, socket = null) {
87
111
  const merged = uniqBy([
88
112
  ...testResults.map(r => serializeObjectWithError(r, 'testExecError')),
@@ -149,6 +149,12 @@ class DetoxContext {
149
149
  await this[$worker].init();
150
150
  }
151
151
 
152
+ /** @abstract */
153
+ async [symbols.allocateDevice]() {}
154
+
155
+ /** @abstract */
156
+ async [symbols.deallocateDevice]() {}
157
+
152
158
  async [symbols.uninstallWorker]() {
153
159
  try {
154
160
  if (this[$worker]) {
@@ -16,15 +16,14 @@ const symbols = require('./symbols');
16
16
  const { $logFinalizer, $restoreSessionState, $sessionState, $worker } = DetoxContext.protected;
17
17
 
18
18
  //#region Private symbols
19
- const _globalLifecycleHandler = Symbol('globalLifecycleHandler');
20
19
  const _ipcServer = Symbol('ipcServer');
21
- const _resetLockFile = Symbol('resetLockFile');
22
20
  const _wss = Symbol('wss');
23
21
  const _dirty = Symbol('dirty');
24
22
  const _emergencyTeardown = Symbol('emergencyTeardown');
25
23
  const _lifecycleLogger = Symbol('lifecycleLogger');
26
24
  const _sessionFile = Symbol('sessionFile');
27
25
  const _logFinalError = Symbol('logFinalError');
26
+ const _deviceAllocator = Symbol('deviceAllocator');
28
27
  //#endregion
29
28
 
30
29
  class DetoxPrimaryContext extends DetoxContext {
@@ -33,7 +32,8 @@ class DetoxPrimaryContext extends DetoxContext {
33
32
 
34
33
  this[_dirty] = false;
35
34
  this[_wss] = null;
36
- this[_globalLifecycleHandler] = null;
35
+ this[_deviceAllocator] = null;
36
+
37
37
  /** Path to file where the initial session object is serialized */
38
38
  this[_sessionFile] = '';
39
39
  /**
@@ -79,7 +79,6 @@ class DetoxPrimaryContext extends DetoxContext {
79
79
  const detoxConfig = await this[symbols.resolveConfig](opts);
80
80
 
81
81
  const {
82
- behavior: behaviorConfig,
83
82
  device: deviceConfig,
84
83
  logger: loggerConfig,
85
84
  session: sessionConfig
@@ -96,20 +95,23 @@ class DetoxPrimaryContext extends DetoxContext {
96
95
  this[_ipcServer] = new IPCServer({
97
96
  sessionState: this[$sessionState],
98
97
  logger: this[symbols.logger],
98
+ callbacks: {
99
+ onAllocateDevice: this[symbols.allocateDevice].bind(this),
100
+ onDeallocateDevice: this[symbols.deallocateDevice].bind(this),
101
+ },
99
102
  });
100
103
 
101
104
  await this[_ipcServer].init();
102
105
 
103
106
  const environmentFactory = require('../environmentFactory');
104
- this[_globalLifecycleHandler] = await environmentFactory.createGlobalLifecycleHandler(deviceConfig);
105
107
 
106
- if (this[_globalLifecycleHandler]) {
107
- await this[_globalLifecycleHandler].globalInit();
108
- }
108
+ const { deviceAllocatorFactory } = environmentFactory.createFactories(deviceConfig);
109
+ this[_deviceAllocator] = deviceAllocatorFactory.createDeviceAllocator({
110
+ detoxConfig,
111
+ detoxSession: this[$sessionState],
112
+ });
109
113
 
110
- if (!behaviorConfig.init.keepLockFile) {
111
- await this[_resetLockFile]();
112
- }
114
+ await this[_deviceAllocator].init();
113
115
 
114
116
  // TODO: Detox-server creation ought to be delegated to a generator/factory.
115
117
  const DetoxServer = require('../server/DetoxServer');
@@ -153,6 +155,29 @@ class DetoxPrimaryContext extends DetoxContext {
153
155
  await super[symbols.installWorker]({ ...opts, workerId });
154
156
  }
155
157
 
158
+ /** @override */
159
+ async [symbols.allocateDevice]() {
160
+ const { device } = this[$sessionState].detoxConfig;
161
+ const deviceCookie = await this[_deviceAllocator].allocate(device);
162
+
163
+ try {
164
+ return await this[_deviceAllocator].postAllocate(deviceCookie);
165
+ } catch (e) {
166
+ try {
167
+ await this[_deviceAllocator].free(deviceCookie, { shutdown: true });
168
+ } catch (e2) {
169
+ this[symbols.logger].error({ cat: 'device', err: e2 }, `Failed to free ${deviceCookie} after a failed allocation`);
170
+ }
171
+
172
+ throw e;
173
+ }
174
+ }
175
+
176
+ /** @override */
177
+ async [symbols.deallocateDevice](cookie) {
178
+ await this[_deviceAllocator].free(cookie);
179
+ }
180
+
156
181
  /** @override */
157
182
  async [symbols.cleanup]() {
158
183
  try {
@@ -160,9 +185,9 @@ class DetoxPrimaryContext extends DetoxContext {
160
185
  await this[symbols.uninstallWorker]();
161
186
  }
162
187
  } finally {
163
- if (this[_globalLifecycleHandler]) {
164
- await this[_globalLifecycleHandler].globalCleanup();
165
- this[_globalLifecycleHandler] = null;
188
+ if (this[_deviceAllocator]) {
189
+ await this[_deviceAllocator].cleanup();
190
+ this[_deviceAllocator] = null;
166
191
  }
167
192
 
168
193
  if (this[_wss]) {
@@ -196,9 +221,9 @@ class DetoxPrimaryContext extends DetoxContext {
196
221
  return;
197
222
  }
198
223
 
199
- if (this[_globalLifecycleHandler]) {
200
- this[_globalLifecycleHandler].emergencyCleanup();
201
- this[_globalLifecycleHandler] = null;
224
+ if (this[_deviceAllocator]) {
225
+ this[_deviceAllocator].emergencyCleanup();
226
+ this[_deviceAllocator] = null;
202
227
  }
203
228
 
204
229
  if (this[_wss]) {
@@ -241,31 +266,6 @@ class DetoxPrimaryContext extends DetoxContext {
241
266
  });
242
267
  }
243
268
  //#endregion
244
-
245
- //#region Private members
246
- async[_resetLockFile]() {
247
- const DeviceRegistry = require('../devices/DeviceRegistry');
248
-
249
- const deviceType = this[symbols.config].device.type;
250
-
251
- switch (deviceType) {
252
- case 'ios.none':
253
- case 'ios.simulator':
254
- await DeviceRegistry.forIOS().reset();
255
- break;
256
- case 'android.attached':
257
- case 'android.emulator':
258
- case 'android.genycloud':
259
- await DeviceRegistry.forAndroid().reset();
260
- break;
261
- }
262
-
263
- if (deviceType === 'android.genycloud') {
264
- const GenyDeviceRegistryFactory = require('../devices/allocation/drivers/android/genycloud/GenyDeviceRegistryFactory');
265
- await GenyDeviceRegistryFactory.forGlobalShutdown().reset();
266
- }
267
- }
268
- //#endregion
269
269
  }
270
270
 
271
271
  module.exports = DetoxPrimaryContext;
@@ -54,6 +54,25 @@ class DetoxSecondaryContext extends DetoxContext {
54
54
  }
55
55
  }
56
56
 
57
+ /** @override */
58
+ async [symbols.allocateDevice]() {
59
+ if (this[_ipcClient]) {
60
+ const deviceCookie = await this[_ipcClient].allocateDevice();
61
+ return deviceCookie;
62
+ } else {
63
+ throw new DetoxInternalError('Detected an attempt to allocate a device using a non-initialized context.');
64
+ }
65
+ }
66
+
67
+ /** @override */
68
+ async [symbols.deallocateDevice](deviceCookie) {
69
+ if (this[_ipcClient]) {
70
+ await this[_ipcClient].deallocateDevice(deviceCookie);
71
+ } else {
72
+ throw new DetoxInternalError('Detected an attempt to allocate a device using a non-initialized context.');
73
+ }
74
+ }
75
+
57
76
  /** @override */
58
77
  async [symbols.cleanup]() {
59
78
  try {
@@ -5,6 +5,8 @@
5
5
  * readonly getStatus: unique symbol;
6
6
  * readonly init: unique symbol;
7
7
  * readonly installWorker: unique symbol;
8
+ * readonly allocateDevice: unique symbol;
9
+ * readonly deallocateDevice: unique symbol;
8
10
  * readonly logger: unique symbol;
9
11
  * readonly onHookFailure: unique symbol;
10
12
  * readonly onRunDescribeFinish: unique symbol;
@@ -32,6 +34,8 @@ module.exports = {
32
34
 
33
35
  //#region IPC
34
36
  reportTestResults: Symbol('reportTestResults'),
37
+ allocateDevice: Symbol('allocateDevice'),
38
+ deallocateDevice: Symbol('deallocateDevice'),
35
39
  //#endregion
36
40
 
37
41
  //#region Main
@@ -0,0 +1,27 @@
1
+ const { pid } = require('process');
2
+
3
+ class PIDService {
4
+ getPid() {
5
+ return pid;
6
+ }
7
+
8
+ /**
9
+ * Checks if the other process id is running in the current operating system
10
+ * @param {number} otherPID
11
+ * @returns {boolean}
12
+ */
13
+ isAlive(otherPID) {
14
+ try {
15
+ process.kill(otherPID, 0);
16
+ return true;
17
+ } catch (ex) {
18
+ if (ex.code === 'ESRCH') {
19
+ return false;
20
+ }
21
+ throw ex;
22
+ }
23
+ }
24
+
25
+ }
26
+
27
+ module.exports = PIDService;
@@ -19,9 +19,8 @@ function which(executable, path) {
19
19
  const DETOX_LIBRARY_ROOT_PATH = path.join(appdatapath.appDataPath(), 'Detox');
20
20
  const MISSING_SDK_ERROR = `$ANDROID_SDK_ROOT is not defined, set the path to the SDK installation directory into $ANDROID_SDK_ROOT,
21
21
  Go to https://developer.android.com/studio/command-line/variables.html for more details`;
22
- const DEVICE_LOCK_FILE_PATH_IOS = path.join(DETOX_LIBRARY_ROOT_PATH, 'device.registry.state.lock');
23
- const DEVICE_LOCK_FILE_PATH_ANDROID = path.join(DETOX_LIBRARY_ROOT_PATH, 'android-device.registry.state.lock');
24
- const GENYCLOUD_GLOBAL_CLEANUP_FILE_PATH = path.join(DETOX_LIBRARY_ROOT_PATH, 'genycloud-cleanup.lock');
22
+ const DETOX_LOCK_FILE_PATH = path.join(DETOX_LIBRARY_ROOT_PATH, 'global-context.json');
23
+ const DEVICE_REGISTRY_PATH = path.join(DETOX_LIBRARY_ROOT_PATH, 'device.registry.json');
25
24
  const LAST_FAILED_TESTS_PATH = path.join(DETOX_LIBRARY_ROOT_PATH, 'last-failed.txt');
26
25
 
27
26
  function getAndroidSDKPath() {
@@ -195,17 +194,12 @@ function getDetoxLibraryRootPath() {
195
194
  return DETOX_LIBRARY_ROOT_PATH;
196
195
  }
197
196
 
198
- function getDeviceLockFilePathIOS() {
199
- return DEVICE_LOCK_FILE_PATH_IOS;
197
+ function getDetoxLockFilePath() {
198
+ return DETOX_LOCK_FILE_PATH;
200
199
  }
201
200
 
202
- // TODO This can probably be merged with IOS' by now
203
- function getDeviceLockFilePathAndroid() {
204
- return DEVICE_LOCK_FILE_PATH_ANDROID;
205
- }
206
-
207
- function getGenyCloudGlobalCleanupFilePath() {
208
- return GENYCLOUD_GLOBAL_CLEANUP_FILE_PATH;
201
+ function getDeviceRegistryPath() {
202
+ return DEVICE_REGISTRY_PATH;
209
203
  }
210
204
 
211
205
  function getLastFailedTestsPath() {
@@ -229,9 +223,8 @@ module.exports = {
229
223
  getAndroidSDKPath,
230
224
  getAndroidEmulatorPath,
231
225
  getDetoxLibraryRootPath,
232
- getDeviceLockFilePathIOS,
233
- getDeviceLockFilePathAndroid,
234
- getGenyCloudGlobalCleanupFilePath,
226
+ getDetoxLockFilePath,
227
+ getDeviceRegistryPath,
235
228
  getLastFailedTestsPath,
236
229
  getHomeDir,
237
230
  };
@@ -40,7 +40,7 @@ function asError(error) {
40
40
  return isError(error) ? error : new Error(error);
41
41
  }
42
42
 
43
- function serializeObjectWithError(obj, errorKey) {
43
+ function serializeObjectWithError(obj, errorKey = 'error') {
44
44
  if (obj[errorKey]) {
45
45
  return { ...obj, [errorKey]: serializeError(obj[errorKey]) };
46
46
  }
@@ -48,7 +48,7 @@ function serializeObjectWithError(obj, errorKey) {
48
48
  return obj;
49
49
  }
50
50
 
51
- function deserializeObjectWithError(obj, errorKey) {
51
+ function deserializeObjectWithError(obj, errorKey = 'error') {
52
52
  if (typeof obj[errorKey] === 'object' && !(obj[errorKey] instanceof Error)) {
53
53
  return { ...obj, [errorKey]: deserializeError(obj[errorKey]) };
54
54
  }
@@ -1 +0,0 @@
1
- 3ab1e77a88959796445b964956a4b6cb
@@ -1 +0,0 @@
1
- a7282bbd2481685e2692a4cf51676464a0f7446f
@@ -1 +0,0 @@
1
- deeac0e7aab27bd41f07df5f72448abe52e6cc4d6ac4355c9a0e3d3be38ce052
@@ -1 +0,0 @@
1
- a039381f1dc1580412a3ab5b34065d74d9cd56c26578201fedcfa8d6325993a38556ac14a8d3ad47f231cc53947fa212f603933fe871c453322e895164768911
@@ -1 +0,0 @@
1
- 5cf453e649a4658381b05b20ad88bde7
@@ -1 +0,0 @@
1
- 6741271763e5c32f00f1d1b6f3a66f8299c7388c
@@ -1 +0,0 @@
1
- dc0c3debc80ef7502250987bfef873bf8ffe3208cb867d9c1f93e5ffe68e3e09
@@ -1 +0,0 @@
1
- f25095114f302dac4e4c1912929d522f333648f6dcc8889c2ccf09b8e5d4b59ceb6cc4d01445bbd789bc3fb36c8f402af1bd4bf1863af82a8c6108021ff58fa0
@@ -1 +0,0 @@
1
- f6329cce61c1d04aff24a0c72fb2710c
@@ -1 +0,0 @@
1
- 1fdb6d612186ed63fef79d13ee8204ef550f1934
@@ -1 +0,0 @@
1
- d850605b833689e3d3e53fb09c2210015fac17ba0e15fa4e6be3953aafd3056e
@@ -1 +0,0 @@
1
- 83d8ead4b94a64418ed9df32830f2628854f9fb7bde37740a3c24eaca90bd86e8563110eccea6d943089c4b7b6fb7e4e72c6533a668bdadf4f500f40eb6ee70e