detox 20.15.0-prerelease.0 → 20.15.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (88) hide show
  1. package/.eslintrc.js +0 -4
  2. package/Detox-android/com/wix/detox/{20.15.0-prerelease.0/detox-20.15.0-prerelease.0-javadoc.jar → 20.15.0/detox-20.15.0-javadoc.jar} +0 -0
  3. package/Detox-android/com/wix/detox/20.15.0/detox-20.15.0-javadoc.jar.md5 +1 -0
  4. package/Detox-android/com/wix/detox/20.15.0/detox-20.15.0-javadoc.jar.sha1 +1 -0
  5. package/Detox-android/com/wix/detox/20.15.0/detox-20.15.0-javadoc.jar.sha256 +1 -0
  6. package/Detox-android/com/wix/detox/20.15.0/detox-20.15.0-javadoc.jar.sha512 +1 -0
  7. package/Detox-android/com/wix/detox/{20.15.0-prerelease.0/detox-20.15.0-prerelease.0-sources.jar → 20.15.0/detox-20.15.0-sources.jar} +0 -0
  8. package/Detox-android/com/wix/detox/20.15.0/detox-20.15.0-sources.jar.md5 +1 -0
  9. package/Detox-android/com/wix/detox/20.15.0/detox-20.15.0-sources.jar.sha1 +1 -0
  10. package/Detox-android/com/wix/detox/20.15.0/detox-20.15.0-sources.jar.sha256 +1 -0
  11. package/Detox-android/com/wix/detox/20.15.0/detox-20.15.0-sources.jar.sha512 +1 -0
  12. package/Detox-android/com/wix/detox/20.15.0/detox-20.15.0.aar +0 -0
  13. package/Detox-android/com/wix/detox/20.15.0/detox-20.15.0.aar.md5 +1 -0
  14. package/Detox-android/com/wix/detox/20.15.0/detox-20.15.0.aar.sha1 +1 -0
  15. package/Detox-android/com/wix/detox/20.15.0/detox-20.15.0.aar.sha256 +1 -0
  16. package/Detox-android/com/wix/detox/20.15.0/detox-20.15.0.aar.sha512 +1 -0
  17. package/Detox-android/com/wix/detox/{20.15.0-prerelease.0/detox-20.15.0-prerelease.0.pom → 20.15.0/detox-20.15.0.pom} +1 -1
  18. package/Detox-android/com/wix/detox/20.15.0/detox-20.15.0.pom.md5 +1 -0
  19. package/Detox-android/com/wix/detox/20.15.0/detox-20.15.0.pom.sha1 +1 -0
  20. package/Detox-android/com/wix/detox/20.15.0/detox-20.15.0.pom.sha256 +1 -0
  21. package/Detox-android/com/wix/detox/20.15.0/detox-20.15.0.pom.sha512 +1 -0
  22. package/Detox-android/com/wix/detox/maven-metadata.xml +4 -4
  23. package/Detox-android/com/wix/detox/maven-metadata.xml.md5 +1 -1
  24. package/Detox-android/com/wix/detox/maven-metadata.xml.sha1 +1 -1
  25. package/Detox-android/com/wix/detox/maven-metadata.xml.sha256 +1 -1
  26. package/Detox-android/com/wix/detox/maven-metadata.xml.sha512 +1 -1
  27. package/Detox-ios-src.tbz +0 -0
  28. package/Detox-ios.tbz +0 -0
  29. package/android/detox/proguard-rules-app.pro +1 -2
  30. package/android/detox/src/full/java/com/wix/detox/espresso/DetoxAction.java +11 -6
  31. package/android/detox/src/main/java/com/wix/detox/espresso/DeviceDisplay.kt +1 -1
  32. package/android/detox/src/main/java/com/wix/detox/espresso/scroll/ScrollHelper.java +113 -16
  33. package/android/detox/src/testFull/java/com/wix/detox/espresso/scroll/ScrollHelperTest.kt +188 -0
  34. package/detox.d.ts +6 -3
  35. package/jest.config.js +1 -1
  36. package/local-cli/init.js +1 -1
  37. package/package.json +16 -16
  38. package/runners/jest/testEnvironment/index.js +24 -9
  39. package/src/DetoxWorker.js +1 -1
  40. package/src/android/actions/native.js +2 -2
  41. package/src/android/core/NativeElement.js +3 -4
  42. package/src/android/espressoapi/DetoxAction.js +9 -1
  43. package/src/android/interactions/native.js +2 -2
  44. package/src/android/matchers/native.js +1 -1
  45. package/src/artifacts/providers/index.js +1 -1
  46. package/src/artifacts/screenshot/SimulatorScreenshotPlugin.js +0 -1
  47. package/src/artifacts/templates/artifact/Artifact.js +1 -1
  48. package/src/client/AsyncWebSocket.js +2 -2
  49. package/src/client/Client.js +2 -2
  50. package/src/devices/allocation/drivers/android/attached/AttachedAndroidAllocDriver.js +0 -1
  51. package/src/devices/allocation/drivers/android/emulator/EmulatorAllocDriver.js +0 -1
  52. package/src/devices/allocation/drivers/android/emulator/EmulatorVersionResolver.js +1 -1
  53. package/src/devices/allocation/drivers/ios/SimulatorAllocDriver.js +0 -1
  54. package/src/devices/allocation/factories/android.js +1 -1
  55. package/src/devices/allocation/factories/ios.js +1 -1
  56. package/src/devices/common/drivers/android/exec/ADB.js +1 -2
  57. package/src/devices/common/drivers/android/tools/ApkValidator.js +1 -1
  58. package/src/devices/common/drivers/android/tools/AppInstallHelper.js +0 -2
  59. package/src/devices/common/drivers/ios/tools/AppleSimUtils.js +1 -0
  60. package/src/devices/runtime/drivers/android/AndroidDriver.js +1 -1
  61. package/src/devices/runtime/drivers/android/emulator/EmulatorDriver.js +0 -1
  62. package/src/devices/runtime/factories/ios.js +0 -2
  63. package/src/ios/expectTwo.js +6 -3
  64. package/src/ipc/IPCClient.js +2 -2
  65. package/src/ipc/IPCServer.js +4 -4
  66. package/src/realms/DetoxContext.js +3 -3
  67. package/src/realms/DetoxPrimaryContext.js +74 -29
  68. package/src/realms/DetoxSecondaryContext.js +2 -2
  69. package/src/utils/childProcess/exec.js +3 -2
  70. package/src/utils/invocationTraceDescriptions.js +3 -2
  71. package/tsconfig.json +1 -1
  72. package/Detox-android/com/wix/detox/20.15.0-prerelease.0/detox-20.15.0-prerelease.0-javadoc.jar.md5 +0 -1
  73. package/Detox-android/com/wix/detox/20.15.0-prerelease.0/detox-20.15.0-prerelease.0-javadoc.jar.sha1 +0 -1
  74. package/Detox-android/com/wix/detox/20.15.0-prerelease.0/detox-20.15.0-prerelease.0-javadoc.jar.sha256 +0 -1
  75. package/Detox-android/com/wix/detox/20.15.0-prerelease.0/detox-20.15.0-prerelease.0-javadoc.jar.sha512 +0 -1
  76. package/Detox-android/com/wix/detox/20.15.0-prerelease.0/detox-20.15.0-prerelease.0-sources.jar.md5 +0 -1
  77. package/Detox-android/com/wix/detox/20.15.0-prerelease.0/detox-20.15.0-prerelease.0-sources.jar.sha1 +0 -1
  78. package/Detox-android/com/wix/detox/20.15.0-prerelease.0/detox-20.15.0-prerelease.0-sources.jar.sha256 +0 -1
  79. package/Detox-android/com/wix/detox/20.15.0-prerelease.0/detox-20.15.0-prerelease.0-sources.jar.sha512 +0 -1
  80. package/Detox-android/com/wix/detox/20.15.0-prerelease.0/detox-20.15.0-prerelease.0.aar +0 -0
  81. package/Detox-android/com/wix/detox/20.15.0-prerelease.0/detox-20.15.0-prerelease.0.aar.md5 +0 -1
  82. package/Detox-android/com/wix/detox/20.15.0-prerelease.0/detox-20.15.0-prerelease.0.aar.sha1 +0 -1
  83. package/Detox-android/com/wix/detox/20.15.0-prerelease.0/detox-20.15.0-prerelease.0.aar.sha256 +0 -1
  84. package/Detox-android/com/wix/detox/20.15.0-prerelease.0/detox-20.15.0-prerelease.0.aar.sha512 +0 -1
  85. package/Detox-android/com/wix/detox/20.15.0-prerelease.0/detox-20.15.0-prerelease.0.pom.md5 +0 -1
  86. package/Detox-android/com/wix/detox/20.15.0-prerelease.0/detox-20.15.0-prerelease.0.pom.sha1 +0 -1
  87. package/Detox-android/com/wix/detox/20.15.0-prerelease.0/detox-20.15.0-prerelease.0.pom.sha256 +0 -1
  88. package/Detox-android/com/wix/detox/20.15.0-prerelease.0/detox-20.15.0-prerelease.0.pom.sha512 +0 -1
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "detox",
3
3
  "description": "E2E tests and automation for mobile",
