@zohodesk/testinglibrary 0.0.11-n20-experimental → 0.0.13-n20-experimental

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/.gitlab-ci.yml CHANGED
@@ -188,4 +188,19 @@ uat-data_generator:
188
188
  paths:
189
189
  - examples/uat/playwright-report
190
190
 
191
+ # uat-search_indexing:
192
+ # stage: uat
193
+ # script:
194
+ # - cd examples
195
+ # - npm install $(npm pack ../../testing-framework | tail -1)
196
+ # - output=$(npm run uat-search_indexing)
197
+ # - echo "$output"
198
+ # - node ../ValidateUATReport.js examples
199
+
200
+ # artifacts:
201
+ # when: always
202
+ # paths:
203
+ # - examples/uat/playwright-report
204
+
205
+
191
206
 
package/README.md CHANGED
@@ -17,7 +17,45 @@
17
17
 
18
18
  - npm run report
19
19
 
20
- ## Version History
20
+ ### v3.2.15 - 14-11-2025
21
+
22
+ #### Enhancement
23
+
24
+ - Aborted test results are now merged into the `.last-run.json` file.
25
+ This ensures that any timed-out tests are included in the next retry cycle.
26
+
27
+ ### v3.2.13 - 30-10-2025
28
+
29
+ #### Enhancement
30
+
31
+ - A teardown option has been introduced in the configuration to manage and clean up login sessions stored in the NFS environment.
32
+
33
+ ### Issue fix
34
+
35
+ - Custom teardown comment provided
36
+
37
+ ### v3.2.11 - 13-10-2025
38
+
39
+ ### Feature
40
+
41
+ - New step a search entity using {string} provided for search indexing, This step will use run time data generation response as input for the indexing
42
+
43
+ ### Issue fix
44
+ - Custom teardown comment provided
45
+
46
+ ### v3.2.10 - 09-10-2025
47
+
48
+ #### Enhancement
49
+ - A teardown option has been introduced in the configuration to manage and clean up login sessions stored in the NFS environment.
50
+
51
+
52
+ ### v3.2.9 - 26-09-2025
53
+
54
+ ### Enhancement
55
+
56
+ - Authentication deatils for data generation can be configured in org level
57
+ - reference link : https://learn.zoho.in/portal/zohocorp/knowledge/manual/client-uat/article/data-generation#_Tocpd3n7yt9ngeg
58
+
21
59
 
22
60
  ### v3.2.8 - 18-09-2025
23
61
 
@@ -39,6 +77,7 @@
39
77
  - Multi-actor execution support – now possible to switch between multiple profile agents within scenarios using the predefined step: - `access the {string} profile page`
40
78
 
41
79
  ### Bug fix
80
+
42
81
  - Fixed the issue where localapp and hcapp UAT were not running properly.
43
82
 
44
83
  ### v3.2.5 - 28-08-2025
@@ -1,5 +1,6 @@
1
1
  import { test } from '@zohodesk/testinglibrary';
2
2
  import DataGenerator from '@zohodesk/testinglibrary/DataGenerator';
3
+ import {getUserForSelectedEditionAndProfile} from '@zohodesk/testinglibrary/helpers'
3
4
 
4
5
  const dataGenerator = new DataGenerator();
5
6
 
