@testim/testim-cli 3.236.0 → 3.237.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/executionQueue.js CHANGED
@@ -7,6 +7,10 @@ class ExecutionQueue {
7
7
  this._waitingTests = testList.map(testInfo => new TestRun(executionId, executionName, testInfo, options, branchToUse, testStatus));
8
8
  }
9
9
 
10
+ stop() {
11
+ this._waitingTests = [];
12
+ }
13
+
10
14
  getNext() {
11
15
  const nextTestRunHandler = this._waitingTests.shift();
12
16
  if (nextTestRunHandler) {
@@ -1,12 +1,12 @@
1
1
  {
2
2
  "name": "@testim/testim-cli",
3
- "version": "3.236.0",
3
+ "version": "3.237.0",
4
4
  "lockfileVersion": 2,
5
5
  "requires": true,
6
6
  "packages": {
7
7
  "": {
8
8
  "name": "@testim/testim-cli",
9
- "version": "3.236.0",
9
+ "version": "3.237.0",
10
10
  "license": "Proprietary",
11
11
  "dependencies": {
12
12
  "@applitools/eyes-sdk-core": "13.2.0",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@testim/testim-cli",
3
- "version": "3.236.0",
3
+ "version": "3.237.0",
4
4
  "description": "Command line interface for running Testing on your CI",
5
5
  "author": "Oren Rubin",
6
6
  "contributors": [{
@@ -332,7 +332,7 @@ class WebDriver extends WebDriverApi {
332
332
  }
333
333
 
334
334
  getElementTextJS(locatedElement) {
335
- function extractTextCode(locatedElement) {
335
+ function extractTextCode(locatedElement, ignoreHiddenTagsText) {
336
336
  // copy of utils.getElementTextContent to run inside content script
337
337
  // sadly .children doesn't work for SVG elements in IE11
338
338
  function clearTitleTags(node) {
@@ -362,14 +362,15 @@ class WebDriver extends WebDriverApi {
362
362
  return element.shadowRoot.textContent.replace(/(\r\n|\n|\r)/gm, "");
363
363
  }
364
364
  } catch (err) { }
365
- if (this.ignoreHiddenTagsText && Array.prototype.some.call(element.children, elem => elem.hidden)) {
366
- const dupElement = element.cloneNode(true);
367
- const hiddenChildren = Array.prototype.filter.call(dupElement.children, elem => elem.hidden);
368
- hiddenChildren.forEach(child => {
365
+ if (ignoreHiddenTagsText && Array.prototype.some.call(element.children, function (elem) { return elem.hidden; })) {
366
+ var dupElement = element.cloneNode(true);
367
+ var hiddenChildren = Array.prototype.filter.call(dupElement.children, function (elem) { return elem.hidden; });
368
+ hiddenChildren.forEach(function (child) {
369
369
  dupElement.removeChild(child);
370
370
  });
371
- return dupElement.textContent.replace(/(\r\n|\n|\r)/gm, "");
372
- } return element.textContent.replace(/(\r\n|\n|\r)/gm, "");
371
+ return dupElement.textContent.replace(/(\r\n|\n|\r)/gm, '');
372
+ }
373
+ return element.textContent.replace(/(\r\n|\n|\r)/gm, '');
373
374
  }
374
375
 
375
376
  function getElementTextContent(element) {
@@ -399,7 +400,7 @@ class WebDriver extends WebDriverApi {
399
400
  var getLocatedElement = ${codeSnippets().getLocatedElementCode};
400
401
  var extractText = ${extractTextCode.toString()};
401
402
  return extractText.apply(null, arguments)
402
- `, locatedElement)
403
+ `, locatedElement, this.ignoreHiddenTagsText)
403
404
  .then(result => result.value);
404
405
  }
405
406
 
package/runOptions.js CHANGED
@@ -187,6 +187,8 @@ program
187
187
  .option('--token [token]', 'identification token to testim')
188
188
  .option('--is-regression-baseline-run', 'save doms and run results as regression baseline data')
189
189
  .option('--parallel [number-of-tests]', 'number of tests to run on parallel')
190
+ .option('--before-parallel [number-of-tests]', 'number of tests to run on parallel in the before phase of a test plan')
191
+ .option('--after-parallel [number-of-tests]', 'number of tests to run on parallel in the after phase of a test plan')
190
192
  .option('--canary [canary-mode]', 'enable canary mode', false)
191
193
  .option('--test-plan [test-plan-name]', 'test plan to run', collect, [])
192
194
  .option('--test-plan-id [test-plan-id]', 'test plan to run', collect, [])
@@ -762,7 +764,9 @@ module.exports = {
762
764
 
763
765
  const timeoutWasGiven = Boolean(program.timeout);
764
766
  program.timeout = !program.timeout || typeof program.timeout === 'boolean' ? 10 * 60 * 1000 : Number(program.timeout);
767
+ program.beforeParallel = !program.beforeParallel || typeof program.beforeParallel === 'boolean' ? 1 : Number(program.beforeParallel);
765
768
  program.parallel = !program.parallel || typeof program.parallel === 'boolean' ? 1 : Number(program.parallel);
769
+ program.afterParallel = !program.afterParallel || typeof program.afterParallel === 'boolean' ? 1 : Number(program.afterParallel);
766
770
 
767
771
 
768
772
  if (program.parallel > 1 && program.run && !program.gridId && !program.grid &&
@@ -817,10 +821,18 @@ module.exports = {
817
821
  throw new ArgError('test run timeout could not be a negative number, --timeout <run-timeout>');
818
822
  }
819
823
 
824
+ if (program.beforeParallel <= 0 || _.isNaN(program.beforeParallel)) {
825
+ throw new ArgError('before-parallel could not be a negative number or not number, --before-parallel <number-of-tests>');
826
+ }
827
+
820
828
  if (program.parallel <= 0 || _.isNaN(program.parallel)) {
821
829
  throw new ArgError('parallel could not be a negative number or not number, --parallel <number-of-tests>');
822
830
  }
823
831
 
832
+ if (program.afterParallel <= 0 || _.isNaN(program.afterParallel)) {
833
+ throw new ArgError('after-parallel could not be a negative number or not number, --after-parallel <number-of-tests>');
834
+ }
835
+
824
836
  if (![CLI_MODE.EXTENSION, CLI_MODE.SELENIUM].includes(program.mode)) {
825
837
  throw new ArgError(`runner mode <${program.mode}> is not supported`);
826
838
  }
@@ -866,6 +878,10 @@ module.exports = {
866
878
  );
867
879
  }
868
880
 
881
+ if (!isTestPlanSpecified && (program.beforeParallel !== 1 || program.afterParallel !== 1)) {
882
+ throw new ArgError('cannot set --before-parallel or --after-parallel without --test-plan option');
883
+ }
884
+
869
885
  if (
870
886
  (program.testId.length ||
871
887
  isTestPlanSpecified ||
@@ -1089,7 +1105,9 @@ module.exports = {
1089
1105
  mode: program.mode,
1090
1106
  isRegressionBaselineRun: program.isRegressionBaselineRun,
1091
1107
  browser: program.browser,
1108
+ beforeParallel: program.beforeParallel,
1092
1109
  parallel: program.parallel,
1110
+ afterParallel: program.afterParallel,
1093
1111
  canary: program.canary,
1094
1112
  rerunFailedByRunId: program.rerunFailedByRunId,
1095
1113
  disableGridCheck: program.disableGridCheck,
@@ -50,6 +50,8 @@ class ParallelWorkerManager {
50
50
  return undefined;
51
51
  }
52
52
 
53
+ let stoppedOnError = false;
54
+ let runningTests = 0;
53
55
  const runAndWaitToComplete = token => new Promise((resolve, reject) => {
54
56
  const projectId = options.project;
55
57
  const executionQueue = new ExecutionQueue(executionId, executionName, testList, options, branchToUse, testStatus);
@@ -68,6 +70,7 @@ class ParallelWorkerManager {
68
70
  const sessionType = utils.getSessionType(options);
69
71
 
70
72
  const onTestStarted = (wid, testId, resultId, isRerun, testRetryKey) => {
73
+ runningTests++;
71
74
  analyticsService.analyticsTestStart({
72
75
  authData,
73
76
  executionId,
@@ -150,11 +153,12 @@ class ParallelWorkerManager {
150
153
  isStartUp,
151
154
  });
152
155
  if (stopOnError && !testResult.success) {
153
- reject(new StopRunOnError());
154
- throw new StopRunOnError();
156
+ executionQueue.stop();
157
+ stoppedOnError = true;
155
158
  }
159
+ runningTests--;
156
160
  const completedTests = Object.keys(combinedTestResults).length;
157
- if (completedTests === testCount) {
161
+ if (completedTests === testCount || (stopOnError && runningTests === 0)) {
158
162
  resolve(combinedTestResults);
159
163
  return undefined;
160
164
  }
@@ -164,8 +168,9 @@ class ParallelWorkerManager {
164
168
  const onTestIgnored = (wid, testResult) => {
165
169
  combinedTestResults[testResult.resultId] = testResult;
166
170
  testStatus.onTestIgnored(wid, testResult.resultId);
171
+ runningTests--;
167
172
  const completedTests = Object.keys(combinedTestResults).length;
168
- if (completedTests === testCount) {
173
+ if (completedTests === testCount || (stopOnError && runningTests === 0)) {
169
174
  resolve(combinedTestResults);
170
175
  }
171
176
  };
@@ -195,7 +200,11 @@ class ParallelWorkerManager {
195
200
 
196
201
  try {
197
202
  const token = await testimCustomToken.getCustomTokenV3();
198
- return await runAndWaitToComplete(token);
203
+ const result = await runAndWaitToComplete(token);
204
+ if (stoppedOnError) {
205
+ throw new StopRunOnError();
206
+ }
207
+ return result;
199
208
  } catch (err) {
200
209
  logger.error('failed running parallel workers', { executionId, err });
201
210
  throw err;
@@ -35,7 +35,7 @@ class TestPlanRunner {
35
35
  const authData = testimCustomToken.getTokenV3UserData();
36
36
 
37
37
  const runBeforeTests = () => {
38
- const workerCount = 1;
38
+ const workerCount = tpOptions.beforeParallel || 1;
39
39
  const stopOnError = true;
40
40
  return this.workerManager.runTests(beforeTests, testStatus, executionId, executionName, tpOptions, branchToUse, authData, workerCount, stopOnError)
41
41
  .then(beforeTestsResults => Object.assign(executionResults, beforeTestsResults));
@@ -51,7 +51,7 @@ class TestPlanRunner {
51
51
  };
52
52
 
53
53
  const runAfterTests = () => {
54
- const workerCount = 1;
54
+ const workerCount = tpOptions.afterParallel || 1;
55
55
  const stopOnError = false;
56
56
  return this.workerManager.runTests(afterTests, testStatus, executionId, executionName, tpOptions, branchToUse, authData, workerCount, stopOnError)
57
57
  .then(afterTestsResults => Object.assign(executionResults, afterTestsResults));