4
- "version": "20.15.0-prerelease.0",
4
+ "version": "20.15.0",
5
5
  "bin": {
6
6
  "detox": "local-cli/cli.js"
7
7
  },
@@ -36,27 +36,26 @@
36
36
  "devDependencies": {
37
37
  "@types/bunyan": "^1.8.8",
38
38
  "@types/child-process-promise": "^2.2.1",
39
- "@types/fs-extra": "^9.0.13",
40
- "@types/jest": "^28.1.8",
39
+ "@types/fs-extra": "^11.0.4",
40
+ "@types/jest": "^29.0.0",
41
41
  "@types/node": "^14.18.33",
42
42
  "@types/node-ipc": "^9.2.0",
43
43
  "@types/ws": "^7.4.0",
44
- "@typescript-eslint/eslint-plugin": "^5.59.8",
45
- "@typescript-eslint/parser": "^5.59.8",
44
+ "@typescript-eslint/eslint-plugin": "^6.16.0",
45
+ "@typescript-eslint/parser": "^6.16.0",
46
46
  "cross-env": "^7.0.3",
47
- "eslint": "^8.41.0",
48
- "eslint-plugin-ecmascript-compat": "^3.0.0",
49
- "eslint-plugin-import": "^2.27.5",
47
+ "eslint": "^8.56.0",
48
+ "eslint-plugin-ecmascript-compat": "^3.1.0",
49
+ "eslint-plugin-import": "^2.29.1",
50
50
  "eslint-plugin-no-only-tests": "^3.1.0",
51
51
  "eslint-plugin-node": "^11.1.0",
52
- "eslint-plugin-unicorn": "^47.0.0",
53
- "jest": "^28.1.3",
54
- "jest-allure2-reporter": "2.0.0-alpha.11",
55
- "mockdate": "^2.0.1",
56
- "prettier": "^2.4.1",
52
+ "eslint-plugin-unicorn": "^50.0.1",
53
+ "jest": "^29.0.0",
54
+ "jest-allure2-reporter": "^2.0.0-beta.4",
55
+ "prettier": "^3.1.1",
57
56
  "react-native": "0.71.10",
58
57
  "react-native-codegen": "^0.0.8",
59
- "typescript": "^4.5.2",
58
+ "typescript": "^5.3.3",
60
59
  "wtfnode": "^0.9.1"
61
60
  },