@@ -9,7 +10,8 @@ export async function generateAndCacheTestData(executionContext, type, identifie
9
10
  const scenarioName = testInfo.title.split('/').pop() || 'Unknown Scenario';
10
11
 
11
12
  if (profile) {
12
- actorInfo = await dataGenerator.getDataGenUserExecutionContext(executionContext.actorInfo.edition, profile);
13
+ const { edition, orgName: portal, beta } = executionContext.actorInfo;
14
+ actorInfo = await getUserForSelectedEditionAndProfile(edition, profile, beta, portal);
13
15
  } else {
14
16
  actorInfo = executionContext.actorInfo;
15
17
  }
@@ -30,11 +30,22 @@ async function entityIdReConstructor(payload) {
30
30
  if (typeof payload !== 'object' || payload === null) {
31
31
  throw new Error('Invalid payload. It must be a non-null object.');
32
32
  }
33
- if (!payload.arguments || typeof payload.arguments.entityId !== 'string') {
34
- throw new Error('Invalid payload.arguments.entityId. It must be a non-empty string.');
33
+
34
+ if (!payload.arguments || (!payload.arguments.entityId)) {
35
+ throw new Error('Invalid payload.arguments.entityId. It must be a non-empty string or array of strings.');
36
+ }
37
+
38
+ const entityId = payload.arguments.entityId;
39
+
40
+ // If it's already an array, validate and clean it
41
+ if (Array.isArray(entityId)) {
42
+ payload.arguments.entityId = entityId.map(id => id.trim());
43
+ }
44
+ // If it's a string, split and convert to array
45
+ else if (typeof entityId === 'string') {
46
+ payload.arguments.entityId = entityId.split(',').map(id => id.trim());
35
47
  }
36
48
 
37
- payload.arguments.entityId = payload.arguments.entityId.split(',').map(id => id.trim());
38
49
  return payload;
39
50
  }
40
51
 
@@ -1,8 +1,14 @@
1
1
  import {createBdd } from '@zohodesk/testinglibrary';
2
2
  import { executeRpcRequest , entityIdReConstructor } from '../helpers/rpcRequestHelper';
3
+ // import jp from 'jsonpath';
3
4
 
4
5
  const { Given } = createBdd();
5
6
 
7
+
8
+ // Given a search entity
9
+ // | moduleName | entityId | entityName | searchString |
10
+ // | contact | 122000006785675, 122000007141665, 122000006636472 | QA Team | testinguat |
11
+
6
12
  Given('a search entity', async ({page}, dataTable)=>{
7
13
  const data = dataTable.hashes();
8
14
 
@@ -22,5 +28,50 @@ Given('a search entity', async ({page}, dataTable)=>{
22
28
 
23
29
  await executeRpcRequest(page, payload);
24
30
  }
25
-
26
31
  });
32
+
33
+ // Given data generation step
34
+ // Given a search entity using "C1"
35
+ // | moduleName | searchString | searchEntity (response of the previous data generation step) |
36
+ // | contact | testinguat | $.id |
37
+ // | contact | testinguat | $.ids |
38
+ // | contact | testinguat |
39
+
40
+ Given('a search entity using {string}', async ({page,cacheLayer}, reference,dataTable)=>{
41
+ const data = dataTable.hashes();
42
+
43
+ const row = data[0];
44
+ if (!row || !row.moduleName || !row.searchString) {
45
+ throw new Error('Invalid or missing data in dataTable');
46
+ }
47
+
48
+ const { moduleName, searchEntity, searchString } = row;
49
+
50
+ const searchObj = cacheLayer.get(reference);
51
+ let entityIdValue;
52
+
53
+ if (typeof searchObj === 'string') {
54
+ entityIdValue = searchObj;
55
+ } else {
56
+ const jsonPath = searchEntity?.startsWith?.('$') ? searchEntity : `$.${searchEntity}`;
57
+ const result = null;//jp.query(searchObj, jsonPath);
58
+
59
+ if (!result || result.length === 0) {
60
+ throw new Error(`JSONPath query '${jsonPath}' returned no results from cache object for reference: ${reference}`);
61
+ }
62
+
63
+ entityIdValue = result.length === 1 ? result[0] : result;
64
+ }
65
+
66
+ const payload = {
67
+ className: 'applicationDriver.rpc.desk.integrations.search.SearchFakeDataPopulator',
68
+ methodName: 'populateSearchData',
69
+ arguments: {
70
+ module: moduleName,
71
+ searchString: searchString,
72
+ entityId: entityIdValue
73
+ }
74
+ };
75
+ await entityIdReConstructor(payload);
76
+ await executeRpcRequest(page, payload);
77
+ });
@@ -47,15 +47,6 @@ class DataGenerator {
47
47
  throw error;
48
48
  }
49
49
  }
50
- async getDataGenUserExecutionContext(edition, profile) {
51
- try {
52
- const dataGenUserDetails = await (0, _helpers.getUserForSelectedEditionAndProfile)(edition, profile);
53
- return dataGenUserDetails;
54
- } catch (error) {
55
- console.error('Error occurred while fetching data generation user details: ', error);
56
- throw error;
57
- }
58
- }
59
50
  }
60
51
  async function _getGenerator(testInfo, generatorName) {
61
52
  let generator = null;
@@ -0,0 +1,11 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.default = void 0;
7
+ class ReporterConstants {
8
+ static DEFAULT_REPORTER_PATH = 'uat/test-results/playwright-test-results.json';
9
+ static LAST_RUN_REPORTER_PATH = 'uat/test-results/.last-run.json';
10
+ }
11
+ exports.default = ReporterConstants;
@@ -4,4 +4,4 @@ Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
6
  exports.CUSTOM_COMMANDS = void 0;
7
- const CUSTOM_COMMANDS = exports.CUSTOM_COMMANDS = ['mode', 'tags', 'edition', 'browsers', 'filePath', 'headless', 'modules'];
7
+ const CUSTOM_COMMANDS = exports.CUSTOM_COMMANDS = ['mode', 'tags', 'edition', 'browsers', 'filePath', 'headless', 'modules', 'isTearDown'];
@@ -113,6 +113,7 @@ function getUserForSelectedEditionAndProfile(preferedEdition, preferredProfile,
113
113
  }
114
114
  return {
115
115
  ...editionData,
116
- ...selectedProfile
116
+ ...selectedProfile,
117
+ 'beta': betaFeature
117
118
  };
118
119
  }
@@ -10,7 +10,6 @@ var _fileMutex = _interopRequireDefault(require("../fileMutex"));
10
10
  var _fileMutexConfig = require("../../constants/fileMutexConfig");
11
11
  var _checkAuthCookies = require("./checkAuthCookies");
12
12
  var _checkAuthDirectory = require("../checkAuthDirectory");
13
- var _logger = require("../../../../utils/logger");
14
13
  /* eslint-disable no-console */
15
14
 
16
15
  async function performLoginSteps(testInfo, isLoggedIn, loginSteps) {
@@ -26,7 +25,7 @@ async function performLoginSteps(testInfo, isLoggedIn, loginSteps) {
26
25
  let loginUsingCookie = false;
27
26
  try {
28
27
  if ((0, _checkAuthCookies.verifyIfCookieFileExists)(authFile)) {
29
- _logger.Logger.log(_logger.Logger.INFO_TYPE, `${email} Cookie file exists. Loading cookies, worker index - ${process.env.TEST_WORKER_INDEX}`);
28
+ console.log(`${email} Cookie file exists. Loading cookies, worker index - ${process.env.TEST_WORKER_INDEX}`);
30
29
  loginUsingCookie = true;
31
30
  } else {
32
31
  await fileMutex.acquire();
@@ -41,7 +40,7 @@ async function performLoginSteps(testInfo, isLoggedIn, loginSteps) {
41
40
  });
42
41
  }
43
42
  } catch (error) {
44
- _logger.Logger.log(_logger.Logger.FAILURE_TYPE, `Error during login for ${email}:`, error);
43
+ console.error(`Error during login for ${email}:`, error);
45
44
  } finally {
46
45
  if (!loginUsingCookie) {
47
46
  await fileMutex.release();
@@ -7,7 +7,6 @@ Object.defineProperty(exports, "__esModule", {
7
7
  exports.default = void 0;
8
8
  var _path = _interopRequireDefault(require("path"));
9
9
  var _fs = require("fs");
10
- var _logger = require("../../../utils/logger");
11
10
  function _classPrivateMethodInitSpec(e, a) { _checkPrivateRedeclaration(e, a), a.add(e); }
12
11
  function _checkPrivateRedeclaration(e, t) { if (t.has(e)) throw new TypeError("Cannot initialize the same private elements twice on an object"); }
13
12
  function _assertClassBrand(e, t, n) { if ("function" == typeof e ? e === t : e.has(t)) return arguments.length < 3 ? t : n; throw new TypeError("Private element is not present on this object"); }
@@ -25,7 +24,7 @@ class FileMutex {
25
24
  return new Promise((resolve, reject) => {
26
25
  if (!(0, _fs.existsSync)(this.lockFilePath)) {
27
26
  (0, _fs.writeFileSync)(this.lockFilePath, 'locked');
28
- _logger.Logger.log(_logger.Logger.INFO_TYPE, `Lock file created: ${this.lockFilePath}, worker index - ${process.env.TEST_WORKER_INDEX}`);
27
+ console.log(`Lock file created: ${this.lockFilePath}, worker index - ${process.env.TEST_WORKER_INDEX}`);
29
28
  return resolve();
30
29
  }
31
30
  const timeout = setTimeout(() => {
@@ -36,12 +35,12 @@ class FileMutex {
36
35
  try {
37
36
  if (eventType === 'rename' && filename === this.lockFileName) {
38
37
  clearTimeout(timeout);
39
- _logger.Logger.log(_logger.Logger.INFO_TYPE, `Lock file deleted! Proceeding, worker index - ${process.env.TEST_WORKER_INDEX}`);
38
+ console.log(`Lock file deleted! Proceeding, worker index - ${process.env.TEST_WORKER_INDEX}`);
40
39
  watcher.close();
41
40
  resolve();
42
41
  }
43
42
  } catch (err) {
44
- _logger.Logger.log(_logger.Logger.FAILURE_TYPE, `Error watching for lock file deletion: ${err.message}`);
43
+ console.error(`Error watching for lock file deletion: ${err.message}`);
45
44
  watcher.close();
46
45
  }
47
46
  });
@@ -51,10 +50,10 @@ class FileMutex {
51
50
  try {
52
51
  if ((0, _fs.existsSync)(this.lockFilePath)) {
53
52
  (0, _fs.unlinkSync)(this.lockFilePath);
54
- _logger.Logger.log(_logger.Logger.INFO_TYPE, `Lock file deleted: ${this.lockFilePath}, worker index - ${process.env.TEST_WORKER_INDEX}`);
53
+ console.log(`Lock file deleted: ${this.lockFilePath}, worker index - ${process.env.TEST_WORKER_INDEX}`);
55
54
  }
56
55
  } catch (err) {
57
- _logger.Logger.log(_logger.Logger.FAILURE_TYPE, `Error deleting lock file: ${err.message}, worker index - ${process.env.TEST_WORKER_INDEX}`);
56
+ console.error(`Error deleting lock file: ${err.message}, worker index - ${process.env.TEST_WORKER_INDEX}`);
58
57
  throw err;
59
58
  }
60
59
  }
@@ -19,6 +19,7 @@ var _ConfigurationHelper = require("./configuration/ConfigurationHelper");
19
19
  let cachedConfig = null;
20
20
  function getDefaultConfig() {
21
21
  return {
22
+ isTearDown: true,
22
23
  uatDirectory: _path.default.join(process.cwd(), 'uat'),
23
24
  headless: false,
24
25
  browsers: ['Chrome'],
@@ -0,0 +1,78 @@
1
+ "use strict";
2
+
3
+ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
4
+ Object.defineProperty(exports, "__esModule", {
5
+ value: true
6
+ });
7
+ exports.default = mergeAbortedTestsIntoLastRun;
8
+ var _fs = _interopRequireDefault(require("fs"));
9
+ var _path = _interopRequireDefault(require("path"));
10
+ var _logger = require("../../../../utils/logger");
11
+ var _fileUtils = require("../../../../utils/fileUtils");
12
+ var _reporterConstants = _interopRequireDefault(require("../../constants/reporterConstants"));
13
+ function mergeAbortedTestsIntoLastRun() {
14
+ let resultsFile = _path.default.resolve(process.cwd(), _reporterConstants.default.DEFAULT_REPORTER_PATH),
15
+ lastRunFile = _path.default.resolve(process.cwd(), _reporterConstants.default.LAST_RUN_REPORTER_PATH);
16
+ try {
17
+ let report;
18
+ try {
19
+ report = JSON.parse(_fs.default.readFileSync(resultsFile, 'utf-8'));
20
+ } catch (e) {
21
+ _logger.Logger.log(_logger.Logger.FAILURE_TYPE, `Failed to parse results file: ${resultsFile}`, e);
22
+ return;
23
+ }
24
+ const abortedTests = collectAbortedSpecIds(report);
25
+ let lastRunData = {
26
+ status: 'passed',
27
+ failedTests: []
28
+ };
29
+ if (_fs.default.existsSync(lastRunFile)) {
30
+ try {
31
+ const parsed = JSON.parse(_fs.default.readFileSync(lastRunFile, 'utf-8'));
32
+ lastRunData.status = parsed.status || lastRunData.status;
33
+ lastRunData.failedTests = Array.isArray(parsed.failedTests) ? parsed.failedTests : [];
34
+ } catch (e) {
35
+ _logger.Logger.log(_logger.Logger.FAILURE_TYPE, `Failed to parse existing last-run file: ${lastRunFile}`, e);
36
+ }
37
+ }
38
+
39
+ // Merge existing failed tests + aborted tests
40
+ const failedSet = new Set(lastRunData.failedTests);
41
+ for (const id of abortedTests) {
42
+ failedSet.add(id);
43
+ }
44
+ lastRunData.failedTests = [...failedSet];
45
+ lastRunData.status = failedSet.size > 0 ? 'failed' : lastRunData.status;
46
+ (0, _fileUtils.writeFileContents)(lastRunFile, JSON.stringify(lastRunData, null, 2));
47
+ _logger.Logger.log(_logger.Logger.INFO_TYPE, `Updated ${abortedTests.size} aborted tests in .last-run.json file \n`);
48
+ return lastRunData;
49
+ } catch (err) {
50
+ _logger.Logger.log(_logger.Logger.FAILURE_TYPE, `Error updating .last-run.json: ${err.message}`);
51
+ }
52
+ }
53
+ function collectAbortedSpecIds(report) {
54
+ const aborted = new Set();
55
+ if (!Array.isArray(report.suites)) {
56
+ return aborted;
57
+ }
58
+ const isAbortedSpec = spec => {
59
+ var _spec$tests;
60
+ const tags = Array.isArray(spec.tags) ? spec.tags : [];
61
+ return (_spec$tests = spec.tests) === null || _spec$tests === void 0 ? void 0 : _spec$tests.some(t => !tags.includes('skip') && t.projectName === 'chromium' && t.status === 'skipped');
62
+ };
63
+ const testResultsObj = report.suites;
64
+ while (testResultsObj.length > 0) {
65
+ const suite = testResultsObj.pop();
66
+ if (Array.isArray(suite.specs)) {
67
+ for (const spec of suite.specs) {
68
+ if (spec && isAbortedSpec(spec)) {
69
+ aborted.add(spec.id);
70
+ }
71
+ }
72
+ }
73
+ if (Array.isArray(suite.suites)) {
74
+ for (const child of suite.suites) testResultsObj.push(child);
75
+ }
76
+ }
77
+ return aborted;
78
+ }
@@ -32,7 +32,6 @@ class SpawnRunner extends _Runner.default {
32
32
  }
33
33
  runPreprocessing() {
34
34
  console.log("Node version:", process.version);
35
- _logger.Logger.log(_logger.Logger.SUCCESS_TYPE, "Node version- " + process.version);
36
35
  //This below functoin is called to copy the data generator spec files to the current project
37
36
  (0, _commonUtils.copyCommonSpecs)();
38
37
  const {
@@ -0,0 +1,35 @@
1
+ "use strict";
2
+
3
+ class Project {
4
+ constructor(name) {
5
+ this.properties = {};
6
+ this.properties.name = name;
7
+ }
8
+ setTestDir(value) {
9
+ this.properties.testDir = value;
10
+ }
11
+ setTestMatch(value) {
12
+ this.properties.testMatch = value;
13
+ }
14
+ setRetries(value) {
15
+ this.properties.retries = value;
16
+ }
17
+ setUse(value) {
18
+ this.properties.use = value;
19
+ }
20
+ setTearDown(value) {
21
+ this.properties.teardown = value;
22
+ }
23
+ setDependencies(value) {
24
+ this.properties.dependencies = value;
25
+ }
26
+ setProperty(key, value) {
27
+ this.properties[key] = value;
28
+ }
29
+ getProperties() {
30
+ return this.properties;
31
+ }
32
+ }
33
+ module.exports = {
34
+ Project
35
+ };
@@ -0,0 +1,80 @@
1
+ "use strict";
2
+
3
+ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
4
+ Object.defineProperty(exports, "__esModule", {
5
+ value: true
6
+ });
7
+ exports.cleanupConfig = cleanupConfig;
8
+ exports.setupConfig = setupConfig;
9
+ exports.smokeTestConfig = smokeTestConfig;
10
+ var _path = _interopRequireDefault(require("path"));
11
+ var _Project = require("./Project");
12
+ var _configUtils = require("./config-utils");
13
+ var _readConfigFile = require("../readConfigFile");
14
+ const uatConfig = (0, _readConfigFile.generateConfigFromFile)();
15
+ const {
16
+ isAuthMode,
17
+ isSmokeTest,
18
+ bddMode,
19
+ authFilePath,
20
+ trace,
21
+ video,
22
+ testIdAttribute,
23
+ viewport
24
+ } = uatConfig;
25
+ function setupConfig() {
26
+ const setupProject = new _Project.Project('setup');
27
+ setupProject.setTestMatch(/.*\.setup\.js/);
28
+ setupProject.setTestDir(_path.default.join(process.cwd(), 'uat'));
29
+ const isTearDown = JSON.parse(process.env.tearDown);
30
+ setupProject.setTearDown(isTearDown ? 'cleanup' : '');
31
+ const setupProjectConfig = [setupProject.getProperties()];
32
+ return setupProjectConfig;
33
+ }
34
+ function smokeTestConfig() {
35
+ const smokeTestProject = new _Project.Project('smokeTest');
36
+ const smokeTestDir = (0, _configUtils.getTestDir)(bddMode, {
37
+ featureFilesFolder: _path.default.join(process.cwd(), 'uat', 'smokeTest', '**', '*.feature'),
38
+ stepDefinitionsFolder: _path.default.join(process.cwd(), 'uat', '**', 'steps', '*.spec.js'),
39
+ outputDir: _path.default.join(process.cwd(), 'uat', '.features-smoke-gen'),
40
+ uatPath: _path.default.join(process.cwd(), 'uat', 'smokeTest')
41
+ });
42
+ const commonConfig = {
43
+ storageState: isAuthMode ? (0, _readConfigFile.getAuthFilePath)(_path.default.resolve(process.cwd(), authFilePath)) : {}
44
+ };
45
+ smokeTestProject.setTestDir(smokeTestDir);
46
+ smokeTestProject.setRetries(0);
47
+ smokeTestProject.setUse({
48
+ ...commonConfig
49
+ });
50
+ smokeTestProject.setDependencies(isAuthMode ? ['setup'] : []);
51
+ const smokeTestProjectConfig = [smokeTestProject.getProperties()];
52
+ return smokeTestProjectConfig;
53
+ }
54
+ function defaultConfig() {
55
+ const defaultProject = new _Project.Project('default');
56
+ const testDir = (0, _configUtils.getTestDir)(bddMode, {
57
+ featureFilesFolder: (0, _configUtils.getPathsForFeatureFiles)(process.cwd()),
58
+ stepDefinitionsFolder: _path.default.join(process.cwd(), 'uat', '**', 'steps', '*.spec.js'),
59
+ outputDir: _path.default.join(process.cwd(), 'uat', '.features-gen'),
60
+ uatPath: _path.default.join(process.cwd(), 'uat')
61
+ });
62
+ const use = {
63
+ trace,
64
+ video,
65
+ viewport,
66
+ testIdAttribute
67
+ };
68
+ defaultProject.setUse(use);
69
+ defaultProject.setTestDir(testDir);
70
+ defaultProject.setDependencies(isSmokeTest ? ['smokeTest'] : []);
71
+ const defaultProjectConfig = [defaultProject.getProperties()];
72
+ return defaultProjectConfig;
73
+ }
74
+ function cleanupConfig() {
75
+ const cleanupProject = new _Project.Project('cleanup');
76
+ cleanupProject.setTestMatch(/.*\.teardown\.js/);
77
+ cleanupProject.setTestDir(_path.default.join(process.cwd(), 'uat'));
78
+ const cleanupProjectConfig = [cleanupProject.getProperties()];
79
+ return cleanupProjectConfig;
80
+ }
@@ -9,25 +9,24 @@ var _test = require("@playwright/test");
9
9
  var _path = _interopRequireDefault(require("path"));
10
10
  var _readConfigFile = require("../readConfigFile");
11
11
  var _configUtils = require("./config-utils");
12
+ var _ProjectConfiguration = require("./ProjectConfiguration");
12
13
  const uatConfig = (0, _readConfigFile.generateConfigFromFile)();
13
14
  const {
15
+ bddMode,
14
16
  browsers,
15
17
  isSmokeTest,
16
- trace,
17
- video,
18
18
  isAuthMode,
19
19
  openReportOn,
20
20
  reportPath,
21
- bddMode,
22
21
  expectTimeout,
23
22
  testTimeout,
24
23
  authFilePath,
25
24
  viewport,
26
- featureFilesFolder,
27
- stepDefinitionsFolder,
28
- testIdAttribute,
29
25
  globalTimeout,
30
- customReporter
26
+ customReporter,
27
+ trace,
28
+ video,
29
+ testIdAttribute
31
30
  } = uatConfig;
32
31
  const projects = (0, _configUtils.getProjects)({
33
32
  browsers,
@@ -38,18 +37,6 @@ const projects = (0, _configUtils.getProjects)({
38
37
  testTimeout,
39
38
  viewport
40
39
  });
41
- const testDir = (0, _configUtils.getTestDir)(bddMode, {
42
- featureFilesFolder: (0, _configUtils.getPathsForFeatureFiles)(process.cwd()),
43
- stepDefinitionsFolder: _path.default.join(process.cwd(), 'uat', '**', 'steps', '*.spec.js'),
44
- outputDir: _path.default.join(process.cwd(), 'uat', '.features-gen'),
45
- uatPath: _path.default.join(process.cwd(), 'uat')
46
- });
47
- const use = {
48
- trace,
49
- video,
50
- viewport,
51
- testIdAttribute
52
- };
53
40
  let reporter = [['html', {
54
41
  outputFolder: reportPath,
55
42
  open: openReportOn
@@ -66,29 +53,23 @@ if (customReporter) {
66
53
  * @returns {import('@playwright/test').PlaywrightTestConfig}
67
54
  */
68
55
 
56
+ const use = {
57
+ trace,
58
+ video,
59
+ viewport,
60
+ testIdAttribute
61
+ };
62
+ const testDir = (0, _configUtils.getTestDir)(bddMode, {
63
+ featureFilesFolder: (0, _configUtils.getPathsForFeatureFiles)(process.cwd()),
64
+ stepDefinitionsFolder: _path.default.join(process.cwd(), 'uat', '**', 'steps', '*.spec.js'),
65
+ outputDir: _path.default.join(process.cwd(), 'uat', '.features-gen'),
66
+ uatPath: _path.default.join(process.cwd(), 'uat')
67
+ });
69
68
  function getPlaywrightConfig() {
70
- const commonConfig = {
71
- storageState: isAuthMode ? (0, _readConfigFile.getAuthFilePath)(_path.default.resolve(process.cwd(), authFilePath)) : {}
72
- };
73
- const dependencies = isAuthMode ? ['setup'] : [];
74
- const smokeTestProject = isSmokeTest ? smokeTestConfig() : [];
75
- function smokeTestConfig() {
76
- const smokeTestDir = (0, _configUtils.getTestDir)(bddMode, {
77
- featureFilesFolder: _path.default.join(process.cwd(), 'uat', 'smokeTest', '**', '*.feature'),
78
- stepDefinitionsFolder: _path.default.join(process.cwd(), 'uat', '**', 'steps', '*.spec.js'),
79
- outputDir: _path.default.join(process.cwd(), 'uat', '.features-smoke-gen'),
80
- uatPath: _path.default.join(process.cwd(), 'uat', 'smokeTest')
81
- });
82
- return [{
83
- name: 'smokeTest',
84
- testDir: smokeTestDir,
85
- use: {
86
- ...commonConfig
87
- },
88
- dependencies: dependencies,
89
- retries: 0
90
- }];
91
- }
69
+ const smokeTestProject = isSmokeTest ? (0, _ProjectConfiguration.smokeTestConfig)() : [];
70
+ const setupProject = isAuthMode ? (0, _ProjectConfiguration.setupConfig)() : [];
71
+ const isTearDown = JSON.parse(process.env.tearDown);
72
+ const cleanupProject = isTearDown ? (0, _ProjectConfiguration.cleanupConfig)() : [];
92
73
  const playwrightConfig = {
93
74
  testDir,
94
75
  globalTimeout: globalTimeout || 3600000,
@@ -100,16 +81,7 @@ function getPlaywrightConfig() {
100
81
  timeout: expectTimeout
101
82
  },
102
83
  use,
103
- projects: isAuthMode ? [{
104
- name: 'setup',
105
- testMatch: /.*\.setup\.js/,
106
- testDir: _path.default.join(process.cwd(), 'uat'),
107
- teardown: 'cleanup'
108
- }, ...smokeTestProject, {
109
- name: 'cleanup',
110
- testMatch: /.*\.teardown\.js/,
111
- testDir: _path.default.join(process.cwd(), 'uat')
112
- }, ...projects] : [...projects, ...smokeTestProject],
84
+ projects: [...setupProject, ...smokeTestProject, ...projects, ...cleanupProject],
113
85
  ...uatConfig
114
86
  };
115
87
  return playwrightConfig;
@@ -11,6 +11,7 @@ var _fileUtils = require("../../../utils/fileUtils");
11
11
  var _readConfigFile = require("../readConfigFile");
12
12
  var _logger = require("../../../utils/logger");
13
13
  var _configFileNameProvider = require("../helpers/configFileNameProvider");
14
+ var _mergeAbortedTests = _interopRequireDefault(require("../reporter/helpers/mergeAbortedTests"));
14
15
  class JSONSummaryReporter {
15
16
  constructor() {
16
17
  this.durationInMS = -1;
@@ -123,6 +124,8 @@ class JSONSummaryReporter {
123
124
  (0, _fileUtils.writeFileContents)(_path.default.join(reportPath, './', (0, _configFileNameProvider.getReportFileName)()), JSON.stringify(this, null, ' '));
124
125
  }
125
126
  onExit() {
127
+ // Update .last-run.json with aborted tests due to timing out or interruption
128
+ (0, _mergeAbortedTests.default)();
126
129
  const shouldClearLastLine = this._open !== 'always' || this._open !== 'on-failure';
127
130
  if (shouldClearLastLine) {
128
131
  /**Below code is to replace the playwright default report commond with abstraction tool command */
@@ -90,9 +90,11 @@ function main() {
90
90
  // overriding the user config's from CLI
91
91
  uatConfig.addAll(userArgConfig);
92
92
  const modules = uatConfig.get('modules');
93
+ const tearDown = uatConfig.get('isTearDown');
93
94
 
94
95
  //We need to change this process.env variable to pass the module name in future.
95
96
  process.env.modules = modules;
97
+ process.env.tearDown = tearDown;
96
98
  const {
97
99
  isAuthMode,
98
100
  editionOrder,
@@ -22,7 +22,7 @@ class LoggerImpl {
22
22
  info() {}
23
23
  log(type, message) {
24
24
  const color = this.colors[type];
25
- this.consoleLogger.log(`${color[0]}${message}${color[1]}`);
25
+ this.consoleLogger.log(`${color[0]}${message}${color[1]}\n`);
26
26
  }
27
27
  }
28
28
  const Logger = exports.Logger = new LoggerImpl();