@xenon-device-management/xenon 1.17.3 → 1.17.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/lib/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@xenon-device-management/xenon",
3
- "version": "1.17.3",
3
+ "version": "1.17.4",
4
4
  "description": "Xenon - Intelligent Mobile Infrastructure. A self-healing device orchestration platform for Appium.",
5
5
  "main": "./lib/src/index.js",
6
6
  "exports": {
@@ -51,8 +51,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
51
51
  return (mod && mod.__esModule) ? mod : { "default": mod };
52
52
  };
53
53
  Object.defineProperty(exports, "__esModule", { value: true });
54
- exports.SessionLifecycleService = exports.XCTRUNNER_SUFFIX = void 0;
55
- exports.stripXctrunnerSuffix = stripXctrunnerSuffix;
54
+ exports.SessionLifecycleService = void 0;
56
55
  const typedi_1 = require("typedi");
57
56
  const uuid_1 = require("uuid");
58
57
  const lodash_1 = __importDefault(require("lodash"));
@@ -89,26 +88,6 @@ const commandsQueueGuard = new async_lock_1.default();
89
88
  // Serializes concurrent deleteSession cleanup for the same sessionId so
90
89
  // that onSessionStopped events don't fire twice if two clients race.
91
90
  const sessionCleanupLock = new async_lock_1.default();
92
- /** The suffix appium-webdriveragent appends to `updatedWDABundleId`. */
93
- exports.XCTRUNNER_SUFFIX = '.xctrunner';
94
- /**
95
- * Normalise an installed WebDriverAgent bundle id for `appium:updatedWDABundleId`.
96
- *
97
- * The driver derives its keep-list entry as
98
- * `${updatedWDABundleId ?? WDA_RUNNER_BUNDLE_ID}${'.xctrunner'}`, so the
99
- * capability wants the id *without* the runner suffix — it puts it back. Handing
100
- * it the id exactly as installed yields `…xctrunner.xctrunner`, which matches
101
- * nothing, and the app the keep-list was meant to protect is uninstalled.
102
- *
103
- * Only a trailing occurrence is removed: a bundle id may legitimately contain
104
- * the word elsewhere, and `String.replace` without an anchor would cut the
105
- * first one it found.
106
- */
107
- function stripXctrunnerSuffix(bundleId) {
108
- return bundleId.endsWith(exports.XCTRUNNER_SUFFIX)
109
- ? bundleId.slice(0, -exports.XCTRUNNER_SUFFIX.length)
110
- : bundleId;
111
- }
112
91
  let SessionLifecycleService = class SessionLifecycleService {
113
92
  constructor() {
114
93
  this.logger = logger_1.default.scope('SessionLifecycleService');
@@ -340,8 +319,7 @@ let SessionLifecycleService = class SessionLifecycleService {
340
319
  const wdaUrl = `http://127.0.0.1:${streamInfo.wdaPort}`;
341
320
  yield (0, device_service_1.updateDeviceProgress)(device.udid, device.host, 'WDA active, finalizing session...');
342
321
  yield new Promise((resolve) => setTimeout(resolve, 2000));
343
- const bundleId = yield streamService.detectWDABundleId(device.udid);
344
- this.injectWDAUrl(caps, wdaUrl, bundleId);
322
+ this.injectWDAUrl(caps, wdaUrl);
345
323
  }
346
324
  catch (err) {
347
325
  this.logger.warn(`⚠️ Artisan WDA: Pre-session boot failed: ${err.message}`);
@@ -350,12 +328,7 @@ let SessionLifecycleService = class SessionLifecycleService {
350
328
  }
351
329
  else if (isWdaActive) {
352
330
  const wdaUrl = `http://127.0.0.1:${streamStatus.wdaPort}`;
353
- // The bundle id matters as much here as on the branch above, and this
354
- // is the branch that runs in the ordinary case — a preview already
355
- // open when a test starts. Omitting it told Appium to manage "the
356
- // preinstalled WDA" without saying which, and it removed ours.
357
- const bundleId = yield streamService.detectWDABundleId(device.udid);
358
- this.injectWDAUrl(caps, wdaUrl, bundleId);
331
+ this.injectWDAUrl(caps, wdaUrl);
359
332
  }
360
333
  const hasWdaUrl = lodash_1.default.has(caps.alwaysMatch, 'appium:webDriverAgentUrl') ||
361
334
  lodash_1.default.has((_a = caps.firstMatch) === null || _a === void 0 ? void 0 : _a[0], 'appium:webDriverAgentUrl');
@@ -368,7 +341,7 @@ let SessionLifecycleService = class SessionLifecycleService {
368
341
  }
369
342
  });
370
343
  }