62
61
  "dependencies": {
@@ -72,6 +71,7 @@
72
71
  "funpermaproxy": "^1.1.0",
73
72
  "glob": "^8.0.3",
74
73
  "ini": "^1.3.4",
74
+ "jest-environment-emit": "^1.0.5",
75
75
  "json-cycle": "^1.3.0",
76
76
  "lodash": "^4.17.11",
77
77
  "multi-sort-stream": "^1.0.3",
@@ -104,10 +104,10 @@
104
104
  }
105
105
  },
106
106
  "engines": {
107
- "node": ">=14.5.0"
107
+ "node": ">=14.14.0"
108
108
  },
109
109
  "browserslist": [
110
110
  "node 14"
111
111
  ],
112
- "gitHead": "d8d24e996503ce2618991d4ec6b9ae546335ad49"
112
+ "gitHead": "bed7b965b2180bd3c628e242b9f78a80660c371f"
113
113
  }
@@ -1,5 +1,6 @@
1
1
  const path = require('path');
2
2
 
3
+ const WithEmitter = require('jest-environment-emit').default;
3
4
  const resolveFrom = require('resolve-from');
4
5
  const maybeNodeEnvironment = require(resolveFrom(process.cwd(), 'jest-environment-node'));
5
6
  /** @type {typeof import('@jest/environment').JestEnvironment} */
@@ -31,7 +32,7 @@ const log = detox.log.child({ cat: 'lifecycle,jest-environment' });
31
32
  /**
32
33
  * @see https://www.npmjs.com/package/jest-circus#overview
33
34
  */
