@testim/testim-cli 3.261.0 → 3.262.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/commons/testimServicesApi.js +10 -7
- package/executionQueue.js +9 -1
- package/npm-shrinkwrap.json +2 -2
- package/package.json +1 -1
- package/player/stepActions/RefreshStepAction.js +7 -4
- package/player/stepActions/baseJsStepAction.js +45 -46
- package/player/stepActions/dropFileStepAction.js +11 -12
- package/player/stepActions/evaluateExpressionStepAction.js +32 -33
- package/player/stepActions/extensionOnlyStepAction.js +3 -4
- package/player/stepActions/extractTextStepAction.js +8 -10
- package/player/stepActions/hoverStepAction.js +3 -3
- package/player/stepActions/locateStepAction.js +39 -34
- package/player/stepActions/mouseStepAction.js +36 -34
- package/player/stepActions/navigationStepAction.js +7 -8
- package/player/stepActions/scrollStepAction.js +22 -22
- package/player/stepActions/stepAction.js +21 -21
- package/player/stepActions/stepActionRegistrar.js +63 -58
- package/player/stepActions/submitStepAction.js +2 -3
- package/player/stepActions/textStepAction.js +14 -14
- package/player/stepActions/textValidationStepAction.js +50 -38
- package/player/stepActions/wheelStepAction.js +5 -11
- package/processHandler.js +2 -0
- package/reports/junitReporter.js +18 -1
- package/runOptions.d.ts +4 -0
- package/runOptions.js +8 -1
- package/runners/TestPlanRunner.js +20 -19
- package/runners/runnerUtils.js +1 -2
- package/testRunHandler.js +18 -9
- package/testRunStatus.js +205 -157
- package/workers/BaseWorker.js +11 -0
- package/workers/WorkerExtension.js +117 -91
- package/workers/WorkerSelenium.js +8 -3
package/testRunStatus.js
CHANGED
|
@@ -1,41 +1,50 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
const
|
|
4
|
-
const { TESTIM_CONCURRENT_WORKER_COUNT } = require('./commons/config');
|
|
3
|
+
const _ = require('lodash');
|
|
5
4
|
const utils = require('./utils');
|
|
6
|
-
const reporter = require('./reports/reporter
|
|
7
|
-
const
|
|
5
|
+
const reporter = require('./reports/reporter');
|
|
6
|
+
const constants = require('./commons/constants');
|
|
8
7
|
const gridService = require('./services/gridService');
|
|
9
|
-
const
|
|
10
|
-
const
|
|
8
|
+
const featureFlags = require('./commons/featureFlags');
|
|
9
|
+
const servicesApi = require('./commons/testimServicesApi');
|
|
11
10
|
const OverrideTestDataBuilder = require('./OverrideTestDataBuilder');
|
|
12
|
-
const
|
|
13
|
-
const
|
|
14
|
-
const
|
|
11
|
+
const featureAvailabilityService = require('./commons/featureAvailabilityService');
|
|
12
|
+
const { ArgError } = require('./errors');
|
|
13
|
+
const { getLogger } = require('./commons/logger');
|
|
15
14
|
const { registerExitHook } = require('./processHandler');
|
|
16
15
|
const { calculateCoverage } = require('./coverage/jsCoverage');
|
|
17
|
-
const
|
|
18
|
-
const featureFlags = require('./commons/featureFlags');
|
|
16
|
+
const { SeleniumPerfStats } = require('./commons/SeleniumPerfStats');
|
|
19
17
|
const { mapFilesToLocalDrive } = require('./services/localRCASaver');
|
|
20
|
-
const {
|
|
18
|
+
const { TESTIM_CONCURRENT_WORKER_COUNT } = require('./commons/config');
|
|
21
19
|
|
|
20
|
+
const logger = getLogger('test-run-status');
|
|
22
21
|
const gitBranch = utils.getEnvironmentGitBranch();
|
|
23
22
|
const gitCommit = process.env.GIT_COMMIT || process.env.CIRCLE_SHA1 || process.env.TRAVIS_COMMIT;
|
|
24
23
|
const gitRepoUrl = process.env.GIT_URL || process.env.CIRCLE_REPOSITORY_URL;
|
|
25
24
|
const runnerVersion = utils.getRunnerVersion();
|
|
26
25
|
|
|
27
26
|
|
|
28
|
-
function runHook(fn, ...args) {
|
|
27
|
+
async function runHook(fn, ...args) {
|
|
29
28
|
if (!fn || typeof fn !== 'function') {
|
|
30
|
-
return
|
|
29
|
+
return undefined;
|
|
31
30
|
}
|
|
32
|
-
|
|
31
|
+
|
|
32
|
+
try {
|
|
33
|
+
const res = await fn(...args);
|
|
34
|
+
return res || {};
|
|
35
|
+
} catch (err) {
|
|
33
36
|
logger.warn('failed to run hook', { err });
|
|
34
37
|
throw new ArgError(`failed to run hook promise ${err.message}`);
|
|
35
|
-
}
|
|
38
|
+
}
|
|
36
39
|
}
|
|
37
40
|
|
|
38
41
|
class RunStatus {
|
|
42
|
+
/**
|
|
43
|
+
* @param {any[]} testInfoList
|
|
44
|
+
* @param {import('./runOptions').RunnerOptions} options
|
|
45
|
+
* @param {string} testPlanId
|
|
46
|
+
* @param {string} branchToUse
|
|
47
|
+
*/
|
|
39
48
|
constructor(testInfoList, options, testPlanId, branchToUse) {
|
|
40
49
|
this.options = options;
|
|
41
50
|
this.options.runParams = this.options.runParams || {};
|
|
@@ -65,7 +74,7 @@ class RunStatus {
|
|
|
65
74
|
testPlanId,
|
|
66
75
|
testPlans: options.testPlan,
|
|
67
76
|
testLabels: options.label,
|
|
68
|
-
testSuites:
|
|
77
|
+
testSuites: [...new Set(testInfoList.flatMap(test => test.testSuites))],
|
|
69
78
|
testNames: options.name,
|
|
70
79
|
testIds: options.testId,
|
|
71
80
|
testConfigs: options.testConfigNames,
|
|
@@ -104,7 +113,18 @@ class RunStatus {
|
|
|
104
113
|
}) {
|
|
105
114
|
const orgTestResult = this.testRunStatus[originalTestResultId] || {};
|
|
106
115
|
const {
|
|
107
|
-
config,
|
|
116
|
+
config,
|
|
117
|
+
isTestsContainer,
|
|
118
|
+
testId,
|
|
119
|
+
name,
|
|
120
|
+
testStatus,
|
|
121
|
+
testCreatorName,
|
|
122
|
+
testCreatorEmail,
|
|
123
|
+
testOwnerName,
|
|
124
|
+
testOwnerEmail,
|
|
125
|
+
testLabels,
|
|
126
|
+
testSuites,
|
|
127
|
+
allLabels,
|
|
108
128
|
} = orgTestResult;
|
|
109
129
|
|
|
110
130
|
const newTestResult = {
|
|
@@ -120,7 +140,15 @@ class RunStatus {
|
|
|
120
140
|
testStatus,
|
|
121
141
|
};
|
|
122
142
|
|
|
123
|
-
this.testRunStatus[newResultId] = newTestResult
|
|
143
|
+
this.testRunStatus[newResultId] = Object.assign({}, newTestResult, {
|
|
144
|
+
testCreatorName,
|
|
145
|
+
testCreatorEmail,
|
|
146
|
+
testOwnerName,
|
|
147
|
+
testOwnerEmail,
|
|
148
|
+
testLabels,
|
|
149
|
+
testSuites,
|
|
150
|
+
allLabels,
|
|
151
|
+
});
|
|
124
152
|
|
|
125
153
|
return servicesApi.addTestRetry({
|
|
126
154
|
projectId,
|
|
@@ -146,55 +174,58 @@ class RunStatus {
|
|
|
146
174
|
return test;
|
|
147
175
|
}
|
|
148
176
|
|
|
149
|
-
updateTestStatusRunning(test, executionId, testRetryKey) {
|
|
177
|
+
async updateTestStatusRunning(test, executionId, testRetryKey) {
|
|
150
178
|
const { project: projectId, remoteRunId, projectData } = this.options;
|
|
151
179
|
if (this.options.lightweightMode?.onlyTestIdsNoSuite) {
|
|
152
180
|
return this.executionStartedPromise;
|
|
153
181
|
}
|
|
154
182
|
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
.
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
183
|
+
let testDataUrl = '';
|
|
184
|
+
|
|
185
|
+
try {
|
|
186
|
+
testDataUrl = await servicesApi.updateTestDataArtifact(projectId, test.testId, test.resultId, test.config.testData, projectData.defaults);
|
|
187
|
+
} catch (err) {
|
|
188
|
+
logger.error('failed to upload test data artifact (runner)', { err });
|
|
189
|
+
}
|
|
190
|
+
const testConfig = _.cloneDeep(test.config);
|
|
191
|
+
delete testConfig.testData;
|
|
192
|
+
testConfig.testDataUrl = testDataUrl;
|
|
193
|
+
await this.executionStartedPromise;
|
|
194
|
+
return servicesApi.updateTestStatus(projectId, executionId, test.testId, test.resultId, 'RUNNING', { startTime: test.startTime, config: testConfig, remoteRunId, testRetryKey });
|
|
167
195
|
}
|
|
168
196
|
|
|
169
|
-
testStartReport(test, executionId, testRetryKey) {
|
|
197
|
+
async testStartReport(test, executionId, testRetryKey) {
|
|
170
198
|
if (utils.isQuarantineAndNotRemoteRun(test, this.options)) {
|
|
171
|
-
return
|
|
199
|
+
return undefined;
|
|
200
|
+
}
|
|
201
|
+
const globalParameters = this.exportsGlobal;
|
|
202
|
+
try {
|
|
203
|
+
const params = await runHook(this.options.beforeTest, Object.assign({}, test, { exportsGlobal: globalParameters, globalParameters }), this.options.userData.loginData.token);
|
|
204
|
+
|
|
205
|
+
// Temporary Sapiens log (SUP-3192)
|
|
206
|
+
if (this.options.projectData && this.options.projectData.projectId === 'fZ63D61PRQQVvvtGY6Ue' && this.options.suites && this.options.suites.includes('Sanity')) {
|
|
207
|
+
logger.info('testRunStatus - testStartReport', {
|
|
208
|
+
'test.config.testData': test.config.testData,
|
|
209
|
+
'this.exportsGlobal': this.exportsGlobal,
|
|
210
|
+
'this.fileUserParamsData': this.fileUserParamsData,
|
|
211
|
+
'this.beforeSuiteParams': this.beforeSuiteParams,
|
|
212
|
+
params,
|
|
213
|
+
executionId,
|
|
214
|
+
'test.testId': test.testId,
|
|
215
|
+
'test.resultId': test.resultId,
|
|
216
|
+
});
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
test.config.testData = Object.assign({}, test.config.testData, this.exportsGlobal, this.fileUserParamsData, this.beforeSuiteParams, params);
|
|
220
|
+
this.options.runParams[test.resultId] = test.config.testData;
|
|
221
|
+
test.startTime = Date.now();
|
|
222
|
+
await this.updateTestStatusRunning(test, executionId, testRetryKey);
|
|
223
|
+
|
|
224
|
+
return test;
|
|
225
|
+
} catch (err) {
|
|
226
|
+
logger.error('Failed to start test', { err });
|
|
227
|
+
throw err;
|
|
172
228
|
}
|
|
173
|
-
return runHook(this.options.beforeTest, Object.assign({}, test, { exportsGlobal: this.exportsGlobal }), this.options.userData.loginData.token)
|
|
174
|
-
.then(async (params) => {
|
|
175
|
-
// Temporary Sapiens log (SUP-3192)
|
|
176
|
-
if (this.options.projectData && this.options.projectData.projectId === 'fZ63D61PRQQVvvtGY6Ue' && this.options.suites && this.options.suites.includes('Sanity')) {
|
|
177
|
-
logger.info('testRunStatus - testStartReport', {
|
|
178
|
-
'test.config.testData': test.config.testData,
|
|
179
|
-
'this.exportsGlobal': this.exportsGlobal,
|
|
180
|
-
'this.fileUserParamsData': this.fileUserParamsData,
|
|
181
|
-
'this.beforeSuiteParams': this.beforeSuiteParams,
|
|
182
|
-
params,
|
|
183
|
-
executionId,
|
|
184
|
-
'test.testId': test.testId,
|
|
185
|
-
'test.resultId': test.resultId,
|
|
186
|
-
});
|
|
187
|
-
}
|
|
188
|
-
test.config.testData = Object.assign({}, test.config.testData, this.exportsGlobal, this.fileUserParamsData, this.beforeSuiteParams, params);
|
|
189
|
-
this.options.runParams[test.resultId] = test.config.testData;
|
|
190
|
-
test.startTime = Date.now();
|
|
191
|
-
await this.updateTestStatusRunning(test, executionId, testRetryKey);
|
|
192
|
-
|
|
193
|
-
return test;
|
|
194
|
-
}).catch(err => {
|
|
195
|
-
logger.error('Failed to start test', { err });
|
|
196
|
-
throw err;
|
|
197
|
-
});
|
|
198
229
|
}
|
|
199
230
|
|
|
200
231
|
testStartAndReport(wid, executionId, resultId, isRerun, testRetryKey) {
|
|
@@ -219,16 +250,14 @@ class RunStatus {
|
|
|
219
250
|
reporter.onTestPassed(name);
|
|
220
251
|
return;
|
|
221
252
|
}
|
|
222
|
-
reporter.onTestFailed(
|
|
253
|
+
reporter.onTestFailed(
|
|
254
|
+
test,
|
|
223
255
|
test.failureReason,
|
|
224
|
-
utils.getTestUrl(this.options.editorUrl,
|
|
225
|
-
this.options.project,
|
|
226
|
-
testId,
|
|
227
|
-
resultId,
|
|
228
|
-
this.branchToUse),
|
|
256
|
+
utils.getTestUrl(this.options.editorUrl, this.options.project, testId, resultId, this.branchToUse),
|
|
229
257
|
testId,
|
|
230
258
|
isRerun,
|
|
231
|
-
resultId
|
|
259
|
+
resultId,
|
|
260
|
+
);
|
|
232
261
|
}
|
|
233
262
|
|
|
234
263
|
calcResultText(result) {
|
|
@@ -298,7 +327,7 @@ class RunStatus {
|
|
|
298
327
|
const globalParameters = result.exportsGlobal;
|
|
299
328
|
try {
|
|
300
329
|
try {
|
|
301
|
-
await runHook(this.options.afterTest, Object.assign({}, test, { globalParameters }), this.options.userData.loginData.token);
|
|
330
|
+
await runHook(this.options.afterTest, Object.assign({}, test, { exportsGlobal: globalParameters, globalParameters }), this.options.userData.loginData.token);
|
|
302
331
|
} catch (err) {
|
|
303
332
|
logger.error('HOOK threw an error', { test: test.testId, err });
|
|
304
333
|
// eslint-disable-next-line no-console
|
|
@@ -364,7 +393,7 @@ class RunStatus {
|
|
|
364
393
|
}, {});
|
|
365
394
|
}
|
|
366
395
|
|
|
367
|
-
executionStart(executionId, projectId, startTime, testPlanName, testNames) {
|
|
396
|
+
async executionStart(executionId, projectId, startTime, testPlanName, testNames) {
|
|
368
397
|
logger.info('execution started', { executionId });
|
|
369
398
|
const { options } = this;
|
|
370
399
|
const { remoteRunId, projectData } = options;
|
|
@@ -383,66 +412,74 @@ class RunStatus {
|
|
|
383
412
|
]));
|
|
384
413
|
|
|
385
414
|
this.startTime = startTime || Date.now();
|
|
386
|
-
const runHooksProps = {
|
|
387
|
-
|
|
388
|
-
|
|
415
|
+
const runHooksProps = {
|
|
416
|
+
projectId,
|
|
417
|
+
executionId,
|
|
418
|
+
...(featureFlags.flags.testNamesToBeforeSuiteHook.isEnabled() && { testNames }),
|
|
419
|
+
};
|
|
420
|
+
const params = await runHook(options.beforeSuite, runHooksProps);
|
|
421
|
+
const overrideTestDataBuilder = new OverrideTestDataBuilder(params, _.cloneDeep(this.testInfoList), projectId);
|
|
422
|
+
this.testInfoList = overrideTestDataBuilder.overrideTestData();
|
|
423
|
+
this.calcTestRunStatus();
|
|
424
|
+
this.beforeSuiteParams = params;
|
|
425
|
+
|
|
426
|
+
const { testInfoList } = this;
|
|
427
|
+
const beforeTests = [];
|
|
428
|
+
const tests = [];
|
|
429
|
+
const afterTests = [];
|
|
430
|
+
for (const test of testInfoList) {
|
|
431
|
+
if (test.isBeforeTestPlan) {
|
|
432
|
+
beforeTests.push(test);
|
|
433
|
+
continue;
|
|
434
|
+
}
|
|
435
|
+
if (test.isAfterTestPlan) {
|
|
436
|
+
afterTests.push(test);
|
|
437
|
+
continue;
|
|
438
|
+
}
|
|
439
|
+
tests.push(test);
|
|
389
440
|
}
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
const
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
const testResults = _.cloneDeep(this.testRunStatus);
|
|
404
|
-
return promiseMap(Object.keys(testResults), testResultId => {
|
|
405
|
-
const test = testResults[testResultId];
|
|
406
|
-
const testData = test.config?.testData;
|
|
407
|
-
const testId = test.testId;
|
|
408
|
-
return servicesApi.updateTestDataArtifact(projectId, testId, testResultId, testData, projectData.defaults)
|
|
409
|
-
.then((testDataUrl) => {
|
|
410
|
-
if (!testDataUrl) {
|
|
411
|
-
return;
|
|
412
|
-
}
|
|
413
|
-
delete test.config.testData;
|
|
414
|
-
test.config.testDataUrl = testDataUrl;
|
|
415
|
-
});
|
|
416
|
-
}).then(() => {
|
|
417
|
-
const isLocalRun = Boolean(options.useLocalChromeDriver || options.useChromeLauncher);
|
|
418
|
-
const data = {
|
|
419
|
-
executionId,
|
|
420
|
-
projectId,
|
|
421
|
-
labels: testPlanName || [],
|
|
422
|
-
startTime,
|
|
423
|
-
executions: testResults,
|
|
424
|
-
config: this.execConfig,
|
|
425
|
-
resultLabels: options.resultLabels,
|
|
426
|
-
remoteRunId: options.remoteRunId,
|
|
427
|
-
localRunUserId: options.user,
|
|
428
|
-
isLocalRun,
|
|
429
|
-
intersections: options.intersections,
|
|
430
|
-
};
|
|
431
|
-
const ret = servicesApi.reportExecutionStarted(data);
|
|
432
|
-
this.executionStartedPromise = ret;
|
|
433
|
-
ret.catch(e => logger.error(e));
|
|
434
|
-
return ret;
|
|
435
|
-
});
|
|
436
|
-
};
|
|
437
|
-
|
|
438
|
-
return reportExecutionStarted()
|
|
439
|
-
.catch(err => {
|
|
440
|
-
logger.error('Failed to start suite', { err });
|
|
441
|
-
// eslint-disable-next-line no-console
|
|
442
|
-
console.error('Failed to start test run. Please contact support@testim.io');
|
|
443
|
-
})
|
|
444
|
-
.then(() => ({ beforeTests, tests, afterTests }));
|
|
441
|
+
|
|
442
|
+
const reportExecutionStarted = async () => {
|
|
443
|
+
const testResults = _.cloneDeep(this.testRunStatus);
|
|
444
|
+
await utils.promiseMap(Object.keys(testResults), async testResultId => {
|
|
445
|
+
const test = testResults[testResultId];
|
|
446
|
+
const testData = test.config?.testData;
|
|
447
|
+
const testId = test.testId;
|
|
448
|
+
const testDataUrl = await servicesApi.updateTestDataArtifact(projectId, testId, testResultId, testData, projectData.defaults);
|
|
449
|
+
if (!testDataUrl) {
|
|
450
|
+
return;
|
|
451
|
+
}
|
|
452
|
+
delete test.config.testData;
|
|
453
|
+
test.config.testDataUrl = testDataUrl;
|
|
445
454
|
});
|
|
455
|
+
const isLocalRun = Boolean(options.useLocalChromeDriver || options.useChromeLauncher);
|
|
456
|
+
const data = {
|
|
457
|
+
executionId,
|
|
458
|
+
projectId,
|
|
459
|
+
labels: testPlanName || [],
|
|
460
|
+
startTime,
|
|
461
|
+
executions: testResults,
|
|
462
|
+
config: this.execConfig,
|
|
463
|
+
resultLabels: options.resultLabels,
|
|
464
|
+
remoteRunId: options.remoteRunId,
|
|
465
|
+
localRunUserId: options.user,
|
|
466
|
+
isLocalRun,
|
|
467
|
+
intersections: options.intersections,
|
|
468
|
+
};
|
|
469
|
+
const ret = servicesApi.reportExecutionStarted(data);
|
|
470
|
+
this.executionStartedPromise = ret;
|
|
471
|
+
ret.catch(e => logger.error(e));
|
|
472
|
+
return ret;
|
|
473
|
+
};
|
|
474
|
+
|
|
475
|
+
try {
|
|
476
|
+
await reportExecutionStarted();
|
|
477
|
+
} catch (err) {
|
|
478
|
+
logger.error('Failed to start suite', { err });
|
|
479
|
+
// eslint-disable-next-line no-console
|
|
480
|
+
console.error('Failed to start test run. Please contact support@testim.io');
|
|
481
|
+
}
|
|
482
|
+
return { beforeTests, tests, afterTests };
|
|
446
483
|
}
|
|
447
484
|
|
|
448
485
|
concatSeleniumPerfMarks(marks) {
|
|
@@ -456,47 +493,58 @@ class RunStatus {
|
|
|
456
493
|
.value();
|
|
457
494
|
}
|
|
458
495
|
|
|
459
|
-
executionEnd(executionId) {
|
|
496
|
+
async executionEnd(executionId) {
|
|
460
497
|
const tests = utils.groupTestsByRetries(this.testRunStatus);
|
|
461
498
|
const total = tests.length;
|
|
462
|
-
const passed = tests.filter(({ status }) => status === constants.runnerTestStatus.PASSED).length;
|
|
463
|
-
const skipped = tests.filter(({ status }) => status === constants.runnerTestStatus.SKIPPED).length;
|
|
464
|
-
const failedInEvaluatingStatus = tests.filter(({ status, testStatus }) => status === constants.runnerTestStatus.FAILED && testStatus === constants.testStatus.EVALUATING).length;
|
|
465
499
|
|
|
466
|
-
|
|
467
|
-
|
|
500
|
+
let passed = 0;
|
|
501
|
+
let skipped = 0;
|
|
502
|
+
let failedInEvaluatingStatus = 0;
|
|
503
|
+
for (const { status, testStatus } of tests) {
|
|
504
|
+
if (status === constants.runnerTestStatus.PASSED) {
|
|
505
|
+
passed++;
|
|
506
|
+
}
|
|
507
|
+
if (status === constants.runnerTestStatus.SKIPPED) {
|
|
508
|
+
skipped++;
|
|
509
|
+
}
|
|
510
|
+
if (status === constants.runnerTestStatus.FAILED && testStatus === constants.testStatus.EVALUATING) {
|
|
511
|
+
failedInEvaluatingStatus++;
|
|
512
|
+
}
|
|
513
|
+
}
|
|
514
|
+
|
|
515
|
+
const { seleniumPerfMarks, ...resultExtraData } = this.seleniumPerfStats.getStats();
|
|
468
516
|
|
|
469
|
-
|
|
517
|
+
await runHook(this.options.afterSuite, {
|
|
470
518
|
exportsGlobal: this.exportsGlobal,
|
|
471
519
|
tests,
|
|
472
520
|
total,
|
|
473
521
|
passed,
|
|
474
522
|
skipped,
|
|
475
|
-
})
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
resultExtraData.coverageSummary = coverageSummary;
|
|
523
|
+
});
|
|
524
|
+
const coverageSummary = await calculateCoverage(this.options, this.branchToUse, total, executionId);
|
|
525
|
+
resultExtraData.coverageSummary = coverageSummary;
|
|
479
526
|
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
527
|
+
if (this.options.lightweightMode?.onlyTestIdsNoSuite) {
|
|
528
|
+
return undefined;
|
|
529
|
+
}
|
|
530
|
+
try {
|
|
531
|
+
return await servicesApi.reportExecutionFinished(
|
|
532
|
+
'FINISHED',
|
|
533
|
+
executionId,
|
|
534
|
+
this.options.project,
|
|
535
|
+
total === (passed + skipped + failedInEvaluatingStatus),
|
|
536
|
+
{
|
|
537
|
+
tmsSuppressReporting: this.options.tmsSuppressReporting,
|
|
538
|
+
tmsRunId: this.options.tmsRunId,
|
|
539
|
+
tmsCustomFields: this.options.tmsCustomFields,
|
|
540
|
+
},
|
|
541
|
+
this.options.remoteRunId,
|
|
542
|
+
resultExtraData
|
|
543
|
+
);
|
|
544
|
+
} catch (err) {
|
|
545
|
+
logger.error('Failed to update suite finished', { err });
|
|
546
|
+
throw err;
|
|
547
|
+
}
|
|
500
548
|
}
|
|
501
549
|
|
|
502
550
|
async markAllQueuedTests(executionId, status, failureReason, success) {
|
package/workers/BaseWorker.js
CHANGED
|
@@ -38,6 +38,17 @@ function buildFailureResult(testId, testName, resultId, reason) {
|
|
|
38
38
|
}
|
|
39
39
|
|
|
40
40
|
class BaseWorker {
|
|
41
|
+
/**
|
|
42
|
+
* @param {import('../executionQueue')} executionQueue
|
|
43
|
+
* @param {import('../runOptions').RunnerOptions} options
|
|
44
|
+
* @param {string=} customExtensionLocalLocation
|
|
45
|
+
* @param {string} executionId
|
|
46
|
+
* @param {Function} onTestStarted
|
|
47
|
+
* @param {Function} onTestCompleted
|
|
48
|
+
* @param {Function} onGridSlot
|
|
49
|
+
* @param {Function} onTestIgnored
|
|
50
|
+
* @param {boolean=} releaseSlotOnTestFinished
|
|
51
|
+
*/
|
|
41
52
|
constructor(executionQueue, options, customExtensionLocalLocation, executionId, onTestStarted, onTestCompleted, onGridSlot, onTestIgnored, releaseSlotOnTestFinished = true) {
|
|
42
53
|
this.lambdatestService = new LambdatestService();
|
|
43
54
|
|