detox 20.12.0-smoke.0 → 20.12.0
Sign up to get free protection for your applications and to get access to all the features.
- package/Detox-android/com/wix/detox/{20.12.0-smoke.0/detox-20.12.0-smoke.0-javadoc.jar → 20.12.0/detox-20.12.0-javadoc.jar} +0 -0
- package/Detox-android/com/wix/detox/20.12.0/detox-20.12.0-javadoc.jar.md5 +1 -0
- package/Detox-android/com/wix/detox/20.12.0/detox-20.12.0-javadoc.jar.sha1 +1 -0
- package/Detox-android/com/wix/detox/20.12.0/detox-20.12.0-javadoc.jar.sha256 +1 -0
- package/Detox-android/com/wix/detox/20.12.0/detox-20.12.0-javadoc.jar.sha512 +1 -0
- package/Detox-android/com/wix/detox/{20.12.0-smoke.0/detox-20.12.0-smoke.0-sources.jar → 20.12.0/detox-20.12.0-sources.jar} +0 -0
- package/Detox-android/com/wix/detox/20.12.0/detox-20.12.0-sources.jar.md5 +1 -0
- package/Detox-android/com/wix/detox/20.12.0/detox-20.12.0-sources.jar.sha1 +1 -0
- package/Detox-android/com/wix/detox/20.12.0/detox-20.12.0-sources.jar.sha256 +1 -0
- package/Detox-android/com/wix/detox/20.12.0/detox-20.12.0-sources.jar.sha512 +1 -0
- package/Detox-android/com/wix/detox/20.12.0/detox-20.12.0.aar +0 -0
- package/Detox-android/com/wix/detox/20.12.0/detox-20.12.0.aar.md5 +1 -0
- package/Detox-android/com/wix/detox/20.12.0/detox-20.12.0.aar.sha1 +1 -0
- package/Detox-android/com/wix/detox/20.12.0/detox-20.12.0.aar.sha256 +1 -0
- package/Detox-android/com/wix/detox/20.12.0/detox-20.12.0.aar.sha512 +1 -0
- package/Detox-android/com/wix/detox/{20.12.0-smoke.0/detox-20.12.0-smoke.0.pom → 20.12.0/detox-20.12.0.pom} +1 -1
- package/Detox-android/com/wix/detox/20.12.0/detox-20.12.0.pom.md5 +1 -0
- package/Detox-android/com/wix/detox/20.12.0/detox-20.12.0.pom.sha1 +1 -0
- package/Detox-android/com/wix/detox/20.12.0/detox-20.12.0.pom.sha256 +1 -0
- package/Detox-android/com/wix/detox/20.12.0/detox-20.12.0.pom.sha512 +1 -0
- package/Detox-android/com/wix/detox/maven-metadata.xml +4 -4
- package/Detox-android/com/wix/detox/maven-metadata.xml.md5 +1 -1
- package/Detox-android/com/wix/detox/maven-metadata.xml.sha1 +1 -1
- package/Detox-android/com/wix/detox/maven-metadata.xml.sha256 +1 -1
- package/Detox-android/com/wix/detox/maven-metadata.xml.sha512 +1 -1
- package/Detox-ios-src.tbz +0 -0
- package/Detox-ios.tbz +0 -0
- package/android/detox/build.gradle +1 -1
- package/android/detox/src/full/java/com/wix/detox/espresso/DetoxAssertion.java +44 -25
- package/android/detox/src/full/java/com/wix/detox/espresso/EspressoDetox.java +6 -7
- package/android/detox/src/full/java/com/wix/detox/espresso/action/GetAttributesAction.kt +4 -4
- package/android/detox/src/full/java/com/wix/detox/espresso/performer/MultipleViewsActionPerformer.kt +43 -0
- package/android/detox/src/full/java/com/wix/detox/espresso/performer/SingleViewActionPerformer.kt +19 -0
- package/android/detox/src/full/java/com/wix/detox/espresso/performer/ViewActionPerformer.kt +24 -0
- package/android/detox/src/full/java/com/wix/invoke/types/Invocation.java +5 -4
- package/android/detox/src/main/java/com/wix/detox/espresso/MultipleViewsAction.kt +4 -0
- package/android/detox/src/main/java/com/wix/detox/espresso/UiControllerSpy.kt +0 -1
- package/android/detox/src/main/java/com/wix/detox/espresso/ViewActionWithResult.kt +2 -1
- package/android/detox/src/testFull/java/com/wix/detox/espresso/action/GetAttributesActionTest.kt +6 -5
- package/android/detox/src/testFull/java/com/wix/detox/espresso/performer/ViewActionPerformerSpec.kt +37 -0
- package/index.d.ts +4 -3
- package/local-cli/reset-lock-file.js +9 -5
- package/package.json +6 -6
- package/src/DetoxWorker.js +9 -5
- package/src/android/core/NativeElement.js +26 -29
- package/src/android/espressoapi/DetoxAssertion.js +16 -14
- package/src/android/espressoapi/EspressoDetox.js +9 -2
- package/src/android/interactions/native.js +2 -3
- package/src/artifacts/providers/index.js +3 -3
- package/src/artifacts/screenshot/SimulatorScreenshotPlugin.js +17 -0
- package/src/devices/DeviceRegistry.js +176 -0
- package/src/devices/allocation/DeviceAllocator.js +15 -50
- package/src/devices/allocation/drivers/AllocationDriverBase.js +4 -10
- package/src/devices/allocation/drivers/android/attached/AttachedAndroidAllocDriver.js +6 -7
- package/src/devices/allocation/drivers/android/attached/AttachedAndroidLauncher.js +13 -0
- package/src/devices/allocation/drivers/android/emulator/EmulatorAllocDriver.js +26 -108
- package/src/devices/allocation/drivers/android/emulator/EmulatorAllocationHelper.js +72 -0
- package/src/devices/allocation/drivers/android/emulator/EmulatorLauncher.js +43 -33
- package/src/devices/allocation/drivers/android/emulator/FreeEmulatorFinder.js +1 -1
- package/src/devices/allocation/drivers/android/emulator/launchEmulatorProcess.js +3 -3
- package/src/devices/allocation/drivers/android/genycloud/GenyAllocDriver.js +27 -87
- package/src/devices/allocation/drivers/android/genycloud/GenyDeviceRegistryFactory.js +16 -0
- package/src/devices/allocation/drivers/android/genycloud/GenyInstanceAllocationHelper.js +65 -0
- package/src/devices/allocation/drivers/android/genycloud/GenyInstanceLauncher.js +28 -39
- package/src/devices/allocation/drivers/ios/SimulatorAllocDriver.js +40 -70
- package/src/devices/allocation/drivers/ios/SimulatorLauncher.js +7 -11
- package/src/devices/allocation/factories/android.js +35 -29
- package/src/devices/allocation/factories/ios.js +5 -7
- package/src/devices/common/drivers/DeviceAllocationHelper.js +20 -0
- package/src/devices/common/drivers/DeviceLauncher.js +19 -0
- package/src/devices/common/drivers/android/emulator/exec/EmulatorExec.js +5 -17
- package/src/devices/common/drivers/android/exec/ADB.js +0 -1
- package/src/devices/common/drivers/android/genycloud/services/GenyInstanceLifecycleService.js +25 -0
- package/src/devices/common/drivers/android/genycloud/services/GenyInstanceLookupService.js +38 -0
- package/src/devices/common/drivers/android/genycloud/services/GenyInstanceNaming.js +14 -0
- package/src/devices/{allocation → common}/drivers/android/genycloud/services/GenyRecipesService.js +1 -1
- package/src/devices/{allocation → common}/drivers/android/genycloud/services/dto/GenyInstance.js +1 -6
- package/src/devices/{allocation/drivers/android → common/drivers/android/tools}/FreeDeviceFinder.js +10 -11
- package/src/devices/common/drivers/ios/tools/AppleSimUtils.js +1 -1
- package/src/devices/cookies/AndroidDeviceCookie.js +0 -4
- package/src/devices/cookies/GenycloudEmulatorCookie.js +5 -3
- package/src/devices/cookies/IosSimulatorCookie.js +0 -4
- package/src/devices/lifecycle/GenyGlobalLifecycleHandler.js +71 -0
- package/src/devices/lifecycle/factories/GenyGlobalLifecycleHandlerFactory.js +18 -0
- package/src/devices/runtime/drivers/android/genycloud/GenyCloudDriver.js +2 -2
- package/src/devices/runtime/factories/android.js +1 -1
- package/src/devices/runtime/factories/ios.js +2 -3
- package/src/environmentFactory.js +11 -1
- package/src/ipc/IPCClient.js +1 -17
- package/src/ipc/IPCServer.js +1 -25
- package/src/realms/DetoxContext.js +0 -6
- package/src/realms/DetoxPrimaryContext.js +42 -42
- package/src/realms/DetoxSecondaryContext.js +0 -19
- package/src/realms/symbols.js +0 -4
- package/src/{devices/servicelocator → servicelocator}/android/emulatorServiceLocator.js +1 -1
- package/src/servicelocator/android/genycloudServiceLocator.js +21 -0
- package/src/servicelocator/android/index.js +25 -0
- package/src/servicelocator/ios.js +7 -0
- package/src/utils/environment.js +15 -8
- package/src/utils/errorUtils.js +2 -2
- package/src/{devices/validation → validation}/android/GenycloudEnvValidator.js +2 -2
- package/src/{devices/validation → validation}/factories/index.js +1 -1
- package/src/{devices/validation → validation}/ios/IosSimulatorEnvValidator.js +2 -2
- package/Detox-android/com/wix/detox/20.12.0-smoke.0/detox-20.12.0-smoke.0-javadoc.jar.md5 +0 -1
- package/Detox-android/com/wix/detox/20.12.0-smoke.0/detox-20.12.0-smoke.0-javadoc.jar.sha1 +0 -1
- package/Detox-android/com/wix/detox/20.12.0-smoke.0/detox-20.12.0-smoke.0-javadoc.jar.sha256 +0 -1
- package/Detox-android/com/wix/detox/20.12.0-smoke.0/detox-20.12.0-smoke.0-javadoc.jar.sha512 +0 -1
- package/Detox-android/com/wix/detox/20.12.0-smoke.0/detox-20.12.0-smoke.0-sources.jar.md5 +0 -1
- package/Detox-android/com/wix/detox/20.12.0-smoke.0/detox-20.12.0-smoke.0-sources.jar.sha1 +0 -1
- package/Detox-android/com/wix/detox/20.12.0-smoke.0/detox-20.12.0-smoke.0-sources.jar.sha256 +0 -1
- package/Detox-android/com/wix/detox/20.12.0-smoke.0/detox-20.12.0-smoke.0-sources.jar.sha512 +0 -1
- package/Detox-android/com/wix/detox/20.12.0-smoke.0/detox-20.12.0-smoke.0.aar +0 -0
- package/Detox-android/com/wix/detox/20.12.0-smoke.0/detox-20.12.0-smoke.0.aar.md5 +0 -1
- package/Detox-android/com/wix/detox/20.12.0-smoke.0/detox-20.12.0-smoke.0.aar.sha1 +0 -1
- package/Detox-android/com/wix/detox/20.12.0-smoke.0/detox-20.12.0-smoke.0.aar.sha256 +0 -1
- package/Detox-android/com/wix/detox/20.12.0-smoke.0/detox-20.12.0-smoke.0.aar.sha512 +0 -1
- package/Detox-android/com/wix/detox/20.12.0-smoke.0/detox-20.12.0-smoke.0.pom.md5 +0 -1
- package/Detox-android/com/wix/detox/20.12.0-smoke.0/detox-20.12.0-smoke.0.pom.sha1 +0 -1
- package/Detox-android/com/wix/detox/20.12.0-smoke.0/detox-20.12.0-smoke.0.pom.sha256 +0 -1
- package/Detox-android/com/wix/detox/20.12.0-smoke.0/detox-20.12.0-smoke.0.pom.sha512 +0 -1
- package/src/devices/allocation/DeviceList.js +0 -44
- package/src/devices/allocation/DeviceRegistry.js +0 -186
- package/src/devices/allocation/drivers/android/emulator/FreePortFinder.js +0 -16
- package/src/devices/allocation/drivers/android/genycloud/GenyRegistry.js +0 -93
- package/src/devices/allocation/drivers/android/genycloud/services/GenyInstanceLifecycleService.js +0 -24
- package/src/devices/allocation/drivers/ios/SimulatorQuery.js +0 -24
- package/src/devices/servicelocator/android/genycloudServiceLocator.js +0 -17
- package/src/devices/servicelocator/android/index.js +0 -23
- package/src/utils/PIDService.js +0 -27
- /package/src/devices/{allocation → common}/drivers/android/genycloud/exec/GenyCloudExec.js +0 -0
- /package/src/devices/{allocation → common}/drivers/android/genycloud/services/GenyAuthService.js +0 -0
- /package/src/devices/{allocation → common}/drivers/android/genycloud/services/dto/GenyRecipe.js +0 -0
- /package/src/{devices/validation → validation}/EnvironmentValidatorBase.js +0 -0
@@ -2,12 +2,11 @@
|
|
2
2
|
const DeviceAllocatorFactory = require('./base');
|
3
3
|
|
4
4
|
class AndroidEmulator extends DeviceAllocatorFactory {
|
5
|
-
_createDriver({
|
6
|
-
const serviceLocator = require('
|
5
|
+
_createDriver({ eventEmitter }) {
|
6
|
+
const serviceLocator = require('../../../servicelocator/android');
|
7
7
|
const adb = serviceLocator.adb;
|
8
8
|
const emulatorExec = serviceLocator.emulator.exec;
|
9
|
-
const
|
10
|
-
const deviceRegistry = new DeviceRegistry({ sessionId: detoxSession.id });
|
9
|
+
const deviceRegistry = serviceLocator.deviceRegistry;
|
11
10
|
|
12
11
|
const AVDsResolver = require('../drivers/android/emulator/AVDsResolver');
|
13
12
|
const avdsResolver = new AVDsResolver(emulatorExec);
|
@@ -21,67 +20,74 @@ class AndroidEmulator extends DeviceAllocatorFactory {
|
|
21
20
|
const FreeEmulatorFinder = require('../drivers/android/emulator/FreeEmulatorFinder');
|
22
21
|
const freeEmulatorFinder = new FreeEmulatorFinder(adb, deviceRegistry);
|
23
22
|
|
24
|
-
const FreePortFinder = require('../drivers/android/emulator/FreePortFinder');
|
25
|
-
const freePortFinder = new FreePortFinder();
|
26
|
-
|
27
23
|
const EmulatorLauncher = require('../drivers/android/emulator/EmulatorLauncher');
|
28
|
-
const emulatorLauncher = new EmulatorLauncher({ adb, emulatorExec });
|
24
|
+
const emulatorLauncher = new EmulatorLauncher({ adb, emulatorExec, eventEmitter });
|
25
|
+
|
26
|
+
const EmulatorAllocationHelper = require('../drivers/android/emulator/EmulatorAllocationHelper');
|
27
|
+
const allocationHelper = new EmulatorAllocationHelper(deviceRegistry, freeEmulatorFinder);
|
29
28
|
|
30
29
|
const EmulatorAllocDriver = require('../drivers/android/emulator/EmulatorAllocDriver');
|
31
30
|
return new EmulatorAllocDriver({
|
32
31
|
adb,
|
33
32
|
avdValidator,
|
34
|
-
detoxConfig,
|
35
|
-
deviceRegistry,
|
36
33
|
emulatorVersionResolver,
|
37
34
|
emulatorLauncher,
|
38
|
-
|
39
|
-
freePortFinder,
|
35
|
+
allocationHelper,
|
40
36
|
});
|
41
37
|
}
|
42
38
|
}
|
43
39
|
|
44
40
|
class AndroidAttached extends DeviceAllocatorFactory {
|
45
|
-
_createDriver({
|
46
|
-
const serviceLocator = require('
|
41
|
+
_createDriver({ eventEmitter }) {
|
42
|
+
const serviceLocator = require('../../../servicelocator/android');
|
47
43
|
const adb = serviceLocator.adb;
|
48
|
-
const
|
49
|
-
const deviceRegistry = new DeviceRegistry({ sessionId: detoxSession.id });
|
44
|
+
const deviceRegistry = serviceLocator.deviceRegistry;
|
50
45
|
|
51
|
-
const FreeDeviceFinder = require('
|
46
|
+
const FreeDeviceFinder = require('../../common/drivers/android/tools/FreeDeviceFinder');
|
52
47
|
const freeDeviceFinder = new FreeDeviceFinder(adb, deviceRegistry);
|
53
48
|
|
49
|
+
const AttachedAndroidLauncher = require('../drivers/android/attached/AttachedAndroidLauncher');
|
50
|
+
const attachedAndroidLauncher = new AttachedAndroidLauncher(eventEmitter);
|
51
|
+
|
54
52
|
const AttachedAndroidAllocDriver = require('../drivers/android/attached/AttachedAndroidAllocDriver');
|
55
|
-
return new AttachedAndroidAllocDriver({ adb, deviceRegistry, freeDeviceFinder });
|
53
|
+
return new AttachedAndroidAllocDriver({ adb, deviceRegistry, freeDeviceFinder, attachedAndroidLauncher });
|
56
54
|
}
|
57
55
|
}
|
58
56
|
|
59
57
|
class Genycloud extends DeviceAllocatorFactory {
|
60
|
-
_createDriver(
|
61
|
-
const serviceLocator = require('
|
58
|
+
_createDriver({ eventEmitter }) {
|
59
|
+
const serviceLocator = require('../../../servicelocator/android');
|
62
60
|
const adb = serviceLocator.adb;
|
63
61
|
const exec = serviceLocator.genycloud.exec;
|
62
|
+
const deviceRegistry = serviceLocator.genycloud.runtimeDeviceRegistry;
|
63
|
+
const deviceCleanupRegistry = serviceLocator.genycloud.cleanupDeviceRegistry;
|
64
64
|
|
65
|
-
const
|
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');
|
66
69
|
const recipeService = new RecipesService(exec);
|
67
70
|
|
68
|
-
const
|
69
|
-
const
|
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);
|
70
76
|
|
71
77
|
const RecipeQuerying = require('../drivers/android/genycloud/GenyRecipeQuerying');
|
72
78
|
const recipeQuerying = new RecipeQuerying(recipeService);
|
73
79
|
|
74
|
-
const
|
75
|
-
const
|
80
|
+
const InstanceAllocationHelper = require('../drivers/android/genycloud/GenyInstanceAllocationHelper');
|
81
|
+
const allocationHelper = new InstanceAllocationHelper({ deviceRegistry, instanceLookupService, instanceLifecycleService });
|
76
82
|
|
83
|
+
const InstanceLauncher = require('../drivers/android/genycloud/GenyInstanceLauncher');
|
77
84
|
const GenyAllocDriver = require('../drivers/android/genycloud/GenyAllocDriver');
|
78
|
-
|
85
|
+
const instanceLauncher = new InstanceLauncher({ instanceLifecycleService, instanceLookupService, deviceCleanupRegistry, eventEmitter });
|
79
86
|
return new GenyAllocDriver({
|
80
87
|
adb,
|
81
|
-
instanceLauncher,
|
82
|
-
instanceLifecycleService,
|
83
88
|
recipeQuerying,
|
84
|
-
|
89
|
+
allocationHelper,
|
90
|
+
instanceLauncher,
|
85
91
|
});
|
86
92
|
}
|
87
93
|
}
|
@@ -2,18 +2,16 @@
|
|
2
2
|
const DeviceAllocatorFactory = require('./base');
|
3
3
|
|
4
4
|
class IosSimulator extends DeviceAllocatorFactory {
|
5
|
-
_createDriver({
|
6
|
-
const
|
7
|
-
const applesimutils =
|
8
|
-
|
9
|
-
const DeviceRegistry = require('../../../devices/allocation/DeviceRegistry');
|
10
|
-
const deviceRegistry = new DeviceRegistry({ sessionId: detoxSession.id });
|
5
|
+
_createDriver({ eventEmitter }) {
|
6
|
+
const serviceLocator = require('../../../servicelocator/ios');
|
7
|
+
const applesimutils = serviceLocator.appleSimUtils;
|
8
|
+
const deviceRegistry = serviceLocator.deviceRegistry;
|
11
9
|
|
12
10
|
const SimulatorLauncher = require('../drivers/ios/SimulatorLauncher');
|
13
11
|
const simulatorLauncher = new SimulatorLauncher({ applesimutils, eventEmitter });
|
14
12
|
|
15
13
|
const SimulatorAllocDriver = require('../drivers/ios/SimulatorAllocDriver');
|
16
|
-
return new SimulatorAllocDriver({
|
14
|
+
return new SimulatorAllocDriver({ deviceRegistry, applesimutils, simulatorLauncher });
|
17
15
|
}
|
18
16
|
}
|
19
17
|
|
@@ -0,0 +1,20 @@
|
|
1
|
+
const ALLOCATE_DEVICE_LOG_EVT = 'ALLOCATE_DEVICE';
|
2
|
+
|
3
|
+
class DeviceAllocationHelper {
|
4
|
+
constructor(deviceRegistry, logger) {
|
5
|
+
this._deviceRegistry = deviceRegistry;
|
6
|
+
this._logger = logger;
|
7
|
+
}
|
8
|
+
|
9
|
+
_logAllocationAttempt(deviceQuery) {
|
10
|
+
this._logger.debug({ event: ALLOCATE_DEVICE_LOG_EVT }, `Trying to allocate a device based on "${deviceQuery}"`);
|
11
|
+
}
|
12
|
+
|
13
|
+
_logAllocationResult(deviceQuery, deviceHandle) {
|
14
|
+
this._logger.debug({ event: ALLOCATE_DEVICE_LOG_EVT }, `Settled on ${deviceHandle}`);
|
15
|
+
}
|
16
|
+
}
|
17
|
+
|
18
|
+
DeviceAllocationHelper.ALLOCATE_DEVICE_LOG_EVT = ALLOCATE_DEVICE_LOG_EVT;
|
19
|
+
|
20
|
+
module.exports = DeviceAllocationHelper;
|
@@ -0,0 +1,19 @@
|
|
1
|
+
class DeviceLauncher {
|
2
|
+
constructor(eventEmitter) {
|
3
|
+
this._eventEmitter = eventEmitter;
|
4
|
+
}
|
5
|
+
|
6
|
+
async _notifyPreShutdown(deviceId) {
|
7
|
+
return this._eventEmitter.emit('beforeShutdownDevice', { deviceId });
|
8
|
+
}
|
9
|
+
|
10
|
+
async _notifyShutdownCompleted(deviceId) {
|
11
|
+
return this._eventEmitter.emit('shutdownDevice', { deviceId });
|
12
|
+
}
|
13
|
+
|
14
|
+
async _notifyBootEvent(deviceId, type, coldBoot, headless) {
|
15
|
+
return this._eventEmitter.emit('bootDevice', { deviceId, type, coldBoot, headless });
|
16
|
+
}
|
17
|
+
}
|
18
|
+
|
19
|
+
module.exports = DeviceLauncher;
|
@@ -32,31 +32,19 @@ class QueryVersionCommand extends ExecCommand {
|
|
32
32
|
}
|
33
33
|
|
34
34
|
class LaunchCommand extends ExecCommand {
|
35
|
-
constructor(options) {
|
35
|
+
constructor(emulatorName, options) {
|
36
36
|
super();
|
37
37
|
this._options = options;
|
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;
|
38
|
+
this._args = this._getEmulatorArgs(emulatorName);
|
39
|
+
this.port = options.port;
|
51
40
|
}
|
52
41
|
|
53
42
|
_getArgs() {
|
54
43
|
return this._args;
|
55
44
|
}
|
56
45
|
|
57
|
-
_getEmulatorArgs() {
|
46
|
+
_getEmulatorArgs(emulatorName) {
|
58
47
|
const {
|
59
|
-
avdName,
|
60
48
|
bootArgs,
|
61
49
|
gpuMode = this._getDefaultGPUMode(),
|
62
50
|
headless,
|
@@ -76,7 +64,7 @@ class LaunchCommand extends ExecCommand {
|
|
76
64
|
port ? '-port' : '',
|
77
65
|
port ? `${port}` : '',
|
78
66
|
...deviceBootArgs,
|
79
|
-
`@${
|
67
|
+
`@${emulatorName}`
|
80
68
|
]);
|
81
69
|
|
82
70
|
return emulatorArgs;
|
@@ -0,0 +1,25 @@
|
|
1
|
+
const Instance = require('./dto/GenyInstance');
|
2
|
+
|
3
|
+
class GenyInstanceLifecycleService {
|
4
|
+
constructor(genyCloudExec, instanceNaming) {
|
5
|
+
this.genyCloudExec = genyCloudExec;
|
6
|
+
this.instanceNaming = instanceNaming;
|
7
|
+
}
|
8
|
+
|
9
|
+
async createInstance(recipeUUID) {
|
10
|
+
const result = await this.genyCloudExec.startInstance(recipeUUID, this.instanceNaming.generateName());
|
11
|
+
return new Instance(result.instance);
|
12
|
+
}
|
13
|
+
|
14
|
+
async adbConnectInstance(instanceUUID) {
|
15
|
+
const result = (await this.genyCloudExec.adbConnect(instanceUUID));
|
16
|
+
return new Instance(result.instance);
|
17
|
+
}
|
18
|
+
|
19
|
+
async deleteInstance(instanceUUID) {
|
20
|
+
const result = await this.genyCloudExec.stopInstance(instanceUUID);
|
21
|
+
return new Instance(result.instance);
|
22
|
+
}
|
23
|
+
}
|
24
|
+
|
25
|
+
module.exports = GenyInstanceLifecycleService;
|
@@ -0,0 +1,38 @@
|
|
1
|
+
const Instance = require('./dto/GenyInstance');
|
2
|
+
|
3
|
+
class GenyInstanceLookupService {
|
4
|
+
constructor(genyCloudExec, instanceNaming, genyCloudDeviceRegistry) {
|
5
|
+
this.genyCloudExec = genyCloudExec;
|
6
|
+
this.instanceNaming = instanceNaming;
|
7
|
+
this.deviceRegistry = genyCloudDeviceRegistry;
|
8
|
+
}
|
9
|
+
|
10
|
+
async findFreeInstance() {
|
11
|
+
const freeInstances = await this._getRelevantInstances();
|
12
|
+
return (freeInstances[0] || null);
|
13
|
+
}
|
14
|
+
|
15
|
+
async getInstance(instanceUUID) {
|
16
|
+
const { instance } = await this.genyCloudExec.getInstance(instanceUUID);
|
17
|
+
return new Instance(instance);
|
18
|
+
}
|
19
|
+
|
20
|
+
async _getRelevantInstances() {
|
21
|
+
const takenInstances = this.deviceRegistry.getRegisteredDevices();
|
22
|
+
const isRelevant = (instance) =>
|
23
|
+
(instance.isOnline() || instance.isInitializing()) &&
|
24
|
+
this.instanceNaming.isFamilial(instance.name) &&
|
25
|
+
!takenInstances.includes(instance.uuid);
|
26
|
+
|
27
|
+
const instances = await this._getAllInstances();
|
28
|
+
return instances.filter(isRelevant);
|
29
|
+
}
|
30
|
+
|
31
|
+
async _getAllInstances() {
|
32
|
+
return (await this.genyCloudExec.getInstances())
|
33
|
+
.instances
|
34
|
+
.map((rawInstance) => new Instance(rawInstance));
|
35
|
+
}
|
36
|
+
}
|
37
|
+
|
38
|
+
module.exports = GenyInstanceLookupService;
|
@@ -0,0 +1,14 @@
|
|
1
|
+
const internals = () => require('../../../../../../../internals');
|
2
|
+
|
3
|
+
class GenyInstanceNaming {
|
4
|
+
generateName() {
|
5
|
+
const { session, worker } = internals();
|
6
|
+
return `Detox.${session.id}.${worker.id}`;
|
7
|
+
}
|
8
|
+
|
9
|
+
isFamilial(name) {
|
10
|
+
return name === this.generateName();
|
11
|
+
}
|
12
|
+
}
|
13
|
+
|
14
|
+
module.exports = GenyInstanceNaming;
|
package/src/devices/{allocation → common}/drivers/android/genycloud/services/dto/GenyInstance.js
RENAMED
@@ -59,12 +59,7 @@ class GenyInstance {
|
|
59
59
|
}
|
60
60
|
|
61
61
|
toString() {
|
62
|
-
|
63
|
-
this.uuid,
|
64
|
-
this.adbName
|
65
|
-
].filter(Boolean).join('/');
|
66
|
-
|
67
|
-
return `${this.name} (${description})`;
|
62
|
+
return `GenyCloud:${this.name} (${this.uuid} ${this.adbName})`;
|
68
63
|
}
|
69
64
|
}
|
70
65
|
|
package/src/devices/{allocation/drivers/android → common/drivers/android/tools}/FreeDeviceFinder.js
RENAMED
@@ -1,6 +1,6 @@
|
|
1
|
-
const log = require('
|
1
|
+
const log = require('../../../../../utils/logger').child({ cat: 'device' });
|
2
2
|
|
3
|
-
const
|
3
|
+
const DEVICE_LOOKUP_LOG_EVT = 'DEVICE_LOOKUP';
|
4
4
|
|
5
5
|
class FreeDeviceFinder {
|
6
6
|
constructor(adb, deviceRegistry) {
|
@@ -10,9 +10,8 @@ class FreeDeviceFinder {
|
|
10
10
|
|
11
11
|
async findFreeDevice(deviceQuery) {
|
12
12
|
const { devices } = await this.adb.devices();
|
13
|
-
const takenDevices = this.deviceRegistry.getTakenDevicesSync();
|
14
13
|
for (const candidate of devices) {
|
15
|
-
if (await this._isDeviceFreeAndMatching(
|
14
|
+
if (await this._isDeviceFreeAndMatching(candidate, deviceQuery)) {
|
16
15
|
return candidate.adbName;
|
17
16
|
}
|
18
17
|
}
|
@@ -20,30 +19,30 @@ class FreeDeviceFinder {
|
|
20
19
|
}
|
21
20
|
|
22
21
|
/**
|
23
|
-
* @
|
22
|
+
* @protected
|
24
23
|
*/
|
25
|
-
async _isDeviceFreeAndMatching(
|
24
|
+
async _isDeviceFreeAndMatching(candidate, deviceQuery) {
|
26
25
|
const { adbName } = candidate;
|
27
26
|
|
28
|
-
const isTaken =
|
27
|
+
const isTaken = this.deviceRegistry.includes(adbName);
|
29
28
|
if (isTaken) {
|
30
|
-
log.debug(
|
29
|
+
log.debug({ event: DEVICE_LOOKUP_LOG_EVT }, `Device ${adbName} is already taken, skipping...`);
|
31
30
|
return false;
|
32
31
|
}
|
33
32
|
|
34
33
|
const isOffline = candidate.status === 'offline';
|
35
34
|
if (isOffline) {
|
36
|
-
log.debug(
|
35
|
+
log.debug({ event: DEVICE_LOOKUP_LOG_EVT }, `Device ${adbName} is offline, skipping...`);
|
37
36
|
return false;
|
38
37
|
}
|
39
38
|
|
40
39
|
const isMatching = await this._isDeviceMatching(candidate, deviceQuery);
|
41
40
|
if (!isMatching) {
|
42
|
-
log.debug(
|
41
|
+
log.debug({ event: DEVICE_LOOKUP_LOG_EVT }, `Device ${adbName} does not match "${deviceQuery}"`);
|
43
42
|
return false;
|
44
43
|
}
|
45
44
|
|
46
|
-
log.debug(
|
45
|
+
log.debug({ event: DEVICE_LOOKUP_LOG_EVT }, `Found a matching & free device ${candidate.adbName}`);
|
47
46
|
return true;
|
48
47
|
}
|
49
48
|
|
@@ -297,7 +297,7 @@ class AppleSimUtils {
|
|
297
297
|
// want to make sure it isn't now.
|
298
298
|
if (err.code === 3 &&
|
299
299
|
(err.stderr.includes(`the app is not currently running`) ||
|
300
|
-
err.stderr.includes(`
|
300
|
+
err.stderr.includes(`found nothing to terminate`))) {
|
301
301
|
return;
|
302
302
|
}
|
303
303
|
|
@@ -6,13 +6,15 @@ class GenycloudEmulatorCookie extends AndroidDeviceCookie {
|
|
6
6
|
* @param instance { GenyInstance }
|
7
7
|
*/
|
8
8
|
constructor(instance) {
|
9
|
-
super(
|
9
|
+
super();
|
10
10
|
this.instance = instance;
|
11
11
|
}
|
12
12
|
|
13
|
-
|
14
|
-
return
|
13
|
+
get adbName() {
|
14
|
+
return this.instance.adbName;
|
15
15
|
}
|
16
|
+
|
17
|
+
set adbName(value) {}
|
16
18
|
}
|
17
19
|
|
18
20
|
module.exports = GenycloudEmulatorCookie;
|
@@ -0,0 +1,71 @@
|
|
1
|
+
const logger = require('../../utils/logger').child({ cat: 'device' });
|
2
|
+
|
3
|
+
const cleanupLogData = {
|
4
|
+
event: 'GENYCLOUD_TEARDOWN',
|
5
|
+
};
|
6
|
+
|
7
|
+
class GenyGlobalLifecycleHandler {
|
8
|
+
constructor({ deviceCleanupRegistry, instanceLifecycleService }) {
|
9
|
+
/** @private */
|
10
|
+
this._deviceCleanupRegistry = deviceCleanupRegistry;
|
11
|
+
/** @private */
|
12
|
+
this._instanceLifecycleService = instanceLifecycleService;
|
13
|
+
}
|
14
|
+
|
15
|
+
async globalInit() {}
|
16
|
+
|
17
|
+
emergencyCleanup() {
|
18
|
+
const { rawDevices } = this._deviceCleanupRegistry.readRegisteredDevicesUNSAFE();
|
19
|
+
const instanceHandles = rawDevicesToInstanceHandles(rawDevices);
|
20
|
+
if (instanceHandles.length) {
|
21
|
+
reportGlobalCleanupSummary(instanceHandles);
|
22
|
+
}
|
23
|
+
}
|
24
|
+
|
25
|
+
async globalCleanup() {
|
26
|
+
const { rawDevices } = await this._deviceCleanupRegistry.readRegisteredDevices();
|
27
|
+
const instanceHandles = rawDevicesToInstanceHandles(rawDevices);
|
28
|
+
if (instanceHandles.length) {
|
29
|
+
await doSafeCleanup(this._instanceLifecycleService, instanceHandles);
|
30
|
+
}
|
31
|
+
}
|
32
|
+
}
|
33
|
+
|
34
|
+
async function doSafeCleanup(instanceLifecycleService, instanceHandles) {
|
35
|
+
logger.info(cleanupLogData, 'Initiating Genymotion SaaS instances teardown...');
|
36
|
+
|
37
|
+
const deletionLeaks = [];
|
38
|
+
const killPromises = instanceHandles.map((instanceHandle) =>
|
39
|
+
instanceLifecycleService.deleteInstance(instanceHandle.uuid)
|
40
|
+
.catch((error) => deletionLeaks.push({ ...instanceHandle, error })));
|
41
|
+
|
42
|
+
await Promise.all(killPromises);
|
43
|
+
reportGlobalCleanupSummary(deletionLeaks);
|
44
|
+
}
|
45
|
+
|
46
|
+
function reportGlobalCleanupSummary(deletionLeaks) {
|
47
|
+
if (deletionLeaks.length) {
|
48
|
+
logger.warn(cleanupLogData, 'WARNING! Detected a Genymotion SaaS instance leakage, for the following instances:');
|
49
|
+
|
50
|
+
deletionLeaks.forEach(({ uuid, name, error }) => {
|
51
|
+
logger.warn(cleanupLogData, [
|
52
|
+
`Instance ${name} (${uuid})${error ? `: ${error}` : ''}`,
|
53
|
+
` Kill it by visiting https://cloud.geny.io/instance/${uuid}, or by running:`,
|
54
|
+
` gmsaas instances stop ${uuid}`,
|
55
|
+
].join('\n'));
|
56
|
+
});
|
57
|
+
|
58
|
+
logger.info(cleanupLogData, 'Instances teardown completed with warnings');
|
59
|
+
} else {
|
60
|
+
logger.info(cleanupLogData, 'Instances teardown completed successfully');
|
61
|
+
}
|
62
|
+
}
|
63
|
+
|
64
|
+
function rawDevicesToInstanceHandles(rawDevices) {
|
65
|
+
return rawDevices.map((rawDevice) => ({
|
66
|
+
uuid: rawDevice.id,
|
67
|
+
name: rawDevice.data.name,
|
68
|
+
}));
|
69
|
+
}
|
70
|
+
|
71
|
+
module.exports = GenyGlobalLifecycleHandler;
|
@@ -0,0 +1,18 @@
|
|
1
|
+
class GenyGlobalLifecycleHandlerFactory {
|
2
|
+
/**
|
3
|
+
* @returns { GenyGlobalLifecycleHandler }
|
4
|
+
*/
|
5
|
+
createHandler() {
|
6
|
+
const serviceLocator = require('../../../servicelocator/android');
|
7
|
+
const deviceCleanupRegistry = serviceLocator.genycloud.cleanupDeviceRegistry;
|
8
|
+
const exec = serviceLocator.genycloud.exec;
|
9
|
+
|
10
|
+
const InstanceLifecycleService = require('../../common/drivers/android/genycloud/services/GenyInstanceLifecycleService');
|
11
|
+
const instanceLifecycleService = new InstanceLifecycleService(exec, null);
|
12
|
+
|
13
|
+
const GenyGlobalLifecycleHandler = require('../GenyGlobalLifecycleHandler');
|
14
|
+
return new GenyGlobalLifecycleHandler({ deviceCleanupRegistry, instanceLifecycleService });
|
15
|
+
}
|
16
|
+
}
|
17
|
+
|
18
|
+
module.exports = GenyGlobalLifecycleHandlerFactory;
|
@@ -17,12 +17,12 @@ class GenyCloudDriver extends AndroidDriver {
|
|
17
17
|
* @param props { GenycloudDriverProps }
|
18
18
|
*/
|
19
19
|
constructor(deps, { instance }) {
|
20
|
-
super(deps, { adbName: instance.
|
20
|
+
super(deps, { adbName: instance.adbName });
|
21
21
|
this.instance = instance;
|
22
22
|
}
|
23
23
|
|
24
24
|
getDeviceName() {
|
25
|
-
return this.instance.
|
25
|
+
return this.instance.toString();
|
26
26
|
}
|
27
27
|
|
28
28
|
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('
|
6
|
+
const serviceLocator = require('../../../servicelocator/android');
|
7
7
|
const adb = serviceLocator.adb;
|
8
8
|
const aapt = serviceLocator.aapt;
|
9
9
|
const apkValidator = serviceLocator.apkValidator;
|
@@ -2,11 +2,10 @@ 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;
|
5
7
|
const { eventEmitter } = commonDeps;
|
6
8
|
|
7
|
-
const AppleSimUtils = require('../../../devices/common/drivers/ios/tools/AppleSimUtils');
|
8
|
-
const applesimutils = new AppleSimUtils();
|
9
|
-
|
10
9
|
const SimulatorLauncher = require('../../allocation/drivers/ios/SimulatorLauncher');
|
11
10
|
return {
|
12
11
|
...commonDeps,
|
@@ -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');
|
6
5
|
const matchersFactories = require('./matchers/factories');
|
7
6
|
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,6 +36,15 @@ 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
|
+
|
39
48
|
function _getFactoryClasses(deviceConfig) {
|
40
49
|
let envValidatorFactoryClass;
|
41
50
|
let artifactsManagerFactoryClass;
|
@@ -106,4 +115,5 @@ function _getExternalModuleFactories(deviceConfig) {
|
|
106
115
|
module.exports = {
|
107
116
|
validateConfig,
|
108
117
|
createFactories,
|
118
|
+
createGlobalLifecycleHandler,
|
109
119
|
};
|
package/src/ipc/IPCClient.js
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
const { IPC } = require('node-ipc');
|
2
2
|
|
3
3
|
const { DetoxInternalError } = require('../errors');
|
4
|
-
const { serializeObjectWithError
|
4
|
+
const { serializeObjectWithError } = require('../utils/errorUtils');
|
5
5
|
|
6
6
|
class IPCClient {
|
7
7
|
constructor({ id, logger, sessionState }) {
|
@@ -60,22 +60,6 @@ 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
|
-
|
79
63
|
/**
|
80
64
|
* @param {DetoxInternals.DetoxTestFileReport[]} testResults
|
81
65
|
*/
|