detox 21.0.0-rc.1 → 21.0.0-rc.10
Sign up to get free protection for your applications and to get access to all the features.
- package/.eslintignore +3 -0
- package/.eslintrc.js +1 -40
- package/Detox-android/com/wix/detox/{21.0.0-rc.1/detox-21.0.0-rc.1-javadoc.jar → 21.0.0-rc.10/detox-21.0.0-rc.10-javadoc.jar} +0 -0
- package/Detox-android/com/wix/detox/21.0.0-rc.10/detox-21.0.0-rc.10-javadoc.jar.md5 +1 -0
- package/Detox-android/com/wix/detox/21.0.0-rc.10/detox-21.0.0-rc.10-javadoc.jar.sha1 +1 -0
- package/Detox-android/com/wix/detox/21.0.0-rc.10/detox-21.0.0-rc.10-javadoc.jar.sha256 +1 -0
- package/Detox-android/com/wix/detox/21.0.0-rc.10/detox-21.0.0-rc.10-javadoc.jar.sha512 +1 -0
- package/Detox-android/com/wix/detox/{21.0.0-rc.1/detox-21.0.0-rc.1-sources.jar → 21.0.0-rc.10/detox-21.0.0-rc.10-sources.jar} +0 -0
- package/Detox-android/com/wix/detox/21.0.0-rc.10/detox-21.0.0-rc.10-sources.jar.md5 +1 -0
- package/Detox-android/com/wix/detox/21.0.0-rc.10/detox-21.0.0-rc.10-sources.jar.sha1 +1 -0
- package/Detox-android/com/wix/detox/21.0.0-rc.10/detox-21.0.0-rc.10-sources.jar.sha256 +1 -0
- package/Detox-android/com/wix/detox/21.0.0-rc.10/detox-21.0.0-rc.10-sources.jar.sha512 +1 -0
- package/Detox-android/com/wix/detox/21.0.0-rc.10/detox-21.0.0-rc.10.aar +0 -0
- package/Detox-android/com/wix/detox/21.0.0-rc.10/detox-21.0.0-rc.10.aar.md5 +1 -0
- package/Detox-android/com/wix/detox/21.0.0-rc.10/detox-21.0.0-rc.10.aar.sha1 +1 -0
- package/Detox-android/com/wix/detox/21.0.0-rc.10/detox-21.0.0-rc.10.aar.sha256 +1 -0
- package/Detox-android/com/wix/detox/21.0.0-rc.10/detox-21.0.0-rc.10.aar.sha512 +1 -0
- package/Detox-android/com/wix/detox/{21.0.0-rc.1/detox-21.0.0-rc.1.pom → 21.0.0-rc.10/detox-21.0.0-rc.10.pom} +1 -7
- package/Detox-android/com/wix/detox/21.0.0-rc.10/detox-21.0.0-rc.10.pom.md5 +1 -0
- package/Detox-android/com/wix/detox/21.0.0-rc.10/detox-21.0.0-rc.10.pom.sha1 +1 -0
- package/Detox-android/com/wix/detox/21.0.0-rc.10/detox-21.0.0-rc.10.pom.sha256 +1 -0
- package/Detox-android/com/wix/detox/21.0.0-rc.10/detox-21.0.0-rc.10.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-framework.tbz +0 -0
- package/Detox-ios-src.tbz +0 -0
- package/Detox-ios-xcuitest.tbz +0 -0
- package/android/build.gradle +20 -10
- package/android/detox/build.gradle +24 -12
- package/android/detox/src/full/java/com/wix/detox/espresso/DetoxAssertion.java +44 -25
- package/android/detox/src/full/java/com/wix/detox/espresso/DetoxMatcher.java +12 -12
- 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/AdjustSliderToPositionAction.kt +2 -2
- package/android/detox/src/full/java/com/wix/detox/espresso/action/GetAttributesAction.kt +34 -35
- package/android/detox/src/full/java/com/wix/detox/espresso/common/MaterialSliderHelper.kt +21 -0
- package/android/detox/src/full/java/com/wix/detox/espresso/common/{SliderHelper.kt → ReactSliderHelper.kt} +7 -6
- package/android/detox/src/full/java/com/wix/detox/espresso/matcher/RegexMatcher.kt +56 -0
- package/android/detox/src/full/java/com/wix/detox/espresso/matcher/ViewMatchers.kt +18 -6
- 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/detox/espresso/web/WebElement.java +4 -4
- package/android/detox/src/full/java/com/wix/invoke/types/Invocation.java +7 -6
- 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/main/java/com/wix/detox/espresso/action/common/MotionEvents.kt +60 -4
- 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/common/MaterialSliderHelperTest.kt +33 -0
- package/android/detox/src/testFull/java/com/wix/detox/espresso/common/{SliderHelperTest.kt → ReactSliderHelperTest.kt} +3 -3
- package/android/detox/src/testFull/java/com/wix/detox/espresso/matcher/RegexMatcherTest.kt +52 -0
- package/android/detox/src/testFull/java/com/wix/detox/espresso/performer/ViewActionPerformerSpec.kt +37 -0
- package/android/detox/src/testFull/java/com/wix/invoke/JsonParserTest.java +23 -7
- package/android/detox/src/testFull/resources/targetInvocationEspressoWebDetoxScript.json +47 -0
- package/android/gradle/wrapper/gradle-wrapper.properties +1 -1
- package/android/rninfo.gradle +25 -0
- package/android/settings.gradle +2 -1
- package/detox.d.ts +1840 -0
- package/globals.d.ts +23 -0
- package/index.d.ts +2 -1789
- package/internals.d.ts +11 -1
- package/jest.config.js +108 -0
- package/local-cli/reset-lock-file.js +5 -9
- package/local-cli/startCommand/AppStartCommand.js +4 -1
- package/local-cli/testCommand/TestRunnerCommand.js +26 -3
- package/local-cli/utils/interruptListeners.js +15 -0
- package/package.json +15 -108
- package/runners/jest/reporter.js +21 -1
- package/runners/jest/reporters/DetoxIPCReporter.js +34 -0
- package/runners/jest/reporters/DetoxReporterDispatcher.js +144 -0
- package/runners/jest/reporters/DetoxSummaryReporter.js +16 -0
- package/runners/jest/reporters/DetoxVerboseReporter.js +16 -0
- package/runners/jest/reporters/index.js +6 -0
- package/runners/jest/testEnvironment/index.js +11 -0
- package/src/DetoxWorker.js +5 -11
- package/src/android/core/NativeElement.js +26 -29
- package/src/android/core/WebElement.js +24 -6
- package/src/android/espressoapi/DetoxAssertion.js +16 -14
- package/src/android/espressoapi/DetoxMatcher.js +24 -8
- package/src/android/espressoapi/EspressoDetox.js +9 -2
- package/src/android/espressoapi/web/WebElement.js +1 -4
- package/src/android/interactions/native.js +2 -3
- package/src/android/matchers/index.js +4 -0
- package/src/android/matchers/native.js +9 -4
- package/src/android/matchers/web.js +26 -1
- package/src/artifacts/providers/index.js +3 -3
- package/src/artifacts/screenshot/SimulatorScreenshotPlugin.js +0 -17
- package/src/configuration/composeLoggerConfig.js +1 -0
- package/src/configuration/composeRunnerConfig.js +3 -1
- package/src/devices/allocation/DeviceAllocator.js +66 -20
- package/src/devices/allocation/DeviceList.js +44 -0
- package/src/devices/allocation/DeviceRegistry.js +189 -0
- package/src/devices/allocation/drivers/AllocationDriverBase.d.ts +15 -0
- package/src/devices/{common/drivers/android/tools → allocation/drivers/android}/FreeDeviceFinder.js +11 -10
- package/src/devices/allocation/drivers/android/attached/AttachedAndroidAllocDriver.js +22 -17
- package/src/devices/allocation/drivers/android/emulator/EmulatorAllocDriver.js +97 -38
- package/src/devices/allocation/drivers/android/emulator/EmulatorLauncher.js +32 -45
- package/src/devices/allocation/drivers/android/emulator/FreeEmulatorFinder.js +1 -1
- package/src/devices/allocation/drivers/android/emulator/FreePortFinder.js +37 -0
- package/src/devices/allocation/drivers/android/emulator/launchEmulatorProcess.js +3 -3
- package/src/devices/allocation/drivers/android/genycloud/GenyAllocDriver.js +104 -32
- package/src/devices/allocation/drivers/android/genycloud/GenyInstanceLauncher.js +40 -31
- package/src/devices/allocation/drivers/android/genycloud/GenyRegistry.js +121 -0
- package/src/devices/allocation/drivers/android/genycloud/services/GenyInstanceLifecycleService.js +24 -0
- package/src/devices/{common → allocation}/drivers/android/genycloud/services/GenyRecipesService.js +1 -1
- package/src/devices/allocation/drivers/android/genycloud/services/dto/GenyInstance.js +83 -0
- package/src/devices/allocation/drivers/android/genycloud/services/dto/GenyRecipe.js +25 -0
- package/src/devices/allocation/drivers/ios/SimulatorAllocDriver.js +95 -54
- package/src/devices/allocation/drivers/ios/SimulatorQuery.js +24 -0
- package/src/devices/allocation/factories/android.js +29 -35
- package/src/devices/allocation/factories/ios.js +6 -7
- package/src/devices/common/drivers/DeviceCookie.d.ts +12 -0
- package/src/devices/common/drivers/android/cookies.d.ts +11 -0
- package/src/devices/common/drivers/android/emulator/exec/EmulatorExec.js +17 -5
- package/src/devices/common/drivers/android/exec/ADB.js +1 -0
- package/src/devices/common/drivers/android/tools/instrumentationArgs.js +7 -1
- package/src/devices/common/drivers/ios/cookies.d.ts +9 -0
- package/src/devices/common/drivers/ios/tools/AppleSimUtils.js +3 -1
- package/src/devices/cookies/index.js +0 -6
- package/src/devices/runtime/drivers/android/genycloud/GenyCloudDriver.js +7 -6
- package/src/devices/runtime/drivers/ios/SimulatorDriver.js +5 -4
- package/src/devices/runtime/drivers/ios/XCUITestUtils.js +21 -11
- package/src/devices/runtime/factories/android.js +3 -11
- package/src/devices/runtime/factories/ios.js +3 -4
- package/src/{servicelocator → devices/servicelocator}/android/emulatorServiceLocator.js +1 -1
- package/src/devices/servicelocator/android/genycloudServiceLocator.js +17 -0
- package/src/devices/servicelocator/android/index.js +23 -0
- package/src/{validation → devices/validation}/EnvironmentValidatorBase.js +1 -0
- package/src/{validation → devices/validation}/android/GenycloudEnvValidator.js +2 -2
- package/src/{validation → devices/validation}/factories/index.js +1 -1
- package/src/{validation → devices/validation}/ios/IosSimulatorEnvValidator.js +2 -2
- package/src/environmentFactory.js +1 -11
- package/src/invoke.js +0 -2
- package/src/ios/expectTwo.js +28 -11
- package/src/ios/web.js +302 -0
- package/src/ipc/IPCClient.js +22 -1
- package/src/ipc/IPCServer.js +42 -1
- package/src/ipc/SessionState.js +1 -0
- package/src/logger/DetoxLogger.js +2 -2
- package/src/realms/DetoxContext.js +8 -0
- package/src/realms/DetoxInternalsFacade.js +1 -0
- package/src/realms/DetoxPrimaryContext.js +49 -44
- package/src/realms/DetoxSecondaryContext.js +27 -0
- package/src/realms/symbols.js +6 -0
- package/src/utils/PIDService.js +27 -0
- package/src/utils/assertIsFunction.js +35 -0
- package/src/utils/environment.js +8 -15
- package/src/utils/errorUtils.js +3 -3
- package/src/utils/invocationTraceDescriptions.js +16 -0
- package/src/utils/isArrowFunction.js +24 -0
- package/src/utils/isRegExp.js +7 -0
- package/tsconfig.json +8 -3
- package/Detox-android/com/wix/detox/21.0.0-rc.1/detox-21.0.0-rc.1-javadoc.jar.md5 +0 -1
- package/Detox-android/com/wix/detox/21.0.0-rc.1/detox-21.0.0-rc.1-javadoc.jar.sha1 +0 -1
- package/Detox-android/com/wix/detox/21.0.0-rc.1/detox-21.0.0-rc.1-javadoc.jar.sha256 +0 -1
- package/Detox-android/com/wix/detox/21.0.0-rc.1/detox-21.0.0-rc.1-javadoc.jar.sha512 +0 -1
- package/Detox-android/com/wix/detox/21.0.0-rc.1/detox-21.0.0-rc.1-sources.jar.md5 +0 -1
- package/Detox-android/com/wix/detox/21.0.0-rc.1/detox-21.0.0-rc.1-sources.jar.sha1 +0 -1
- package/Detox-android/com/wix/detox/21.0.0-rc.1/detox-21.0.0-rc.1-sources.jar.sha256 +0 -1
- package/Detox-android/com/wix/detox/21.0.0-rc.1/detox-21.0.0-rc.1-sources.jar.sha512 +0 -1
- package/Detox-android/com/wix/detox/21.0.0-rc.1/detox-21.0.0-rc.1.aar +0 -0
- package/Detox-android/com/wix/detox/21.0.0-rc.1/detox-21.0.0-rc.1.aar.md5 +0 -1
- package/Detox-android/com/wix/detox/21.0.0-rc.1/detox-21.0.0-rc.1.aar.sha1 +0 -1
- package/Detox-android/com/wix/detox/21.0.0-rc.1/detox-21.0.0-rc.1.aar.sha256 +0 -1
- package/Detox-android/com/wix/detox/21.0.0-rc.1/detox-21.0.0-rc.1.aar.sha512 +0 -1
- package/Detox-android/com/wix/detox/21.0.0-rc.1/detox-21.0.0-rc.1.pom.md5 +0 -1
- package/Detox-android/com/wix/detox/21.0.0-rc.1/detox-21.0.0-rc.1.pom.sha1 +0 -1
- package/Detox-android/com/wix/detox/21.0.0-rc.1/detox-21.0.0-rc.1.pom.sha256 +0 -1
- package/Detox-android/com/wix/detox/21.0.0-rc.1/detox-21.0.0-rc.1.pom.sha512 +0 -1
- package/runners/jest/reporters/DetoxReporter.js +0 -36
- package/src/devices/DeviceRegistry.js +0 -176
- package/src/devices/allocation/drivers/AllocationDriverBase.js +0 -30
- package/src/devices/allocation/drivers/android/attached/AttachedAndroidLauncher.js +0 -13
- package/src/devices/allocation/drivers/android/emulator/EmulatorAllocationHelper.js +0 -72
- package/src/devices/allocation/drivers/android/genycloud/GenyDeviceRegistryFactory.js +0 -16
- package/src/devices/allocation/drivers/android/genycloud/GenyInstanceAllocationHelper.js +0 -65
- package/src/devices/allocation/drivers/ios/SimulatorLauncher.js +0 -21
- package/src/devices/common/drivers/DeviceAllocationHelper.js +0 -20
- package/src/devices/common/drivers/DeviceLauncher.js +0 -19
- package/src/devices/common/drivers/android/genycloud/services/GenyInstanceLifecycleService.js +0 -25
- package/src/devices/common/drivers/android/genycloud/services/GenyInstanceLookupService.js +0 -38
- package/src/devices/common/drivers/android/genycloud/services/GenyInstanceNaming.js +0 -14
- package/src/devices/common/drivers/android/genycloud/services/dto/GenyInstance.js +0 -66
- package/src/devices/common/drivers/android/genycloud/services/dto/GenyRecipe.js +0 -13
- package/src/devices/cookies/AndroidDeviceCookie.js +0 -13
- package/src/devices/cookies/AndroidEmulatorCookie.js +0 -6
- package/src/devices/cookies/AttachedAndroidDeviceCookie.js +0 -12
- package/src/devices/cookies/DeviceCookie.js +0 -4
- package/src/devices/cookies/GenycloudEmulatorCookie.js +0 -20
- package/src/devices/cookies/IosCookie.js +0 -6
- package/src/devices/cookies/IosSimulatorCookie.js +0 -10
- package/src/devices/lifecycle/GenyGlobalLifecycleHandler.js +0 -71
- package/src/devices/lifecycle/factories/GenyGlobalLifecycleHandlerFactory.js +0 -18
- package/src/invoke/EarlGrey.js +0 -8
- package/src/servicelocator/android/genycloudServiceLocator.js +0 -21
- package/src/servicelocator/android/index.js +0 -25
- package/src/servicelocator/ios.js +0 -7
- /package/src/devices/{common → allocation}/drivers/android/genycloud/exec/GenyCloudExec.js +0 -0
- /package/src/devices/{common → allocation}/drivers/android/genycloud/services/GenyAuthService.js +0 -0
package/src/ios/web.js
ADDED
@@ -0,0 +1,302 @@
|
|
1
|
+
const assert = require('assert');
|
2
|
+
|
3
|
+
const _ = require('lodash');
|
4
|
+
|
5
|
+
const { DetoxRuntimeError } = require('../errors');
|
6
|
+
const { webViewActionDescription, expectDescription } = require('../utils/invocationTraceDescriptions');
|
7
|
+
const log = require('../utils/logger').child({ cat: 'ws-client, ws' });
|
8
|
+
const traceInvocationCall = require('../utils/traceInvocationCall').bind(null, log);
|
9
|
+
|
10
|
+
|
11
|
+
class WebExpect {
|
12
|
+
constructor(invocationManager, element) {
|
13
|
+
this._invocationManager = invocationManager;
|
14
|
+
this.element = element;
|
15
|
+
this.modifiers = [];
|
16
|
+
}
|
17
|
+
|
18
|
+
toHaveText(text) {
|
19
|
+
const traceDescription = expectDescription.toHaveText(text);
|
20
|
+
return this.expect('toHaveText', traceDescription, text);
|
21
|
+
}
|
22
|
+
|
23
|
+
toExist() {
|
24
|
+
const traceDescription = expectDescription.toExist();
|
25
|
+
return this.expect('toExist', traceDescription);
|
26
|
+
}
|
27
|
+
|
28
|
+
get not() {
|
29
|
+
this.modifiers.push('not');
|
30
|
+
return this;
|
31
|
+
}
|
32
|
+
getText;
|
33
|
+
createInvocation(webExpectation, ...params) {
|
34
|
+
const definedParams = _.without(params, undefined);
|
35
|
+
return {
|
36
|
+
type: 'webExpectation',
|
37
|
+
...(this.element.webViewElement !== undefined) && {
|
38
|
+
predicate: this.element.webViewElement.matcher.predicate,
|
39
|
+
...(this.element.webViewElement.index !== undefined && { atIndex: this.element.webViewElement.index }),
|
40
|
+
},
|
41
|
+
webPredicate: this.element.matcher.predicate,
|
42
|
+
...(this.element.index !== undefined && { webAtIndex: this.element.index }),
|
43
|
+
...(this.modifiers.length !== 0 && { webModifiers: this.modifiers }),
|
44
|
+
webExpectation,
|
45
|
+
...(definedParams.length !== 0 && { params: definedParams })
|
46
|
+
};
|
47
|
+
}
|
48
|
+
|
49
|
+
expect(expectation, traceDescription, ...params) {
|
50
|
+
assert(traceDescription, `must provide trace description for expectation: \n ${JSON.stringify(expectation)}`);
|
51
|
+
|
52
|
+
const invocation = this.createInvocation(expectation, ...params);
|
53
|
+
traceDescription = expectDescription.full(traceDescription, this.modifiers.includes('not'));
|
54
|
+
return _executeInvocation(this._invocationManager, invocation, traceDescription);
|
55
|
+
}
|
56
|
+
}
|
57
|
+
|
58
|
+
class WebElement {
|
59
|
+
constructor(invocationManager, emitter, webViewElement, matcher, index) {
|
60
|
+
this._invocationManager = invocationManager;
|
61
|
+
this._emitter = emitter;
|
62
|
+
this.webViewElement = webViewElement;
|
63
|
+
this.matcher = matcher;
|
64
|
+
this.index = index;
|
65
|
+
}
|
66
|
+
|
67
|
+
atIndex(index) {
|
68
|
+
if (typeof index !== 'number') throw new DetoxRuntimeError(`atIndex argument must be a number, got ${typeof index}`);
|
69
|
+
this.index = index;
|
70
|
+
return this;
|
71
|
+
}
|
72
|
+
|
73
|
+
tap() {
|
74
|
+
const traceDescription = webViewActionDescription.tap();
|
75
|
+
return this.withAction('tap', traceDescription);
|
76
|
+
}
|
77
|
+
|
78
|
+
typeText(text, isContentEditable = false) {
|
79
|
+
const traceDescription = webViewActionDescription.typeText(text, isContentEditable);
|
80
|
+
return this.withAction('typeText', traceDescription, text, isContentEditable);
|
81
|
+
}
|
82
|
+
|
83
|
+
replaceText(text) {
|
84
|
+
const traceDescription = webViewActionDescription.replaceText(text);
|
85
|
+
return this.withAction('replaceText', traceDescription, text);
|
86
|
+
}
|
87
|
+
|
88
|
+
clearText() {
|
89
|
+
const traceDescription = webViewActionDescription.clearText();
|
90
|
+
return this.withAction('clearText', traceDescription);
|
91
|
+
}
|
92
|
+
|
93
|
+
selectAllText() {
|
94
|
+
const traceDescription = webViewActionDescription.selectAllText();
|
95
|
+
return this.withAction('selectAllText', traceDescription);
|
96
|
+
}
|
97
|
+
|
98
|
+
async getText() {
|
99
|
+
const traceDescription = webViewActionDescription.getText();
|
100
|
+
let result = await this.withAction('getText', traceDescription);
|
101
|
+
|
102
|
+
if (result['text']) {
|
103
|
+
return result['text'];
|
104
|
+
} else {
|
105
|
+
throw new DetoxRuntimeError(`Failed to extract text from result: ${JSON.stringify(result)}`);
|
106
|
+
}
|
107
|
+
}
|
108
|
+
|
109
|
+
scrollToView() {
|
110
|
+
const traceDescription = webViewActionDescription.scrollToView();
|
111
|
+
return this.withAction('scrollToView', traceDescription);
|
112
|
+
}
|
113
|
+
|
114
|
+
focus() {
|
115
|
+
const traceDescription = webViewActionDescription.focus();
|
116
|
+
return this.withAction('focus', traceDescription);
|
117
|
+
}
|
118
|
+
|
119
|
+
moveCursorToEnd() {
|
120
|
+
const traceDescription = webViewActionDescription.moveCursorToEnd();
|
121
|
+
return this.withAction('moveCursorToEnd', traceDescription);
|
122
|
+
}
|
123
|
+
|
124
|
+
async runScript(script, args) {
|
125
|
+
if (args !== undefined && args.length !== 0) {
|
126
|
+
return await this.runScriptWithArgs(script, args);
|
127
|
+
}
|
128
|
+
|
129
|
+
const traceDescription = webViewActionDescription.runScript(script);
|
130
|
+
const result = await this.withAction('runScript', traceDescription, script);
|
131
|
+
|
132
|
+
if (result['result'] !== undefined) {
|
133
|
+
return result['result'];
|
134
|
+
} else {
|
135
|
+
throw new DetoxRuntimeError(`Failed to extract result from result: ${JSON.stringify(result)}`);
|
136
|
+
}
|
137
|
+
}
|
138
|
+
|
139
|
+
async runScriptWithArgs(script, args) {
|
140
|
+
const traceDescription = webViewActionDescription.runScriptWithArgs(script, args);
|
141
|
+
const result = await this.withAction('runScriptWithArgs', traceDescription, script, args);
|
142
|
+
|
143
|
+
if (result['result'] !== undefined) {
|
144
|
+
return result['result'];
|
145
|
+
} else {
|
146
|
+
throw new DetoxRuntimeError(`Failed to extract result from result: ${JSON.stringify(result)}`);
|
147
|
+
}
|
148
|
+
}
|
149
|
+
|
150
|
+
async getCurrentUrl() {
|
151
|
+
const traceDescription = webViewActionDescription.getCurrentUrl();
|
152
|
+
let result = await this.withAction('getCurrentUrl', traceDescription);
|
153
|
+
|
154
|
+
if (result['url']) {
|
155
|
+
return result['url'];
|
156
|
+
} else {
|
157
|
+
throw new DetoxRuntimeError(`Failed to extract url from result: ${JSON.stringify(result)}`);
|
158
|
+
}
|
159
|
+
}
|
160
|
+
|
161
|
+
async getTitle() {
|
162
|
+
const traceDescription = webViewActionDescription.getTitle();
|
163
|
+
let result = await this.withAction('getTitle', traceDescription);
|
164
|
+
|
165
|
+
if (result['title']) {
|
166
|
+
return result['title'];
|
167
|
+
} else {
|
168
|
+
throw new DetoxRuntimeError(`Failed to extract title from result: ${JSON.stringify(result)}`);
|
169
|
+
}
|
170
|
+
}
|
171
|
+
|
172
|
+
withAction(action, traceDescription, ...params) {
|
173
|
+
assert(traceDescription, `must provide trace description for action: \n ${JSON.stringify(action)}`);
|
174
|
+
|
175
|
+
const invocation = {
|
176
|
+
type: 'webAction',
|
177
|
+
...(this.webViewElement !== undefined) && {
|
178
|
+
predicate: this.webViewElement.matcher.predicate,
|
179
|
+
...(this.webViewElement.index !== undefined && { atIndex: this.webViewElement.index }),
|
180
|
+
},
|
181
|
+
webPredicate: this.matcher.predicate,
|
182
|
+
...(this.index !== undefined && { webAtIndex: this.index }),
|
183
|
+
webAction: action,
|
184
|
+
...(params.length !== 0 && { params }),
|
185
|
+
};
|
186
|
+
traceDescription = webViewActionDescription.full(traceDescription);
|
187
|
+
return _executeInvocation(this._invocationManager, invocation, traceDescription);
|
188
|
+
}
|
189
|
+
}
|
190
|
+
|
191
|
+
class WebElementMatcher {
|
192
|
+
id(id) {
|
193
|
+
if (typeof id !== 'string') throw new DetoxRuntimeError('id should be a string, but got ' + (id + (' (' + (typeof id + ')'))));
|
194
|
+
this.predicate = { type: 'id', value: id.toString() };
|
195
|
+
return this;
|
196
|
+
}
|
197
|
+
|
198
|
+
className(className) {
|
199
|
+
if (typeof className !== 'string') throw new DetoxRuntimeError('className should be a string, but got ' + (className + (' (' + (typeof className + ')'))));
|
200
|
+
this.predicate = { type: 'class', value: className.toString() };
|
201
|
+
return this;
|
202
|
+
}
|
203
|
+
|
204
|
+
cssSelector(cssSelector) {
|
205
|
+
if (typeof cssSelector !== 'string') throw new DetoxRuntimeError('cssSelector should be a string, but got ' + (cssSelector + (' (' + (typeof cssSelector + ')'))));
|
206
|
+
this.predicate = { type: 'css', value: cssSelector.toString() };
|
207
|
+
return this;
|
208
|
+
}
|
209
|
+
|
210
|
+
name(name) {
|
211
|
+
if (typeof name !== 'string') throw new DetoxRuntimeError('name should be a string, but got ' + (name + (' (' + (typeof name + ')'))));
|
212
|
+
this.predicate = { type: 'name', value: name.toString() };
|
213
|
+
return this;
|
214
|
+
}
|
215
|
+
|
216
|
+
xpath(xpath) {
|
217
|
+
if (typeof xpath !== 'string') throw new DetoxRuntimeError('xpath should be a string, but got ' + (xpath + (' (' + (typeof xpath + ')'))));
|
218
|
+
this.predicate = { type: 'xpath', value: xpath.toString() };
|
219
|
+
return this;
|
220
|
+
}
|
221
|
+
|
222
|
+
href(href) {
|
223
|
+
if (typeof href !== 'string') throw new DetoxRuntimeError('href should be a string, but got ' + (href + (' (' + (typeof href + ')'))));
|
224
|
+
this.predicate = { type: 'href', value: href.toString() };
|
225
|
+
return this;
|
226
|
+
}
|
227
|
+
|
228
|
+
hrefContains(href) {
|
229
|
+
if (typeof href !== 'string') throw new DetoxRuntimeError('href should be a string, but got ' + (href + (' (' + (typeof href + ')'))));
|
230
|
+
this.predicate = { type: 'hrefContains', value: href.toString() };
|
231
|
+
return this;
|
232
|
+
}
|
233
|
+
|
234
|
+
tag(tag) {
|
235
|
+
if (typeof tag !== 'string') throw new DetoxRuntimeError('tag should be a string, but got ' + (tag + (' (' + (typeof tag + ')'))));
|
236
|
+
this.predicate = { type: 'tag', value: tag.toString() };
|
237
|
+
return this;
|
238
|
+
}
|
239
|
+
|
240
|
+
label(label) {
|
241
|
+
if (typeof label !== 'string') throw new DetoxRuntimeError('label should be a string, but got ' + (label + (' (' + (typeof label + ')'))));
|
242
|
+
this.predicate = { type: 'label', value: label.toString() };
|
243
|
+
return this;
|
244
|
+
}
|
245
|
+
|
246
|
+
value(value) {
|
247
|
+
if (typeof value !== 'string') throw new DetoxRuntimeError('value should be a string, but got ' + (value + (' (' + (typeof value + ')'))));
|
248
|
+
this.predicate = { type: 'value', value: value.toString() };
|
249
|
+
return this;
|
250
|
+
}
|
251
|
+
|
252
|
+
accessibilityType(type) {
|
253
|
+
if (typeof type !== 'string') throw new DetoxRuntimeError('accessibilityType should be a string, but got ' + (type + (' (' + (typeof type + ')'))));
|
254
|
+
this.predicate = { type: 'accessibilityType', value: type.toString() };
|
255
|
+
return this;
|
256
|
+
}
|
257
|
+
}
|
258
|
+
|
259
|
+
function webMatcher() {
|
260
|
+
return new WebElementMatcher();
|
261
|
+
}
|
262
|
+
|
263
|
+
function webElement(invocationManager, emitter, webViewElement, matcher) {
|
264
|
+
if (!(matcher instanceof WebElementMatcher)) {
|
265
|
+
throwWebViewMatcherError(matcher);
|
266
|
+
}
|
267
|
+
|
268
|
+
return new WebElement(invocationManager, emitter, webViewElement, matcher);
|
269
|
+
}
|
270
|
+
|
271
|
+
function throwWebViewMatcherError(param) {
|
272
|
+
const paramDescription = JSON.stringify(param);
|
273
|
+
throw new DetoxRuntimeError(`${paramDescription} is not a Detox web-view matcher. More about web-view matchers here: https://wix.github.io/Detox/docs/api/webviews`);
|
274
|
+
}
|
275
|
+
|
276
|
+
function webExpect(invocationManager, element) {
|
277
|
+
if (!(element instanceof WebElement)) {
|
278
|
+
throwWebElementError(element);
|
279
|
+
}
|
280
|
+
|
281
|
+
return new WebExpect(invocationManager, element);
|
282
|
+
}
|
283
|
+
|
284
|
+
function throwWebElementError(param) {
|
285
|
+
const paramDescription = JSON.stringify(param);
|
286
|
+
throw new DetoxRuntimeError(`${paramDescription} is not a web element. More about web elements here: https://wix.github.io/Detox/docs/api/webviews`);
|
287
|
+
}
|
288
|
+
|
289
|
+
function _executeInvocation(invocationManager, invocation, traceDescription) {
|
290
|
+
return traceInvocationCall(traceDescription, invocation, invocationManager.execute(invocation));
|
291
|
+
}
|
292
|
+
|
293
|
+
function isWebElement(element) {
|
294
|
+
return element instanceof WebElement;
|
295
|
+
}
|
296
|
+
|
297
|
+
module.exports = {
|
298
|
+
webMatcher,
|
299
|
+
webElement,
|
300
|
+
webExpect,
|
301
|
+
isWebElement
|
302
|
+
};
|
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 } = 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({ permanent }) {
|
90
|
+
const sessionState = await this._emit('conductEarlyTeardown', { permanent });
|
91
|
+
this._sessionState.patch(sessionState);
|
92
|
+
}
|
93
|
+
|
73
94
|
async _connectToServer() {
|
74
95
|
const serverId = this.serverId;
|
75
96
|
|
package/src/ipc/IPCServer.js
CHANGED
@@ -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
|
}
|
@@ -66,6 +73,7 @@ class IPCServer {
|
|
66
73
|
this._ipc.server.emit(socket, 'registerContextDone', {
|
67
74
|
testResults: this._sessionState.testResults,
|
68
75
|
testSessionIndex: this._sessionState.testSessionIndex,
|
76
|
+
unsafe_earlyTeardown: this._sessionState.unsafe_earlyTeardown,
|
69
77
|
});
|
70
78
|
}
|
71
79
|
|
@@ -83,6 +91,39 @@ class IPCServer {
|
|
83
91
|
}
|
84
92
|
}
|
85
93
|
|
94
|
+
onConductEarlyTeardown({ permanent }, socket = null) {
|
95
|
+
const newState = { unsafe_earlyTeardown: true };
|
96
|
+
if (permanent) {
|
97
|
+
Object.assign(this._sessionState, newState);
|
98
|
+
}
|
99
|
+
|
100
|
+
if (socket) {
|
101
|
+
this._ipc.server.emit(socket, 'conductEarlyTeardownDone', newState);
|
102
|
+
}
|
103
|
+
|
104
|
+
this._ipc.server.broadcast('sessionStateUpdate', newState);
|
105
|
+
}
|
106
|
+
|
107
|
+
async onAllocateDevice(_payload, socket) {
|
108
|
+
let deviceCookie;
|
109
|
+
|
110
|
+
try {
|
111
|
+
deviceCookie = await this._callbacks.onAllocateDevice();
|
112
|
+
this._ipc.server.emit(socket, 'allocateDeviceDone', { deviceCookie });
|
113
|
+
} catch (error) {
|
114
|
+
this._ipc.server.emit(socket, 'allocateDeviceDone', serializeObjectWithError({ error }));
|
115
|
+
}
|
116
|
+
}
|
117
|
+
|
118
|
+
async onDeallocateDevice({ deviceCookie }, socket) {
|
119
|
+
try {
|
120
|
+
await this._callbacks.onDeallocateDevice(deviceCookie);
|
121
|
+
this._ipc.server.emit(socket, 'deallocateDeviceDone', {});
|
122
|
+
} catch (error) {
|
123
|
+
this._ipc.server.emit(socket, 'deallocateDeviceDone', serializeObjectWithError({ error }));
|
124
|
+
}
|
125
|
+
}
|
126
|
+
|
86
127
|
onReportTestResults({ testResults }, socket = null) {
|
87
128
|
const merged = uniqBy([
|
88
129
|
...testResults.map(r => serializeObjectWithError(r, 'testExecError')),
|
package/src/ipc/SessionState.js
CHANGED
@@ -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(
|
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,
|
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](_permanent) {}
|
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
|
}
|
@@ -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[
|
35
|
+
this[_deviceAllocator] = null;
|
36
|
+
|
37
37
|
/** Path to file where the initial session object is serialized */
|
38
38
|
this[_sessionFile] = '';
|
39
39
|
/**
|
@@ -51,8 +51,13 @@ class DetoxPrimaryContext extends DetoxContext {
|
|
51
51
|
}
|
52
52
|
}
|
53
53
|
|
54
|
-
|
55
|
-
|
54
|
+
[symbols.conductEarlyTeardown] = async (permanent = false) => {
|
55
|
+
if (this[_ipcServer]) {
|
56
|
+
await this[_ipcServer].onConductEarlyTeardown({ permanent });
|
57
|
+
}
|
58
|
+
};
|
59
|
+
|
60
|
+
async [symbols.resolveConfig](opts = {}) {
|
56
61
|
const session = this[$sessionState];
|
57
62
|
if (!session.detoxConfig) {
|
58
63
|
const configuration = require('../configuration');
|
@@ -80,7 +85,6 @@ class DetoxPrimaryContext extends DetoxContext {
|
|
80
85
|
const detoxConfig = await this[symbols.resolveConfig](opts);
|
81
86
|
|
82
87
|
const {
|
83
|
-
behavior: behaviorConfig,
|
84
88
|
device: deviceConfig,
|
85
89
|
logger: loggerConfig,
|
86
90
|
session: sessionConfig
|
@@ -97,20 +101,23 @@ class DetoxPrimaryContext extends DetoxContext {
|
|
97
101
|
this[_ipcServer] = new IPCServer({
|
98
102
|
sessionState: this[$sessionState],
|
99
103
|
logger: this[symbols.logger],
|
104
|
+
callbacks: {
|
105
|
+
onAllocateDevice: this[symbols.allocateDevice].bind(this),
|
106
|
+
onDeallocateDevice: this[symbols.deallocateDevice].bind(this),
|
107
|
+
},
|
100
108
|
});
|
101
109
|
|
102
110
|
await this[_ipcServer].init();
|
103
111
|
|
104
112
|
const environmentFactory = require('../environmentFactory');
|
105
|
-
this[_globalLifecycleHandler] = await environmentFactory.createGlobalLifecycleHandler(deviceConfig);
|
106
113
|
|
107
|
-
|
108
|
-
|
109
|
-
|
114
|
+
const { deviceAllocatorFactory } = environmentFactory.createFactories(deviceConfig);
|
115
|
+
this[_deviceAllocator] = deviceAllocatorFactory.createDeviceAllocator({
|
116
|
+
detoxConfig,
|
117
|
+
detoxSession: this[$sessionState],
|
118
|
+
});
|
110
119
|
|
111
|
-
|
112
|
-
await this[_resetLockFile]();
|
113
|
-
}
|
120
|
+
await this[_deviceAllocator].init();
|
114
121
|
|
115
122
|
// TODO: Detox-server creation ought to be delegated to a generator/factory.
|
116
123
|
const DetoxServer = require('../server/DetoxServer');
|
@@ -154,6 +161,29 @@ class DetoxPrimaryContext extends DetoxContext {
|
|
154
161
|
await super[symbols.installWorker]({ ...opts, workerId });
|
155
162
|
}
|
156
163
|
|
164
|
+
/** @override */
|
165
|
+
async [symbols.allocateDevice]() {
|
166
|
+
const { device } = this[$sessionState].detoxConfig;
|
167
|
+
const deviceCookie = await this[_deviceAllocator].allocate(device);
|
168
|
+
|
169
|
+
try {
|
170
|
+
return await this[_deviceAllocator].postAllocate(deviceCookie);
|
171
|
+
} catch (e) {
|
172
|
+
try {
|
173
|
+
await this[_deviceAllocator].free(deviceCookie, { shutdown: true });
|
174
|
+
} catch (e2) {
|
175
|
+
this[symbols.logger].error({ cat: 'device', err: e2 }, `Failed to free ${deviceCookie.name || deviceCookie.id} after a failed allocation`);
|
176
|
+
}
|
177
|
+
|
178
|
+
throw e;
|
179
|
+
}
|
180
|
+
}
|
181
|
+
|
182
|
+
/** @override */
|
183
|
+
async [symbols.deallocateDevice](cookie) {
|
184
|
+
await this[_deviceAllocator].free(cookie);
|
185
|
+
}
|
186
|
+
|
157
187
|
/** @override */
|
158
188
|
async [symbols.cleanup]() {
|
159
189
|
try {
|
@@ -161,9 +191,9 @@ class DetoxPrimaryContext extends DetoxContext {
|
|
161
191
|
await this[symbols.uninstallWorker]();
|
162
192
|
}
|
163
193
|
} finally {
|
164
|
-
if (this[
|
165
|
-
await this[
|
166
|
-
this[
|
194
|
+
if (this[_deviceAllocator]) {
|
195
|
+
await this[_deviceAllocator].cleanup();
|
196
|
+
this[_deviceAllocator] = null;
|
167
197
|
}
|
168
198
|
|
169
199
|
if (this[_wss]) {
|
@@ -197,9 +227,9 @@ class DetoxPrimaryContext extends DetoxContext {
|
|
197
227
|
return;
|
198
228
|
}
|
199
229
|
|
200
|
-
if (this[
|
201
|
-
this[
|
202
|
-
this[
|
230
|
+
if (this[_deviceAllocator]) {
|
231
|
+
this[_deviceAllocator].emergencyCleanup();
|
232
|
+
this[_deviceAllocator] = null;
|
203
233
|
}
|
204
234
|
|
205
235
|
if (this[_wss]) {
|
@@ -242,31 +272,6 @@ class DetoxPrimaryContext extends DetoxContext {
|
|
242
272
|
});
|
243
273
|
}
|
244
274
|
//#endregion
|
245
|
-
|
246
|
-
//#region Private members
|
247
|
-
async[_resetLockFile]() {
|
248
|
-
const DeviceRegistry = require('../devices/DeviceRegistry');
|
249
|
-
|
250
|
-
const deviceType = this[symbols.config].device.type;
|
251
|
-
|
252
|
-
switch (deviceType) {
|
253
|
-
case 'ios.none':
|
254
|
-
case 'ios.simulator':
|
255
|
-
await DeviceRegistry.forIOS().reset();
|
256
|
-
break;
|
257
|
-
case 'android.attached':
|
258
|
-
case 'android.emulator':
|
259
|
-
case 'android.genycloud':
|
260
|
-
await DeviceRegistry.forAndroid().reset();
|
261
|
-
break;
|
262
|
-
}
|
263
|
-
|
264
|
-
if (deviceType === 'android.genycloud') {
|
265
|
-
const GenyDeviceRegistryFactory = require('../devices/allocation/drivers/android/genycloud/GenyDeviceRegistryFactory');
|
266
|
-
await GenyDeviceRegistryFactory.forGlobalShutdown().reset();
|
267
|
-
}
|
268
|
-
}
|
269
|
-
//#endregion
|
270
275
|
}
|
271
276
|
|
272
277
|
module.exports = DetoxPrimaryContext;
|
@@ -33,6 +33,14 @@ class DetoxSecondaryContext extends DetoxContext {
|
|
33
33
|
}
|
34
34
|
}
|
35
35
|
|
36
|
+
[symbols.conductEarlyTeardown] = async (permanent = false) => {
|
37
|
+
if (this[_ipcClient]) {
|
38
|
+
await this[_ipcClient].conductEarlyTeardown({ permanent });
|
39
|
+
} else {
|
40
|
+
throw new DetoxInternalError('Detected an attempt to report early teardown using a non-initialized context.');
|
41
|
+
}
|
42
|
+
};
|
43
|
+
|
36
44
|
async [symbols.resolveConfig]() {
|
37
45
|
return this[symbols.config];
|
38
46
|
}
|
@@ -54,6 +62,25 @@ class DetoxSecondaryContext extends DetoxContext {
|
|
54
62
|
}
|
55
63
|
}
|
56
64
|
|
65
|
+
/** @override */
|
66
|
+
async [symbols.allocateDevice]() {
|
67
|
+
if (this[_ipcClient]) {
|
68
|
+
const deviceCookie = await this[_ipcClient].allocateDevice();
|
69
|
+
return deviceCookie;
|
70
|
+
} else {
|
71
|
+
throw new DetoxInternalError('Detected an attempt to allocate a device using a non-initialized context.');
|
72
|
+
}
|
73
|
+
}
|
74
|
+
|
75
|
+
/** @override */
|
76
|
+
async [symbols.deallocateDevice](deviceCookie) {
|
77
|
+
if (this[_ipcClient]) {
|
78
|
+
await this[_ipcClient].deallocateDevice(deviceCookie);
|
79
|
+
} else {
|
80
|
+
throw new DetoxInternalError('Detected an attempt to allocate a device using a non-initialized context.');
|
81
|
+
}
|
82
|
+
}
|
83
|
+
|
57
84
|
/** @override */
|
58
85
|
async [symbols.cleanup]() {
|
59
86
|
try {
|