@testim/testim-cli 3.266.0 → 3.268.0

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/testRunStatus.js CHANGED
@@ -233,7 +233,11 @@ class RunStatus {
233
233
  return this.testStartReport(test, executionId, testRetryKey);
234
234
  }
235
235
 
236
- onGridSlot(executionId, resultId, gridInfo) {
236
+ /**
237
+ * @param {string} resultId
238
+ * @param {Awaited<ReturnType<typeof import('./services/gridService')['getGridSlot']>>} gridInfo
239
+ */
240
+ onGridSlot(resultId, gridInfo) {
237
241
  const test = this.getTestResult(resultId);
238
242
  test.config.gridInfo = Object.assign({}, gridInfo, { key: undefined, user: undefined });
239
243
  logger.info('on get grid info', { gridInfo: test.config.gridInfo });
@@ -264,6 +268,10 @@ class RunStatus {
264
268
  return result.success ? constants.runnerTestStatus.PASSED : constants.runnerTestStatus.FAILED;
265
269
  }
266
270
 
271
+ /**
272
+ * @param {number} wid
273
+ * @param {Parameters<ConstructorParameters<typeof import('./workers/BaseWorker')>[7]>[1]} resultId
274
+ */
267
275
  onTestIgnored(wid, resultId) {
268
276
  const test = this.getTestResult(resultId);
269
277
  reporter.onTestIgnored(wid, test, `test in ${constants.testStatus.QUARANTINE}`);
@@ -1,5 +1,4 @@
1
1
  /* eslint-disable no-console */
2
- const Promise = require('bluebird');
3
2
  const semver = require('semver');
4
3
  const config = require('./commons/config');
5
4
  const fs = require('fs');
@@ -7,10 +6,9 @@ const logger = require('./commons/logger').getLogger('npm-driver');
7
6
  const localRunnerCache = require('./commons/runnerFileCache');
8
7
  const npmWrapper = require('./commons/npmWrapper');
9
8
  const chalk = require('chalk');
9
+ const utils = require('./utils');
10
10
 
11
- function getNpmVersion(packName) {
12
- return Promise.resolve(npmWrapper.getLatestPackageVersion(packName));
13
- }
11
+ const getNpmVersion = localRunnerCache.memoize(() => npmWrapper.getLatestPackageVersion('@testim/testim-cli'), 'getNpmVersion');
14
12
 
15
13
  function getPackageVersion() {
16
14
  try {
@@ -29,22 +27,21 @@ function getPackageVersion() {
29
27
  }
30
28
  }
31
29
 
32
- function checkNpmVersion() {
30
+ async function checkNpmVersion() {
33
31
  if (config.IS_ON_PREM) {
34
- return Promise.resolve();
32
+ return;
33
+ }
34
+ try {
35
+ const latestVersion = await utils.promiseTimeout(getNpmVersion('@testim/testim-cli'), 5000, 'The API call to NPM timed out');
36
+ const packVersion = getPackageVersion();
37
+ if (packVersion && semver.lt(packVersion, latestVersion)) {
38
+ console.log(chalk.yellow(
39
+ `Warning: You are using version ${packVersion}, a newer version is available. To update please run npm install (npm install -g @testim/testim-cli)`)
40
+ );
41
+ }
42
+ } catch (err) {
43
+ logger.warn('Failed to get NPM version', { err });
35
44
  }
36
- return localRunnerCache.memoize(() => getNpmVersion('@testim/testim-cli')
37
- .timeout(5000, 'The API call to NPM timed out')
38
- .then(latestVersion => {
39
- const packVersion = getPackageVersion();
40
- if (packVersion && semver.lt(packVersion, latestVersion)) {
41
- console.log(chalk.yellow(
42
- `Warning: You are using version ${packVersion}, a newer version is available. To update please run npm install (npm install -g @testim/testim-cli)`)
43
- );
44
- }
45
- })
46
- .catch(err => logger.warn('Failed to get NPM version', { err }))
47
- .then(() => true), 'checkNpmVersion');
48
45
  }
49
46
 
50
47
  module.exports = {
@@ -27,6 +27,12 @@ const { SETUP_TIMEOUT, NETWORK_ERROR, GRID_ERROR, BROWSER_CLOSED, SELENIUM_ERROR
27
27
  const DELAY_BETWEEN_TESTS = ms('1s');
28
28
  let ordinal = 1;
29
29
 
30
+ /**
31
+ * @param {string} testId
32
+ * @param {string} testName
33
+ * @param {string} resultId
34
+ * @param {string} reason
35
+ */
30
36
  function buildFailureResult(testId, testName, resultId, reason) {
31
37
  return {
32
38
  testId,
@@ -43,10 +49,10 @@ class BaseWorker {
43
49
  * @param {import('../runOptions').RunnerOptions} options
44
50
  * @param {string=} customExtensionLocalLocation
45
51
  * @param {string} executionId
46
- * @param {Function} onTestStarted
47
- * @param {Function} onTestCompleted
48
- * @param {Function} onGridSlot
49
- * @param {Function} onTestIgnored
52
+ * @param {(workerId: number, testId: string, resultId: string, isRerun: boolean | undefined, testRetryKey: `${number}:${number}` ) => Promise<any>} onTestStarted
53
+ * @param {(workerId: number, testId: string, testResult: any, sessionId: string, shouldRerun: boolean | undefined) => Promise<void>} onTestCompleted
54
+ * @param {import('../testRunStatus')['onGridSlot']} onGridSlot
55
+ * @param {(workerId: number, testResult: { name: string; testId: string; resultId: string; runnerStatus: 'SKIPPED'; testStatus: 'quarantine' }) => void} onTestIgnored
50
56
  * @param {boolean=} releaseSlotOnTestFinished
51
57
  */
52
58
  constructor(executionQueue, options, customExtensionLocalLocation, executionId, onTestStarted, onTestCompleted, onGridSlot, onTestIgnored, releaseSlotOnTestFinished = true) {
@@ -75,10 +81,17 @@ class BaseWorker {
75
81
  return ordinal++;
76
82
  }
77
83
 
78
- getGridSlot(browser, testRunHandler) {
79
- return gridService.getGridSlot(browser, testRunHandler.getExecutionId(), testRunHandler.getTestResultId(), this.onGridSlot, this.options, this.id);
84
+ /**
85
+ * @param {string} browser
86
+ * @param {import('../testRunHandler')} testRunHandler
87
+ */
88
+ async getGridSlot(browser, testRunHandler) {
89
+ const slot = await gridService.getGridSlot(browser, testRunHandler.executionId, this.options, this.id);
90
+ this.onGridSlot(testRunHandler.testResultId, slot);
91
+ return slot;
80
92
  }
81
93
 
94
+ /** @param {import('../testRunHandler')} testRunHandler */
82
95
  async getSlotOnce(testRunHandler) {
83
96
  const { browserValue } = this.testRunConfig;
84
97
  reporter.onGetSlot(this.id, browserValue || 'chrome');
@@ -86,6 +99,10 @@ class BaseWorker {
86
99
  return gridInfo;
87
100
  }
88
101
 
102
+ /**
103
+ * @abstract
104
+ * @returns {import('../player/appiumTestPlayer') | import('../player/seleniumTestPlayer') | import('../player/extensionTestPlayer') | import('../player/chromeLauncherTestPlayer')}
105
+ */
89
106
  initPlayer() {
90
107
  throw new NotImplementedError(true);
91
108
  }
@@ -94,30 +111,35 @@ class BaseWorker {
94
111
  throw new NotImplementedError(true);
95
112
  }
96
113
 
114
+ /**
115
+ * @param {import('../testRunHandler')} testRunHandler
116
+ * @param {ReturnType<typeof this['initPlayer']>} player
117
+ */
97
118
  async runTestOnce(testRunHandler, player) {
98
- testRunHandler.setSessionId(player.getSessionId());
119
+ testRunHandler.sessionId = player.getSessionId();
99
120
  logger.info('Test run started', {
100
- testId: testRunHandler.getTestId(),
101
- resultId: testRunHandler.getTestResultId(),
121
+ testId: testRunHandler.testId,
122
+ resultId: testRunHandler.testResultId,
102
123
  seleniumSession: player.getSessionId(),
103
124
  });
104
125
 
105
126
  return await testRunHandler.clearTestResult();
106
127
  }
107
128
 
129
+ /** @param {import('../testRunHandler')} testRunHandler */
108
130
  handleQuarantine(testRunHandler) {
109
- if (utils.isQuarantineAndNotRemoteRun({ testStatus: testRunHandler.getTestStatus() }, this.options)) {
110
- const testResult = {
111
- name: testRunHandler.getTestName(),
112
- testId: testRunHandler.getTestId(),
113
- resultId: testRunHandler.getTestResultId(),
114
- runnerStatus: runnerTestStatus.SKIPPED,
115
- testStatus: testRunHandler.getTestStatus(),
116
- };
117
- this.onTestIgnored(this.id, testResult);
118
- return testResult;
131
+ if (!utils.isQuarantineAndNotRemoteRun({ testStatus: testRunHandler.testStatus }, this.options)) {
132
+ return undefined;
119
133
  }
120
- return undefined;
134
+ const testResult = {
135
+ name: testRunHandler.testName,
136
+ testId: testRunHandler.testId,
137
+ resultId: testRunHandler.testResultId,
138
+ runnerStatus: runnerTestStatus.SKIPPED,
139
+ testStatus: testRunHandler.testStatus,
140
+ };
141
+ this.onTestIgnored(this.id, testResult);
142
+ return testResult;
121
143
  }
122
144
 
123
145
  setSessionTimeout() {
@@ -127,6 +149,10 @@ class BaseWorker {
127
149
  return Math.max(this.lambdatestService.getSessionTimeout, this.options.getSessionTimeout);
128
150
  }
129
151
 
152
+ /**
153
+ * @param {import('../testRunHandler')} testRunHandler
154
+ * @param {string=} customExtensionLocalLocation
155
+ */
130
156
  async getTestPlayer(testRunHandler, customExtensionLocalLocation) {
131
157
  const projectId = this.userData?.projectId;
132
158
  let testPlayer;
@@ -202,6 +228,11 @@ class BaseWorker {
202
228
  return testPlayer;
203
229
  }
204
230
 
231
+ /**
232
+ * @param {import('../testRunHandler')} testRunHandler
233
+ * @param {string=} customExtensionLocalLocation
234
+ * @param {boolean=} shouldRerun
235
+ */
205
236
  async runTest(testRunHandler, customExtensionLocalLocation, shouldRerun) {
206
237
  perf.log('inside runTest');
207
238
  const projectId = this.userData?.projectId;
@@ -211,7 +242,7 @@ class BaseWorker {
211
242
  }
212
243
 
213
244
  perf.log('before runTest onTestStarted');
214
- const test = await this.onTestStarted(this.id, testRunHandler.getTestId(), testRunHandler.getTestResultId(), shouldRerun, testRunHandler.getRetryKey());
245
+ const test = await this.onTestStarted(this.id, testRunHandler.testId, testRunHandler.testResultId, shouldRerun, testRunHandler.retryKey);
215
246
  testRunHandler._baseUrl = test.config.baseUrl;
216
247
 
217
248
  const testPlayer = await this.getTestPlayer(testRunHandler, customExtensionLocalLocation);
@@ -233,11 +264,16 @@ class BaseWorker {
233
264
  run() {
234
265
  const runNextTest = () => process.nextTick(() => this.run());
235
266
 
267
+ /**
268
+ * @param {*} testResult
269
+ * @param {import('../testRunHandler')} testRunHandler
270
+ * @param {Error=} err
271
+ */
236
272
  const onRunComplete = async (testResult, testRunHandler, err) => {
237
273
  if (utils.isQuarantineAndNotRemoteRun(testResult, this.options)) {
238
274
  return runNextTest();
239
275
  }
240
- const sessionId = testRunHandler.getSessionId();
276
+ const sessionId = testRunHandler.sessionId;
241
277
 
242
278
  const isTimeoutError = (timeoutMsg) => err.message.includes(timeoutMsg);
243
279
  const isIgnoreErrors = err && (err instanceof GetBrowserError);
@@ -251,7 +287,7 @@ class BaseWorker {
251
287
  );
252
288
 
253
289
  try {
254
- const testRetryKey = testRunHandler.getRetryKey();
290
+ const testRetryKey = testRunHandler.retryKey;
255
291
  testResult.testRetryKey = testRetryKey;
256
292
  await this.onTestCompleted(this.id, this.testId, testResult, sessionId, shouldRerun);
257
293
  if (this.executionQueue.hasMoreTests() && !this.options.lightweightMode?.general) {
@@ -271,7 +307,7 @@ class BaseWorker {
271
307
  testRetryKey,
272
308
  totalRetries: testRunHandler._totalRetryCount,
273
309
  });
274
- this.testResultId = testRunHandler.getTestResultId();
310
+ this.testResultId = testRunHandler.testResultId;
275
311
  return await runTestAndCalcResult(testRunHandler, shouldRerun);
276
312
  }
277
313
  return await runNextTest();
@@ -287,6 +323,10 @@ class BaseWorker {
287
323
  const getNetworkErrorMessage = () => 'Due to network connectivity issues, Testim CLI has been unable to connect to the grid.\n' +
288
324
  `Please make sure the CLI has stable access to the internet. ${didNetworkConnectivityTestFail() ? '(Internal: network connectivity test failed)' : ''}`;
289
325
 
326
+ /**
327
+ * @param {Error} err
328
+ * @param {boolean} wasNetworkHealthy
329
+ */
290
330
  const buildError = (err, wasNetworkHealthy) => {
291
331
  if (!wasNetworkHealthy && featureFlags.flags.errorMessageOnBadNetwork.isEnabled()) {
292
332
  return {
@@ -344,6 +384,10 @@ class BaseWorker {
344
384
  return { errorType: UNKNOWN_ERROR, reason: msg };
345
385
  };
346
386
 
387
+ /**
388
+ * @param {Error} err
389
+ * @param {import('../testRunHandler')} testRunHandler
390
+ */
347
391
  const onRunError = async (err, testRunHandler) => {
348
392
  const wasNetworkHealthy = await isNetworkHealthy();
349
393
  if (!wasNetworkHealthy && featureFlags.flags.warnOnBadNetwork.isEnabled()) {
@@ -360,12 +404,16 @@ class BaseWorker {
360
404
  success: false,
361
405
  reason,
362
406
  errorType,
363
- testRetryKey: testRunHandler.getRetryKey(),
407
+ testRetryKey: testRunHandler.retryKey,
364
408
  setupStepResult: { status: testRunStatus.COMPLETED, success: false, reason, errorType },
365
- }, testRunHandler.getRemoteRunId());
409
+ }, testRunHandler.remoteRunId);
366
410
  await onRunComplete(buildFailureResult(this.testId, this.testName, this.testResultId, reason), testRunHandler, err);
367
411
  };
368
412
 
413
+ /**
414
+ * @param {Error} runError
415
+ * @param {import('../testRunHandler')} testRunHandler
416
+ */
369
417
  const recoverTestResults = async (runError, testRunHandler) => {
370
418
  const testId = this.testId;
371
419
  const resultId = this.testResultId;
@@ -401,35 +449,41 @@ class BaseWorker {
401
449
  const disableResults = this.options.disableSockets || (this.options.lightweightMode?.disableResults && (this.options.useChromeLauncher || this.options.mode !== 'extension'));
402
450
  const disableRemoteStep = this.options.disableSockets || (this.options.lightweightMode?.disableRemoteStep);
403
451
 
404
- const runTestAndCalcResult = (testRunHandler, shouldRerun) => Promise.all([
405
- !disableRemoteStep && remoteStepService.joinToRemoteStep(this.testResultId),
406
- !disableResults && testResultService.joinToTestResult(this.testResultId, this.testId),
407
- ])
408
- .then(() => testRunHandler.validateRunConfig())
409
- .then(() => this.runTest(testRunHandler, this.customExtensionLocalLocation, shouldRerun))
410
- .then(testResult => onRunComplete(testResult, testRunHandler))
411
- .then(result => {
452
+ /**
453
+ * @param {import('../testRunHandler')} testRunHandler
454
+ * @param {boolean=} shouldRerun
455
+ */
456
+ const runTestAndCalcResult = async (testRunHandler, shouldRerun) => {
457
+ try {
458
+ await Promise.all([
459
+ !disableRemoteStep && remoteStepService.joinToRemoteStep(this.testResultId),
460
+ !disableResults && testResultService.joinToTestResult(this.testResultId, this.testId),
461
+ ]);
462
+ testRunHandler.validateRunConfig();
463
+ const testResult = await this.runTest(testRunHandler, this.customExtensionLocalLocation, shouldRerun);
464
+ const result = await onRunComplete(testResult, testRunHandler);
412
465
  perf.log('After onRunComplete');
413
466
  return result;
414
- })
415
- .catch(runError => recoverTestResults(runError, testRunHandler))
416
- .finally(() => {
467
+ } catch (runError) {
468
+ return recoverTestResults(runError, testRunHandler);
469
+ } finally {
417
470
  if (!disableRemoteStep) {
418
471
  remoteStepService.unlistenToRemoteStep(this.testResultId);
419
472
  }
420
- });
473
+ }
474
+ };
421
475
 
422
476
  const testRunHandler = this.executionQueue.getNext();
423
477
 
424
478
  if (!testRunHandler) { // no more tests to run
425
479
  return this.onQueueCompleted();
426
480
  }
427
- this.testId = testRunHandler.getTestId();
428
- this.testName = testRunHandler.getTestName();
429
- this.testResultId = testRunHandler.getTestResultId();
430
- this.overrideTestConfigId = testRunHandler.getOverrideTestConfigId();
431
- this.testRunConfig = testRunHandler.getRunConfig();
432
- this.branch = testRunHandler.getBranch();
481
+ this.testId = testRunHandler.testId;
482
+ this.testName = testRunHandler.testName;
483
+ this.testResultId = testRunHandler.testResultId;
484
+ this.overrideTestConfigId = testRunHandler.overrideTestConfigId;
485
+ this.testRunConfig = testRunHandler.runConfig;
486
+ this.branch = testRunHandler.branch;
433
487
 
434
488
  return runTestAndCalcResult(testRunHandler);
435
489
  }
@@ -25,12 +25,12 @@ describe('BaseWorker', () => {
25
25
  },
26
26
  });
27
27
 
28
- worker = new BaseWorker(null, {}, null, null, onTestStartedStub);
28
+ worker = new BaseWorker(null, {}, null, null, onTestStartedStub, null, () => { /* noop */ });
29
29
  worker.userData = {};
30
30
  worker.options = { gridData: {}, browser: 'chrome', company: { companyId: 'companyId' }, getBrowserTimeout: 1000, getSessionTimeout: 100, getBrowserRetries: 10 };
31
31
  worker.testRunConfig = {};
32
32
 
33
- testRunHandlerMock = { getExecutionId: () => 'executionId', getTestResultId: () => 'testResultId' };
33
+ testRunHandlerMock = { executionId: 'executionId', testResultId: 'testResultId' };
34
34
  testPlayerMock = { onDone: sinon.spy() };
35
35
 
36
36
  sinon.stub(worker, 'initPlayer').returns(testPlayerMock);
@@ -170,11 +170,6 @@ describe('BaseWorker', () => {
170
170
  it('should call the runTestOnc with the base url of the test object we acquired from onTestStarted', async () => {
171
171
  const testRunHandler = {
172
172
  _baseUrl: 'https://testim.io',
173
- getTestStatus: () => sinon.stub().returns(42),
174
- getTestId: () => sinon.stub().returns(42),
175
- getTestResultId: () => sinon.stub().returns(42),
176
- getRetryKey: () => sinon.stub().returns(42),
177
- getExecutionId: () => sinon.stub().returns(42),
178
173
  testRunHandler: () => sinon.stub().returns(42),
179
174
  clearTestResult: () => sinon.stub().returns(42),
180
175
  };
@@ -8,33 +8,46 @@ const AppiumTestPlayer = require('../player/appiumTestPlayer');
8
8
  const sessionPlayerInit = require('../commons/getSessionPlayerRequire');
9
9
  const AppiumApi = require('../commons/getSessionPlayerRequire').AppiumApi;
10
10
  const desiredCapabilitiesBuilder = require('../commons/testimDesiredCapabilitiesBuilder');
11
+ const testimServicesApi = require('../commons/testimServicesApi');
12
+ const config = require('../commons/config');
11
13
 
12
14
  class WorkerAppium extends BaseWorker {
13
- constructor(...args) {
14
- super(...args);
15
- this.getBrowserOnce = Promise.method(this.getBrowserOnce);
16
- }
17
-
15
+ /**
16
+ * @override
17
+ * @param {import('../testRunHandler')} testRunHandler
18
+ */
18
19
  initPlayer(testRunHandler) {
19
- return new AppiumTestPlayer(this.id,
20
- testRunHandler.getRunParams(),
20
+ return new AppiumTestPlayer(
21
+ this.id,
22
+ testRunHandler.runParams,
21
23
  this.options.shouldMonitorPerformance,
22
- testRunHandler.getAutomationMode(),
24
+ testRunHandler.automationMode,
23
25
  undefined,
24
- testRunHandler.getRetryCount(),
25
- testRunHandler.getPreviousTestResultId());
26
+ testRunHandler.retryCount,
27
+ testRunHandler.previousTestResultId,
28
+ );
26
29
  }
27
30
 
28
31
  async getBrowserOnce(testRunHandler, customExtensionLocalLocation, appiumTestPlayer, gridInfo) {
29
- reporter.onGetSession(this.id, this.testName, testRunHandler.getRunMode());
32
+ reporter.onGetSession(this.id, this.testName, testRunHandler.runMode);
30
33
  const { driver } = appiumTestPlayer;
31
- const nativeApp = testRunHandler.getNativeAppData();
34
+ let appPath = null;
35
+ if (this.options.appId) {
36
+ const { project: projectId, appId } = this.options;
37
+ const mobileApp = await testimServicesApi.getAppDetails({ appId, projectId });
38
+ if (!mobileApp) {
39
+ logger.error('mobile app not found', { appId, projectId });
40
+ throw new Error('mobile app not found');
41
+ }
42
+ appPath = `${config.SERVICES_HOST}/storage${mobileApp.filePath}?access_token=${this.options.authData.token}`;
43
+ }
44
+ const nativeApp = await testRunHandler.getNativeAppData();
32
45
  const projectType = this.options.projectData.type;
33
- const capabilities = desiredCapabilitiesBuilder.buildAppiumOptions({ projectType, gridInfo, testRunConfig: this.testRunConfig, nativeApp, options: this.options });
34
46
  try {
35
- //we assume the application is installed on the device. (all headspin allocated devices)
47
+ const capabilities = desiredCapabilitiesBuilder.buildAppiumOptions({ projectType, gridInfo, testRunConfig: this.testRunConfig, nativeApp, options: this.options, appPath });
36
48
  const activeSession = await driver.remote(capabilities);
37
49
  driver.activeSession = activeSession;
50
+ await this.updateDeviceInfo(testRunHandler, activeSession);
38
51
  logger.info(`init new appium session testName: ${this.testName}`, { sessionId: activeSession.sessionId, testResultId: this.testResultId, nativeApp });
39
52
  } catch (err) {
40
53
  //TODO: catch app status validation
@@ -44,10 +57,34 @@ class WorkerAppium extends BaseWorker {
44
57
  }
45
58
 
46
59
  getServerAddressFromGrid(testRunHandler) {
47
- const { _options: { gridData: { host, port, accessToken } } } = testRunHandler;
60
+ const { host, port, accessToken } = testRunHandler._options.gridData;
48
61
  return `https://${host}:${port}/v0/${accessToken}/wd/hub`;
49
62
  }
50
63
 
64
+ async updateDeviceInfo(testRunHandler, activeSession) {
65
+ const {
66
+ _executionId, _testId, _testResultId,
67
+ _options: { project: projectId },
68
+ } = testRunHandler;
69
+ const device = {
70
+ name: activeSession.capabilities.deviceName,
71
+ model: activeSession.capabilities.deviceModel,
72
+ osVersion: activeSession.capabilities.platformVersion,
73
+ udid: activeSession.capabilities.udid,
74
+ osType: activeSession.capabilities.platformName,
75
+ scaleFactor: activeSession.capabilities.pixelRatio,
76
+ virtual: false,
77
+ };
78
+ await testimServicesApi.updateTestStatus(
79
+ projectId,
80
+ _executionId,
81
+ _testId,
82
+ _testResultId,
83
+ 'RUNNING',
84
+ { device },
85
+ );
86
+ }
87
+
51
88
  getDirectAddressConnection(activeSessionCapabilities) {
52
89
  const { directConnectProtocol: protocol, directConnectHost: host, directConnectPort: port, directConnectPath: path } = activeSessionCapabilities;
53
90
  if (protocol && host && port && path) {
@@ -56,27 +93,29 @@ class WorkerAppium extends BaseWorker {
56
93
  return undefined;
57
94
  }
58
95
 
96
+ /**
97
+ * @param {import('../testRunHandler')} testRunHandler
98
+ * @param {import('../player/appiumTestPlayer')} appiumTestPlayer
99
+ */
59
100
  async runTestOnce(testRunHandler, appiumTestPlayer) {
60
101
  const { driver, sessionPlayer } = appiumTestPlayer;
61
102
  const version = sessionPlayerInit.manifestVersion || 'runner';
62
103
 
63
104
  reporter.onWaitToTestComplete(this.id, this.isCodeMode);
64
105
 
65
- sessionPlayer.playbackManager.executionId = testRunHandler.getExecutionId();
66
- sessionPlayer.playbackManager.executionName = testRunHandler.getExecutionName();
106
+ sessionPlayer.playbackManager.executionId = testRunHandler.executionId;
107
+ sessionPlayer.playbackManager.executionName = testRunHandler.executionName;
67
108
 
68
109
  const serverAddress = this.getDirectAddressConnection(driver.activeSession.capabilities) || this.getServerAddressFromGrid(testRunHandler);
69
- const DOMParser = new (jsdom.JSDOM)('').window.DOMParser;
110
+ const DOMParser = new jsdom.JSDOM('').window.DOMParser;
70
111
  sessionPlayer.playbackManager.appiumApi = new AppiumApi(serverAddress, driver.activeSession.sessionId, DOMParser);
71
-
72
-
73
112
  if (sessionPlayerInit.localAssetService) {
74
113
  sessionPlayerInit.localAssetService.initialize({ serverUrl: this.options.localRCASaver });
75
114
  }
76
115
  async function runAppiumTest() {
77
116
  try {
78
117
  const INCOGNITO = false;
79
- const testResult = await (new Promise((resolve, reject) =>
118
+ const testResult = await new Promise((resolve, reject) =>
80
119
  // eslint-disable-next-line no-promise-executor-return
81
120
  sessionPlayer.playByTestId(
82
121
  this.testId,
@@ -90,11 +129,12 @@ class WorkerAppium extends BaseWorker {
90
129
  this.overrideTestConfigId,
91
130
  this.branch,
92
131
  INCOGNITO,
93
- testRunHandler.getRemoteRunId(),
94
- undefined,
132
+ testRunHandler.remoteRunId,
95
133
  undefined,
96
134
  undefined,
97
- )));
135
+ undefined
136
+ )
137
+ );
98
138
  if (sessionPlayerInit.localAssetService) {
99
139
  await sessionPlayerInit.localAssetService.drain();
100
140
  }
@@ -21,6 +21,12 @@ class WorkerExtension extends BaseWorker {
21
21
  return new ExtensionTestPlayer(this.id);
22
22
  }
23
23
 
24
+ /**
25
+ * @param {import('../testRunHandler')} testRunHandler
26
+ * @param {string=} customExtensionLocalLocation
27
+ * @param {import('../player/extensionTestPlayer')} player
28
+ * @param {Awaited<ReturnType<import('../services/gridService')['getGridSlot']>>} gridInfo
29
+ */
24
30
  async _getBrowserOnce(testRunHandler, customExtensionLocalLocation, player, gridInfo) {
25
31
  const { driver } = player;
26
32
  try {
@@ -40,8 +46,8 @@ class WorkerExtension extends BaseWorker {
40
46
  logger.error('failed to get browser', {
41
47
  err,
42
48
  gridInfo,
43
- testId: testRunHandler.getTestId(),
44
- resultId: testRunHandler.getTestResultId(),
49
+ testId: testRunHandler.testId,
50
+ resultId: testRunHandler.testResultId,
45
51
  });
46
52
  throw err;
47
53
  }
@@ -49,7 +55,7 @@ class WorkerExtension extends BaseWorker {
49
55
 
50
56
  /** @override */
51
57
  async getBrowserOnce(testRunHandler, customExtensionLocalLocation, player, gridInfo) {
52
- reporter.onGetSession(this.id, this.testName, testRunHandler.getRunMode());
58
+ reporter.onGetSession(this.id, this.testName, testRunHandler.runMode);
53
59
  return this._getBrowserOnce(testRunHandler, customExtensionLocalLocation, player, gridInfo);
54
60
  }
55
61
 
@@ -175,8 +181,8 @@ class WorkerExtension extends BaseWorker {
175
181
  } catch (err) {
176
182
  logger.error('failed to run test', {
177
183
  err,
178
- testId: testRunHandler.getTestId(),
179
- resultId: testRunHandler.getTestResultId(),
184
+ testId: testRunHandler.testId,
185
+ resultId: testRunHandler.testResultId,
180
186
  });
181
187
  throw err;
182
188
  }
@@ -23,10 +23,15 @@ class WorkerExtensionSingleBrowser extends WorkerExtension {
23
23
  }
24
24
 
25
25
  async getBrowserOnce(testRunHandler, customExtensionLocalLocation, player, gridInfo) {
26
- reporter.onGetSession(this.id, `worker ${this.id}`, testRunHandler.getRunMode());
26
+ reporter.onGetSession(this.id, `worker ${this.id}`, testRunHandler.runMode);
27
27
  return this._getBrowserOnce(testRunHandler, customExtensionLocalLocation, player, gridInfo);
28
28
  }
29
29
 
30
+ /**
31
+ * @override
32
+ * @param {import('../testRunHandler')} testRunHandler
33
+ * @param {string=} customExtensionLocalLocation
34
+ */
30
35
  async getTestPlayer(testRunHandler, customExtensionLocalLocation) {
31
36
  if (this.testPlayer && !this.testPlayer.driver.isAlive()) {
32
37
  logger.warn('WorkerExtensionSingleBrowser is releasing a dead player', { workerId: this.id });
@@ -38,6 +43,11 @@ class WorkerExtensionSingleBrowser extends WorkerExtension {
38
43
  return this.testPlayer;
39
44
  }
40
45
 
46
+ /**
47
+ * @param {import('../testRunHandler')} testRunHandler
48
+ * @param {string=} customExtensionLocalLocation
49
+ * @param {boolean=} shouldRerun
50
+ */
41
51
  async runTest(testRunHandler, customExtensionLocalLocation, shouldRerun) {
42
52
  const quarantineResult = this.handleQuarantine(testRunHandler);
43
53
  if (quarantineResult) {
@@ -45,7 +55,7 @@ class WorkerExtensionSingleBrowser extends WorkerExtension {
45
55
  }
46
56
 
47
57
  perf.log('before runTest onTestStarted single browser');
48
- const test = await this.onTestStarted(this.id, testRunHandler.getTestId(), testRunHandler.getTestResultId(), shouldRerun, testRunHandler.getRetryKey());
58
+ const test = await this.onTestStarted(this.id, testRunHandler.testId, testRunHandler.testResultId, shouldRerun, testRunHandler.retryKey);
49
59
  testRunHandler._baseUrl = test.config.baseUrl;
50
60
  const testPlayer = await this.getTestPlayer(testRunHandler, customExtensionLocalLocation);
51
61