371
- injectWDAUrl(caps, wdaUrl, bundleId) {
344
+ injectWDAUrl(caps, wdaUrl) {
372
345
  var _a, _b, _c;
373
346
  // W3C capability rules forbid a property from appearing in BOTH alwaysMatch
374
347
  // and a firstMatch entry; appium rejects the session with "property
@@ -380,44 +353,35 @@ let SessionLifecycleService = class SessionLifecycleService {
380
353
  if (!target)
381
354
  return;
382
355
  const other = target === caps.alwaysMatch ? (_c = caps.firstMatch) === null || _c === void 0 ? void 0 : _c[0] : caps.alwaysMatch;
356
+ // The URL, and only the URL. Xenon owns this WebDriverAgent: it launched
357
+ // it through go-ios and keeps the XCTest session alive for the stream. The
358
+ // driver is a guest here, and `webDriverAgentUrl` is precisely how you say
359
+ // that — `selectWdaStartupStrategyName` returns 'existing-url' on it before
360
+ // considering anything else, and that strategy's own quit() reads
361
+ // "Stopping neither xcodebuild nor XCTest session since WDA lifecycle is
362
+ // not managed by this driver".
383
363
  target['appium:webDriverAgentUrl'] = wdaUrl;
384
- // `usePreinstalledWDA` and `updatedWDABundleId` travel together or not at
385
- // all. On its own, the first one sends the driver down
386
- // `preparePreinstalled`, which calls `cleanupApps(driver,
387
- // [driver.wda.bundleIdForXctest])` — that removes every installed app
388
- // whose CFBundleName is WebDriverAgentRunner except the one bundle id it
389
- // was told to keep. Without `updatedWDABundleId` that keep-list is the
390
- // driver's own default, `com.facebook.WebDriverAgentRunner.xctrunner`, so
391
- // the WDA Xenon just launched (`com.qasecret.…` here) is not on it and is
392
- // uninstalled from the device mid-session. Observed twice on a real
393
- // iPhone: "Removing WebDriverAgent runner app
394
- // 'com.qasecret.WebDriverAgentRunner.xctrunner'", after which every iOS
395
- // feature fails with "WebDriverAgent is not installed" until someone
396
- // re-signs and reinstalls it by hand.
364
+ // `usePreinstalledWDA` is removed, never added, and this is the whole fix.
397
365
  //
398
- // `webDriverAgentUrl` alone is enough to reuse a running WDA, and it does
399
- // not enter that cleanup path — so when the bundle id is unknown, the safe
400
- // move is to say less, not more.
366
+ // It does not change which strategy runs — the URL already won that — it
367
+ // only makes `launchOnce` call `preparePreinstalled` first, which is:
401
368
  //
402
- // The suffix matters as much as the value. The keep-list entry is
403
- // `bundleIdForXctest`, which the driver builds as
404
- // `${updatedWDABundleId ?? WDA_RUNNER_BUNDLE_ID}${'.xctrunner'}` — so this
405
- // capability wants the id WITHOUT the runner suffix, and the driver adds
406
- // it back. Passing the installed id verbatim produced a keep-list of
407
- // `com.qasecret.WebDriverAgentRunner.xctrunner.xctrunner`, which matched
408
- // nothing on the device, and the real runner was uninstalled anyway. That
409
- // is the same normalisation the driver applies to its own prebuilt path:
410
- // `updatedWDABundleId = candidateBundleId.replace('.xctrunner', '')`.
411
- if (bundleId) {
412
- target['appium:usePreinstalledWDA'] = true;
413
- target['appium:updatedWDABundleId'] = stripXctrunnerSuffix(bundleId);
414
- }
415
- else {
416
- logger_1.default.warn(`[Xenon] Could not identify the WebDriverAgent bundle on this device; reusing it by URL only. ` +
417
- `Sending usePreinstalledWDA without a bundle id would let the driver uninstall it.`);
418
- delete target['appium:usePreinstalledWDA'];
419
- delete target['appium:updatedWDABundleId'];
420
- }
369
+ // await driver.mobileKillApp(driver.wda.bundleIdForXctest);
370
+ // await cleanupApps(driver, [driver.wda.bundleIdForXctest]);
371
+ //
372
+ // Kill the app, then uninstall every WebDriverAgentRunner not on a
373
+ // one-entry keep-list. Against a WDA that Xenon is hosting that is
374
+ // exactly wrong twice over, and both halves were observed on a real
375
+ // iPhone: the uninstall as "Removing WebDriverAgent runner app
376
+ // 'com.qasecret.WebDriverAgentRunner.xctrunner'", leaving the device with
377
+ // no WDA until someone re-signs one by hand; and the kill as the driver's
378
+ // own next request failing with ECONNRESET, because go-ios's runwda was
379
+ // gone while iproxy still held the port.
380
+ //
381
+ // Getting the keep-list right only converts the uninstall into the kill.
382
+ // The driver must not be invited to manage this app at all.
383
+ delete target['appium:usePreinstalledWDA'];
384
+ delete target['appium:updatedWDABundleId'];
421
385
  // These conflict with a pre-installed WDA URL — strip from both buckets.
422
386
  for (const bucket of [target, other]) {
423
387
  if (!bucket)
@@ -19,34 +19,31 @@ describe('SessionLifecycleService.injectWDAUrl — W3C capability composition',
19
19
  alwaysMatch: { 'appium:automationName': 'XCUITest' },
20
20
  firstMatch: [{ 'appium:udid': 'abc' }],
21
21
  };
22
- injectWDAUrl(caps, URL, 'com.qasecret.WebDriverAgentRunner');
22
+ injectWDAUrl(caps, URL);
23
23
  // Present in alwaysMatch...
24
24
  expect(caps.alwaysMatch['appium:webDriverAgentUrl']).to.equal(URL);
25
- expect(caps.alwaysMatch['appium:usePreinstalledWDA']).to.equal(true);
26
- expect(caps.alwaysMatch['appium:updatedWDABundleId']).to.equal('com.qasecret.WebDriverAgentRunner');
27
25
  // ...and NOT in firstMatch — the bug was duplicating into both, which appium
28
26
  // rejects with "property 'webDriverAgentUrl' should not exist on both
29
27
  // primary and secondary object".
30
28
  expect(caps.firstMatch[0]).to.not.have.property('appium:webDriverAgentUrl');
31
- expect(caps.firstMatch[0]).to.not.have.property('appium:usePreinstalledWDA');
32
- expect(caps.firstMatch[0]).to.not.have.property('appium:updatedWDABundleId');
33
29
  });
34
30
  it('falls back to firstMatch[0] when there is no alwaysMatch', () => {
35
31
  const caps = { firstMatch: [{ 'appium:udid': 'abc' }] };
36
- injectWDAUrl(caps, URL, 'com.qasecret.WebDriverAgentRunner');
32
+ injectWDAUrl(caps, URL);
37
33
  expect(caps.firstMatch[0]['appium:webDriverAgentUrl']).to.equal(URL);
38
- expect(caps.firstMatch[0]['appium:usePreinstalledWDA']).to.equal(true);
39
34
  });
40
- it('does not claim a preinstalled WDA it cannot name, in either bucket', () => {
41
- // This case used to assert the opposite, and the behaviour it pinned
42
- // uninstalled WebDriverAgent from the device: `usePreinstalledWDA` without
43
- // `updatedWDABundleId` sends the driver into `cleanupApps`, whose keep-list
44
- // is then its own default bundle id rather than ours. See
35
+ it('never invites the driver to manage the WDA, in either bucket', () => {
36
+ // Two earlier versions of this case asserted the opposite, and each
37
+ // pinned a behaviour that damaged a real device: `usePreinstalledWDA`
38
+ // makes `launchOnce` run `preparePreinstalled`, which kills the runner
39
+ // and uninstalls every sibling not on a one-entry keep-list. Xenon hosts
40
+ // this WDA itself, so the driver must never be invited to manage it. See
45
41
  // test/unit/wda-cap-injection.spec.ts for the full chain.
46
42
  const caps = { firstMatch: [{ 'appium:udid': 'abc' }] };
47
43
  injectWDAUrl(caps, URL);
48
44
  expect(caps.firstMatch[0]['appium:webDriverAgentUrl']).to.equal(URL);
49
45
  expect(caps.firstMatch[0]).to.not.have.property('appium:usePreinstalledWDA');
46
+ expect(caps.firstMatch[0]).to.not.have.property('appium:updatedWDABundleId');
50
47
  });
51
48
  it('scrubs conflicting WDA caps from both buckets', () => {
52
49
  const caps = {
@@ -4,103 +4,90 @@ require("reflect-metadata");
4
4
  const chai_1 = require("chai");
5
5
  const SessionLifecycleService_1 = require("../../src/services/SessionLifecycleService");
6
6
  /**
7
- * `appium:usePreinstalledWDA` sends appium-xcuitest-driver down
8
- * `preparePreinstalled`, which calls
9
- * `cleanupApps(driver, [driver.wda.bundleIdForXctest])` — removing every
10
- * installed app whose CFBundleName is WebDriverAgentRunner except the single
11
- * bundle id on that keep-list.
7
+ * Xenon owns this WebDriverAgent. It launches it through go-ios and keeps the
8
+ * XCTest session alive for the live stream; the Appium driver is a guest.
12
9
  *
13
- * Without `appium:updatedWDABundleId`, that keep-list holds the driver's own
14
- * default (`com.facebook.WebDriverAgentRunner.xctrunner`), so a differently
15
- * signed WDA — which is what Xenon launches — is not on it and gets
16
- * uninstalled from the device mid-session. Observed twice on a real iPhone,
17
- * logged verbatim by the driver as:
10
+ * `appium:webDriverAgentUrl` is exactly how that is expressed —
11
+ * `selectWdaStartupStrategyName` returns 'existing-url' on it before
12
+ * considering anything else, and that strategy's `quit()` reads "Stopping
13
+ * neither xcodebuild nor XCTest session since WDA lifecycle is not managed by
14
+ * this driver".
18
15
  *
19
- * Removing WebDriverAgent runner app 'com.qasecret.WebDriverAgentRunner.xctrunner'
16
+ * `appium:usePreinstalledWDA` invites the opposite. It does not change the
17
+ * strategy — the URL already won — it only makes `launchOnce` run
18
+ * `preparePreinstalled` first:
20
19
  *
21
- * after which every iOS feature fails with "WebDriverAgent is not installed"
22
- * until it is re-signed and reinstalled by hand.
20
+ * await driver.mobileKillApp(driver.wda.bundleIdForXctest);
21
+ * await cleanupApps(driver, [driver.wda.bundleIdForXctest]);
23
22
  *
24
- * So the two capabilities are a pair. These tests pin that they can never be
25
- * emitted apart.
23
+ * Both halves were observed against a real iPhone: the uninstall as "Removing
24
+ * WebDriverAgent runner app 'com.qasecret.WebDriverAgentRunner.xctrunner'",
25
+ * leaving the device with no WDA at all, and the kill as the driver's own next
26
+ * request failing with ECONNRESET because go-ios's runwda was gone while
27
+ * iproxy still held the port.
26
28
  */
27
29
  describe('WDA capability injection', () => {
28
30
  // The method is private by design; this is the one place its contract is
29
31
  // asserted, so it is reached deliberately rather than widening the API.
30
- const inject = (caps, url, bundleId) => SessionLifecycleService_1.SessionLifecycleService.prototype.injectWDAUrl.call(Object.create(SessionLifecycleService_1.SessionLifecycleService.prototype), caps, url, bundleId);
32
+ const inject = (caps, url) => SessionLifecycleService_1.SessionLifecycleService.prototype.injectWDAUrl.call(Object.create(SessionLifecycleService_1.SessionLifecycleService.prototype), caps, url);
31
33
  const WDA_URL = 'http://127.0.0.1:8100';
32
- const BUNDLE = 'com.qasecret.WebDriverAgentRunner.xctrunner';
33
- it('names the bundle whenever it claims a preinstalled WDA', () => {
34
+ it('reuses the running WDA by URL', () => {
34
35
  const caps = { alwaysMatch: {}, firstMatch: [{}] };
35
- inject(caps, WDA_URL, BUNDLE);
36
- (0, chai_1.expect)(caps.alwaysMatch['appium:usePreinstalledWDA']).to.equal(true);
37
- (0, chai_1.expect)(caps.alwaysMatch['appium:updatedWDABundleId']).to.equal('com.qasecret.WebDriverAgentRunner');
38
- });
39
- it('sends the id the driver will rebuild into the installed one', () => {
40
- // This is the whole contract, and getting it wrong is not a near miss:
41
- // the driver's keep-list is `updatedWDABundleId + '.xctrunner'`, so an
42
- // id that is off by that suffix protects a bundle that does not exist
43
- // and the real runner is uninstalled from the device.
44
- const caps = { alwaysMatch: {}, firstMatch: [{}] };
45
- inject(caps, WDA_URL, BUNDLE);
46
- const keepListEntry = caps.alwaysMatch['appium:updatedWDABundleId'] + SessionLifecycleService_1.XCTRUNNER_SUFFIX;
47
- (0, chai_1.expect)(keepListEntry).to.equal(BUNDLE);
48
- });
49
- it('leaves an id that already lacks the suffix alone', () => {
50
- const caps = { alwaysMatch: {}, firstMatch: [{}] };
51
- inject(caps, WDA_URL, 'com.qasecret.WebDriverAgentRunner');
52
- (0, chai_1.expect)(caps.alwaysMatch['appium:updatedWDABundleId'] + SessionLifecycleService_1.XCTRUNNER_SUFFIX).to.equal(BUNDLE);
53
- });
54
- it('never claims a preinstalled WDA it cannot name', () => {
55
- // The destructive combination. `webDriverAgentUrl` alone still reuses the
56
- // running WDA and does not enter the cleanup path at all.
57
- const caps = { alwaysMatch: {}, firstMatch: [{}] };
58
- inject(caps, WDA_URL, null);
36
+ inject(caps, WDA_URL);
59
37
  (0, chai_1.expect)(caps.alwaysMatch['appium:webDriverAgentUrl']).to.equal(WDA_URL);
60
- (0, chai_1.expect)(caps.alwaysMatch['appium:usePreinstalledWDA']).to.equal(undefined);
61
- (0, chai_1.expect)(caps.alwaysMatch['appium:updatedWDABundleId']).to.equal(undefined);
62
38
  });
63
- it('never claims one when the bundle id is simply absent', () => {
39
+ it('never invites the driver to manage the app', () => {
64
40
  const caps = { alwaysMatch: {}, firstMatch: [{}] };
65
41
  inject(caps, WDA_URL);
66
- (0, chai_1.expect)(caps.alwaysMatch['appium:usePreinstalledWDA']).to.equal(undefined);
42
+ (0, chai_1.expect)(caps.alwaysMatch).to.not.have.property('appium:usePreinstalledWDA');
43
+ (0, chai_1.expect)(caps.alwaysMatch).to.not.have.property('appium:updatedWDABundleId');
67
44
  });
68
- it('does not leave a stale pairing behind from the caller', () => {
69
- // A caller that already set the flag must not be able to smuggle it past
70
- // the check when the bundle id is unknown.
45
+ it('strips the invitation even when the caller supplied it', () => {
46
+ // Honouring it would kill the WDA Xenon is hosting. On this path the
47
+ // capability is not the caller's to give.
71
48
  const caps = {
72
- alwaysMatch: { 'appium:usePreinstalledWDA': true, 'appium:updatedWDABundleId': 'stale' },
49
+ alwaysMatch: { 'appium:usePreinstalledWDA': true, 'appium:updatedWDABundleId': 'com.x.WDA' },
73
50
  firstMatch: [{}],
74
51
  };
75
- inject(caps, WDA_URL, null);
76
- (0, chai_1.expect)(caps.alwaysMatch['appium:usePreinstalledWDA']).to.equal(undefined);
77
- (0, chai_1.expect)(caps.alwaysMatch['appium:updatedWDABundleId']).to.equal(undefined);
52
+ inject(caps, WDA_URL);
53
+ (0, chai_1.expect)(caps.alwaysMatch).to.not.have.property('appium:usePreinstalledWDA');
54
+ (0, chai_1.expect)(caps.alwaysMatch).to.not.have.property('appium:updatedWDABundleId');
55
+ });
56
+ it('strips it from the other bucket too', () => {
57
+ const caps = {
58
+ alwaysMatch: {},
59
+ firstMatch: [{ 'appium:usePreinstalledWDA': true, 'appium:updatedWDABundleId': 'com.x.WDA' }],
60
+ };
61
+ inject(caps, WDA_URL);
62
+ (0, chai_1.expect)(caps.firstMatch[0]).to.not.have.property('appium:usePreinstalledWDA');
63
+ (0, chai_1.expect)(caps.firstMatch[0]).to.not.have.property('appium:updatedWDABundleId');
78
64
  });
79
- it('keeps the injected keys out of the other capability bucket', () => {
65
+ it('keeps the injected url out of the other capability bucket', () => {
80
66
  // W3C forbids a property in both alwaysMatch and a firstMatch entry;
81
67
  // appium rejects the whole session if it happens.
82
68
  const caps = {
83
69
  alwaysMatch: {},
84
- firstMatch: [{ 'appium:webDriverAgentUrl': 'http://stale', 'appium:usePreinstalledWDA': true }],
70
+ firstMatch: [{ 'appium:webDriverAgentUrl': 'http://stale' }],
85
71
  };
86
- inject(caps, WDA_URL, BUNDLE);
87
- (0, chai_1.expect)(caps.firstMatch[0]['appium:webDriverAgentUrl']).to.equal(undefined);
88
- (0, chai_1.expect)(caps.firstMatch[0]['appium:usePreinstalledWDA']).to.equal(undefined);
72
+ inject(caps, WDA_URL);
73
+ (0, chai_1.expect)(caps.firstMatch[0]).to.not.have.property('appium:webDriverAgentUrl');
89
74
  (0, chai_1.expect)(caps.alwaysMatch['appium:webDriverAgentUrl']).to.equal(WDA_URL);
90
75
  });
91
- it('only strips a trailing suffix, never one embedded in the id', () => {
92
- (0, chai_1.expect)((0, SessionLifecycleService_1.stripXctrunnerSuffix)('com.x.xctrunner.WebDriverAgentRunner.xctrunner')).to.equal('com.x.xctrunner.WebDriverAgentRunner');
93
- (0, chai_1.expect)((0, SessionLifecycleService_1.stripXctrunnerSuffix)('com.x.WebDriverAgentRunner')).to.equal('com.x.WebDriverAgentRunner');
76
+ it('falls back to firstMatch[0] when there is no alwaysMatch', () => {
77
+ const caps = { firstMatch: [{ 'appium:udid': 'abc' }] };
78
+ inject(caps, WDA_URL);
79
+ (0, chai_1.expect)(caps.firstMatch[0]['appium:webDriverAgentUrl']).to.equal(WDA_URL);
80
+ (0, chai_1.expect)(caps.firstMatch[0]).to.not.have.property('appium:usePreinstalledWDA');
94
81
  });
95
82
  it('strips the caps that conflict with reusing a WDA by URL', () => {
96
83
  const caps = {
97
84
  alwaysMatch: { 'appium:wdaLocalPort': 8100, 'appium:derivedDataPath': '/tmp/dd' },
98
85
  firstMatch: [{ 'appium:mjpegServerPort': 9100, 'appium:usePrebuiltWDA': true }],
99
86
  };
100
- inject(caps, WDA_URL, BUNDLE);
101
- (0, chai_1.expect)(caps.alwaysMatch['appium:wdaLocalPort']).to.equal(undefined);
102
- (0, chai_1.expect)(caps.alwaysMatch['appium:derivedDataPath']).to.equal(undefined);
103
- (0, chai_1.expect)(caps.firstMatch[0]['appium:mjpegServerPort']).to.equal(undefined);
104
- (0, chai_1.expect)(caps.firstMatch[0]['appium:usePrebuiltWDA']).to.equal(undefined);
87
+ inject(caps, WDA_URL);
88
+ (0, chai_1.expect)(caps.alwaysMatch).to.not.have.property('appium:wdaLocalPort');
89
+ (0, chai_1.expect)(caps.alwaysMatch).to.not.have.property('appium:derivedDataPath');
90
+ (0, chai_1.expect)(caps.firstMatch[0]).to.not.have.property('appium:mjpegServerPort');
91
+ (0, chai_1.expect)(caps.firstMatch[0]).to.not.have.property('appium:usePrebuiltWDA');
105
92
  });
106
93
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@xenon-device-management/xenon",
3
- "version": "1.17.3",
3
+ "version": "1.17.4",
4
4
  "description": "Xenon - Intelligent Mobile Infrastructure. A self-healing device orchestration platform for Appium.",
5
5
  "main": "./lib/src/index.js",
6
6
  "exports": {