34
- class DetoxCircusEnvironment extends NodeEnvironment {
35
+ class DetoxCircusEnvironment extends WithEmitter(NodeEnvironment) {
35
36
  constructor(config, context) {
36
37
  super(assertJestCircus27(config), assertExistingContext(context));
37
38
 
@@ -62,6 +63,8 @@ class DetoxCircusEnvironment extends NodeEnvironment {
62
63
  SpecReporter,
63
64
  WorkerAssignReporter,
64
65
  });
66
+
67
+ this.testEvents.on('*', this._onTestEvent.bind(this));
65
68
  }
66
69
 
67
70
  /** @override */
@@ -72,19 +75,14 @@ class DetoxCircusEnvironment extends NodeEnvironment {
72
75
 
73
76
  // @ts-expect-error TS2425
74
77
  async handleTestEvent(event, state) {
78
+ // @ts-expect-error TS2855
79
+ await super.handleTestEvent(event, state);
80
+
75
81
  if (detox.session.unsafe_earlyTeardown) {
76
82
  if (event.name === 'test_fn_start' || event.name === 'hook_start') {
77
83
  throw new Error('Detox halted test execution due to an early teardown request');
78
84
  }
79
85
  }
80
-
81
- this._timer.schedule(state.testTimeout != null ? state.testTimeout : this.setupTimeout);
82
-
83
- if (SYNC_CIRCUS_EVENTS.has(event.name)) {
84
- this._handleTestEventSync(event, state);
85
- } else {
86
- await this._handleTestEventAsync(event, state);
87
- }
88
86
  }
89
87
 
90
88
  /** @override */
@@ -147,6 +145,23 @@ class DetoxCircusEnvironment extends NodeEnvironment {
147
145
  }
148
146
  }
149
147
 
148
+ /** @private */
149
+ _onTestEvent({ type, event, state }) {
150
+ const timeout = state && state.testTimeout != null ? state.testTimeout : this.setupTimeout;
151
+
152
+ this._timer.schedule(timeout);
153
+
154
+ if (event) {
155
+ if (SYNC_CIRCUS_EVENTS.has(event.name)) {
156
+ this._handleTestEventSync(event, state);
157
+ } else {
158
+ return this._handleTestEventAsync(event, state);
159
+ }
160
+ } else {
161
+ return this._handleTestEventAsync({ name: type }, null);
162
+ }
163
+ }
164
+
150
165
  /** @private */
151
166
  async _handleTestEventAsync(event, state = null) {
152
167
  const description = `handling ${state ? 'jest-circus' : 'jest-environment'} "${event.name}" event`;
@@ -132,7 +132,7 @@ class DetoxWorker {
132
132
  };
133
133
 
134
134
  this._artifactsManager = artifactsManagerFactory.createArtifactsManager(this._artifactsConfig, commonDeps);
135
- this._deviceCookie = yield this._context[symbols.allocateDevice]();
135
+ this._deviceCookie = yield this._context[symbols.allocateDevice](this._deviceConfig);
136
136
 
137
137
  this.device = runtimeDeviceFactory.createRuntimeDevice(
138
138
  this._deviceCookie,
@@ -81,10 +81,10 @@ class ScrollAmountStopAtEdgeAction extends Action {
81
81
  }
82
82
 
83
83
  class ScrollEdgeAction extends Action {
84
- constructor(edge) {
84
+ constructor(edge, startPositionX = -1, startPositionY = -1) {
85
85
  super();
86
86
 
87
- this._call = invoke.callDirectly(DetoxActionApi.scrollToEdge(edge));
87
+ this._call = invoke.callDirectly(DetoxActionApi.scrollToEdge(edge, startPositionX, startPositionY));
88
88
  }
89
89
  }
90
90
 
@@ -93,12 +93,12 @@ class NativeElement {
93
93
  return await new ActionInteraction(this._invocationManager, this._matcher, action, traceDescription).execute();
94
94
  }
95
95
 
96
- async scrollTo(edge) {
96
+ async scrollTo(edge, startPositionX, startPositionY) {
97
97
  // override the user's element selection with an extended matcher that looks for UIScrollView children
98
98
  this._matcher = this._matcher._extendToDescendantScrollViews();
99
99
 
100
- const action = new actions.ScrollEdgeAction(edge);
101
- const traceDescription = actionDescription.scrollTo(edge);
100
+ const action = new actions.ScrollEdgeAction(edge, startPositionX, startPositionY);
101
+ const traceDescription = actionDescription.scrollTo(edge, startPositionX, startPositionY);
102
102
  return await new ActionInteraction(this._invocationManager, this._matcher, action, traceDescription).execute();
103
103
  }
104
104
 
@@ -140,7 +140,6 @@ class NativeElement {
140
140
  }
141
141
 
142
142
  async takeScreenshot(screenshotName) {
143
- // TODO this should be moved to a lower-layer handler of this use-case
144
143
  const action = new actions.TakeElementScreenshot();
145
144
  const traceDescription = actionDescription.takeScreenshot(screenshotName);
146
145
  const resultBase64 = await new ActionInteraction(this._invocationManager, this._matcher, action, traceDescription).execute();
@@ -68,8 +68,10 @@ class DetoxAction {
68
68
  };
69
69
  }
70
70
 
71
- static scrollToEdge(edge) {
71
+ static scrollToEdge(edge, startOffsetPercentX, startOffsetPercentY) {
72
72
  if (typeof edge !== "string") throw new Error("edge should be a string, but got " + (edge + (" (" + (typeof edge + ")"))));
73
+ if (typeof startOffsetPercentX !== "number") throw new Error("startOffsetPercentX should be a number, but got " + (startOffsetPercentX + (" (" + (typeof startOffsetPercentX + ")"))));
74
+ if (typeof startOffsetPercentY !== "number") throw new Error("startOffsetPercentY should be a number, but got " + (startOffsetPercentY + (" (" + (typeof startOffsetPercentY + ")"))));
73
75
  return {
74
76
  target: {
75
77
  type: "Class",
@@ -79,6 +81,12 @@ class DetoxAction {
79
81
  args: [{
80
82
  type: "Integer",
81
83
  value: sanitize_android_edge(edge)
84
+ }, {
85
+ type: "Double",
86
+ value: startOffsetPercentX
87
+ }, {
88
+ type: "Double",
89
+ value: startOffsetPercentY
82
90
  }]
83
91
  };
84
92
  }
@@ -28,7 +28,7 @@ class ActionInteraction extends Interaction {
28
28
  constructor(invocationManager, matcher, action, traceDescription) {
29
29
  super(invocationManager, traceDescription);
30
30
  this._call = EspressoDetoxApi.perform(matcher, action._call);
31
- // TODO: move this.execute() here from the caller
31
+ // TODO [2024-12-01]: move this.execute() here from the caller
32
32
  }
33
33
  }
34
34
 
@@ -39,7 +39,7 @@ class MatcherAssertionInteraction extends Interaction {
39
39
 
40
40
  matcher = notCondition ? matcher.not : matcher;
41
41
  this._call = DetoxAssertionApi.assertMatcher(call(element._call), matcher._call.value);
42
- // TODO: move this.execute() here from the caller
42
+ // TODO [2024-12-01]: move this.execute() here from the caller
43
43
  }
44
44
  }
45
45
 
@@ -76,7 +76,7 @@ class ToggleMatcher extends NativeMatcher {
76
76
  }
77
77
  }
78
78
 
79
- // TODO: Please be aware, that this is just a dummy matcher
79
+ // NOTE: Please be aware, that this is just a dummy matcher
80
80
  class TraitsMatcher extends NativeMatcher {
81
81
  constructor(value) {
82
82
  super();
@@ -1,5 +1,5 @@
1
1
  class ArtifactPluginsProvider {
2
- declareArtifactPlugins({ client }) {} // eslint-disable-line no-unused-vars
2
+ declareArtifactPlugins({ client }) {} // eslint-disable-line no-unused-vars,@typescript-eslint/no-unused-vars
3
3
  }
4
4
 
5
5
  class AndroidArtifactPluginsProvider extends ArtifactPluginsProvider {
@@ -1,7 +1,6 @@
1
1
  const path = require('path');
2
2
 
3
3
  const fs = require('../../utils/fsext');
4
- const log = require('../../utils/logger').child({ cat: 'artifacts-plugin,artifacts' });
5
4
  const FileArtifact = require('../templates/artifact/FileArtifact');
6
5
  const temporaryPath = require('../utils/temporaryPath');
7
6
 
@@ -107,7 +107,7 @@ class Artifact {
107
107
 
108
108
  async doStop() {}
109
109
 
110
- async doSave(artifactPath) {} // eslint-disable-line no-unused-vars
110
+ async doSave(_artifactPath) {}
111
111
 
112
112
  async doDiscard() {}
113
113
  }
@@ -134,7 +134,7 @@ class AsyncWebSocket {
134
134
  }
135
135
  }
136
136
 
137
- // TODO: handle this leaked abstraction some day
137
+ // TODO [2024-12-01]: handle this leaked abstraction some day
138
138
  hasPendingActions() {
139
139
  return _.some(this.inFlightPromises, p => p.message.type !== 'currentStatus');
140
140
  }
@@ -168,7 +168,7 @@ class AsyncWebSocket {
168
168
  case WebSocket.CONNECTING: return 'opening';
169
169
  case WebSocket.OPEN: return 'open';
170
170
  /* istanbul ignore next */
171
- default: // TODO: [2021-12-01] throw new DetoxInternalError('...'); instead
171
+ default:
172
172
  return undefined;
173
173
  }
174
174
  }
@@ -187,14 +187,14 @@ class Client {
187
187
  this._whenAppIsReady = new Deferred();
188
188
 
189
189
  await this._whenAppIsConnected.promise;
190
- // TODO: optimize traffic (!) - we can just listen for 'ready' event
190
+ // TODO [2024-12-01]: optimize traffic (!) - we can just listen for 'ready' event
191
191
  // if app always sends it upon load completion. On iOS it works,
192
192
  // but not on Android. Afterwards, this will suffice:
193
193
  //
194
194
  // await this._whenAppIsReady.promise;
195
195
  }
196
196
 
197
- // TODO: move to else branch after the optimization
197
+ // TODO [2024-12-01]: move to else branch after the optimization ↑↑
198
198
  if (!this._whenAppIsReady.isResolved()) {
199
199
  this._whenAppIsReady = new Deferred();
200
200
  await this.sendAction(new actions.Ready());
@@ -41,7 +41,6 @@ class AttachedAndroidAllocDriver {
41
41
  async postAllocate(deviceCookie) {
42
42
  const { adbName } = deviceCookie;
43
43
 
44
- // TODO Also disable native animations?
45
44
  await this._adb.apiLevel(adbName);
46
45
  await this._adb.unlockScreen(adbName);
47
46
  }
@@ -5,7 +5,6 @@
5
5
 
6
6
  const _ = require('lodash');
7
7
 
8
- const Deferred = require('../../../../../utils/Deferred');
9
8
  const log = require('../../../../../utils/logger').child({ cat: 'device,device-allocation' });
10
9
 
11
10
  const { patchAvdSkinConfig } = require('./patchAvdSkinConfig');
@@ -7,7 +7,7 @@ class EmulatorVersionResolver {
7
7
  this.version = undefined;
8
8
  }
9
9
 
10
- async resolve(isHeadless = false) { // TODO Make isHeadless a config arg (i.e. through c'tor)?
10
+ async resolve(isHeadless = false) {
11
11
  if (!this.version) {
12
12
  this.version = await this._resolve(isHeadless);
13
13
  }
@@ -39,7 +39,6 @@ class SimulatorAllocDriver {
39
39
  async allocate(deviceConfig) {
40
40
  const deviceQuery = new SimulatorQuery(deviceConfig.device);
41
41
 
42
- // TODO Delegate this onto a well tested allocator class
43
42
  const udid = await this._deviceRegistry.registerDevice(async () => {
44
43
  return await this._findOrCreateDevice(deviceQuery);
45
44
  });
@@ -42,7 +42,7 @@ class AndroidEmulator extends DeviceAllocatorFactory {
42
42
  }
43
43
 
44
44
  class AndroidAttached extends DeviceAllocatorFactory {
45
- _createDriver({ detoxSession, detoxConfig }) {
45
+ _createDriver({ detoxSession }) {
46
46
  const serviceLocator = require('../../servicelocator/android');
47
47
  const adb = serviceLocator.adb;
48
48
  const DeviceRegistry = require('../../allocation/DeviceRegistry');
@@ -2,7 +2,7 @@
2
2
  const DeviceAllocatorFactory = require('./base');
3
3
 
4
4
  class IosSimulator extends DeviceAllocatorFactory {
5
- _createDriver({ detoxConfig, detoxSession, eventEmitter }) {
5
+ _createDriver({ detoxConfig, detoxSession }) {
6
6
  const AppleSimUtils = require('../../../devices/common/drivers/ios/tools/AppleSimUtils');
7
7
  const applesimutils = new AppleSimUtils();
8
8
 
@@ -8,7 +8,7 @@ const { escape } = require('../../../../../utils/pipeCommands');
8
8
  const DeviceHandle = require('../tools/DeviceHandle');
9
9
  const EmulatorHandle = require('../tools/EmulatorHandle');
10
10
 
11
- const INSTALL_TIMEOUT = 45000; // TODO Double check 45s makes sense
11
+ const INSTALL_TIMEOUT = 45000;
12
12
 
13
13
  class ADB {
14
14
  constructor() {
@@ -345,7 +345,6 @@ class ADB {
345
345
  return this.adbCmd(deviceId, `emu kill`);
346
346
  }
347
347
 
348
- // TODO refactor the whole thing so as to make usage of BinaryExec -- similar to EmulatorExec
349
348
  async adbCmd(deviceId, params, options = {}) {
350
349
  const serial = `${deviceId ? `-s ${deviceId}` : ''}`;
351
350
  const cmd = `"${this.adbBin}" ${serial} ${params}`;
@@ -1,6 +1,6 @@
1
1
  const DetoxRuntimeError = require('../../../../../errors/DetoxRuntimeError');
2
2
 
3
- const setupGuideHint = 'For further assistance, visit the Android setup guide: https://github.com/wix/Detox/blob/master/docs/Introduction.Android.md';
3
+ const setupGuideHint = 'For further assistance, visit the project setup guide (select the Android tabs): https://wix.github.io/Detox/docs/introduction/project-setup';
4
4
 
5
5
  class ApkValidator {
6
6
  constructor(aapt) {
@@ -1,5 +1,3 @@
1
- // TODO Tweak such that if apk's already exist on the device (need to store uniquely), they will not be resent (would optimize cloud, for example)
2
-
3
1
  class AppInstallHelper {
4
2
  constructor(adb, fileTransfer) {
5
3
  this._adb = adb;
@@ -33,6 +33,7 @@ class AppleSimUtils {
33
33
  args: `--list ${joinArgs(query)}`,
34
34
  retries: 1,
35
35
  statusLogs: listOptions.trying ? { trying: listOptions.trying } : undefined,
36
+ maxBuffer: 4 * 1024 * 1024,
36
37
  };
37
38
  const response = await this._execAppleSimUtils(options);
38
39
  const parsed = this._parseResponseFromAppleSimUtils(response);
@@ -280,7 +280,7 @@ class AndroidDriver extends DeviceDriverBase {
280
280
  throw new DetoxRuntimeError({
281
281
  message: `The test APK could not be found at path: '${testApkPath}'`,
282
282
  hint: 'Try running the detox build command, and make sure it was configured to execute a build command (e.g. \'./gradlew assembleAndroidTest\')' +
283
- '\nFor further assistance, visit the Android setup guide: https://github.com/wix/Detox/blob/master/docs/Introduction.Android.md',
283
+ '\nFor further assistance, visit the project setup guide (select the Android tabs): https://wix.github.io/Detox/docs/introduction/project-setup',
284
284
  });
285
285
  }
286
286
  return testApkPath;
@@ -11,7 +11,6 @@ const AndroidDriver = require('../AndroidDriver');
11
11
  * @property forceAdbInstall { Boolean }
12
12
  */
13
13
 
14
- // TODO Unit test coverage
15
14
  class EmulatorDriver extends AndroidDriver {
16
15
  /**
17
16
  * @param deps { EmulatorDriverDeps }
@@ -2,8 +2,6 @@ const RuntimeDeviceFactory = require('./base');
2
2
 
3
3
  class RuntimeDriverFactoryIos extends RuntimeDeviceFactory {
4
4
  _createDriverDependencies(commonDeps) {
5
- const { eventEmitter } = commonDeps;
6
-
7
5
  const AppleSimUtils = require('../../../devices/common/drivers/ios/tools/AppleSimUtils');
8
6
  const applesimutils = new AppleSimUtils();
9
7
 
@@ -247,10 +247,13 @@ class Element {
247
247
  return this.withAction('scroll', traceDescription, pixels, direction, startPositionX, startPositionY);
248
248
  }
249
249
 
250
- scrollTo(edge) {
250
+ scrollTo(edge, startPositionX = NaN, startPositionY = NaN) {
251
251
  if (!['left', 'right', 'top', 'bottom'].some(option => option === edge)) throw new Error('edge should be one of [left, right, top, bottom], but got ' + edge);
252
- const traceDescription = actionDescription.scrollTo(edge);
253
- return this.withAction('scrollTo', traceDescription, edge);
252
+ if (typeof startPositionX !== 'number') throw new Error('startPositionX should be a number, but got ' + (startPositionX + (' (' + (typeof startPositionX + ')'))));
253
+ if (typeof startPositionY !== 'number') throw new Error('startPositionY should be a number, but got ' + (startPositionY + (' (' + (typeof startPositionY + ')'))));
254
+
255
+ const traceDescription = actionDescription.scrollTo(edge, startPositionX, startPositionY);
256
+ return this.withAction('scrollTo', traceDescription, edge, startPositionX, startPositionY);
254
257
  }
255
258
 
256
259
  swipe(direction, speed = 'fast', normalizedSwipeOffset = NaN, normalizedStartingPointX = NaN, normalizedStartingPointY = NaN) {
@@ -60,8 +60,8 @@ class IPCClient {
60
60
  this._sessionState.patch(sessionState);
61
61
  }
62
62
 
63
- async allocateDevice() {
64
- const { deviceCookie, error } = deserializeObjectWithError(await this._emit('allocateDevice', {}));
63
+ async allocateDevice(deviceConfig) {
64
+ const { deviceCookie, error } = deserializeObjectWithError(await this._emit('allocateDevice', { deviceConfig }));
65
65
  if (error) {
66
66
  throw error;
67
67
  }
@@ -9,7 +9,7 @@ class IPCServer {
9
9
  * @param {import('./SessionState')} options.sessionState
10
10
  * @param {Detox.Logger} options.logger
11
11
  * @param {object} options.callbacks
12
- * @param {() => Promise<any>} options.callbacks.onAllocateDevice
12
+ * @param {(deviceConfig: DetoxInternals.RuntimeConfig['device']) => Promise<any>} options.callbacks.onAllocateDevice
13
13
  * @param {(cookie: any) => Promise<void>} options.callbacks.onDeallocateDevice
14
14
  */
15
15
  constructor({ sessionState, logger, callbacks }) {
@@ -40,7 +40,7 @@ class IPCServer {
40
40
  this._ipc.config.logger = (msg) => this._logger.trace(msg);
41
41
 
42
42
  await new Promise((resolve) => {
43
- // TODO: handle reject
43
+ // It is worth to handle rejection here some day
44
44
  this._ipc.serve(() => resolve());
45
45
  this._ipc.server.on('conductEarlyTeardown', this.onConductEarlyTeardown.bind(this));
46
46
  this._ipc.server.on('registerContext', this.onRegisterContext.bind(this));
@@ -104,11 +104,11 @@ class IPCServer {
104
104
  this._ipc.server.broadcast('sessionStateUpdate', newState);
105
105
  }
106
106
 
107
- async onAllocateDevice(_payload, socket) {
107
+ async onAllocateDevice({ deviceConfig }, socket) {
108
108
  let deviceCookie;
109
109
 
110
110
  try {
111
- deviceCookie = await this._callbacks.onAllocateDevice();
111
+ deviceCookie = await this._callbacks.onAllocateDevice(deviceConfig);
112
112
  this._ipc.server.emit(socket, 'allocateDeviceDone', { deviceCookie });
113
113
  } catch (error) {
114
114
  this._ipc.server.emit(socket, 'allocateDeviceDone', serializeObjectWithError({ error }));
@@ -47,7 +47,7 @@ class DetoxContext {
47
47
  this[$sessionState] = this[$restoreSessionState]();
48
48
 
49
49
  /**
50
- * @type {DetoxLogger & Detox.Logger}
50
+ * @type {import('../logger/').DetoxLogger & Detox.Logger}
51
51
  */
52
52
  this[symbols.logger] = new DetoxLogger({
53
53
  file: temporary.for.jsonl(`${this[$sessionState].id}.${process.pid}`),
@@ -152,10 +152,10 @@ class DetoxContext {
152
152
  }
153
153
 
154
154
  /** @abstract */
155
- async [symbols.allocateDevice]() {}
155
+ async [symbols.allocateDevice](_deviceConfig) {}
156
156
 
157
157
  /** @abstract */
158
- async [symbols.deallocateDevice]() {}
158
+ async [symbols.deallocateDevice](_deviceCookie) {}
159
159
 
160
160
  async [symbols.uninstallWorker]() {
161
161
  try {