@zohodesk/testinglibrary 0.0.12-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 +13 -13
- package/README.md +18 -0
- package/build/common/data-generator/steps/DataGeneratorStepsHelper.js +3 -1
- package/build/core/dataGenerator/DataGenerator.js +0 -9
- package/build/core/playwright/constants/reporterConstants.js +11 -0
- package/build/core/playwright/helpers/auth/getUsers.js +2 -1
- package/build/core/playwright/helpers/auth/loginSteps.js +2 -3
- package/build/core/playwright/helpers/fileMutex.js +5 -6
- package/build/core/playwright/reporter/helpers/mergeAbortedTests.js +78 -0
- package/build/core/playwright/setup/custom-reporter.js +3 -0
- package/build/utils/logger.js +1 -1
- package/npm-shrinkwrap.json +712 -725
- package/package.json +7 -7
- package/zohodesk-testinglibrary-0.0.10-n20-experimental.tgz +0 -0
- package/zohodesk-testinglibrary-0.0.11-n20-experimental.tgz +0 -0
- package/zohodesk-testinglibrary-3.2.13.tgz +0 -0
package/.gitlab-ci.yml
CHANGED
|
@@ -188,19 +188,19 @@ uat-data_generator:
|
|
|
188
188
|
paths:
|
|
189
189
|
- examples/uat/playwright-report
|
|
190
190
|
|
|
191
|
-
uat-search_indexing:
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
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
204
|
|
|
205
205
|
|
|
206
206
|
|
package/README.md
CHANGED
|
@@ -17,6 +17,23 @@
|
|
|
17
17
|
|
|
18
18
|
- npm run report
|
|
19
19
|
|
|
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
|
+
|
|
20
37
|
### v3.2.11 - 13-10-2025
|
|
21
38
|
|
|
22
39
|
### Feature
|
|
@@ -60,6 +77,7 @@
|
|
|
60
77
|
- Multi-actor execution support – now possible to switch between multiple profile agents within scenarios using the predefined step: - `access the {string} profile page`
|
|
61
78
|
|
|
62
79
|
### Bug fix
|
|
80
|
+
|
|
63
81
|
- Fixed the issue where localapp and hcapp UAT were not running properly.
|
|
64
82
|
|
|
65
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
|
-
|
|
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
|
}
|
|
@@ -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;
|
|
@@ -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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
53
|
+
console.log(`Lock file deleted: ${this.lockFilePath}, worker index - ${process.env.TEST_WORKER_INDEX}`);
|
|
55
54
|
}
|
|
56
55
|
} catch (err) {
|
|
57
|
-
|
|
56
|
+
console.error(`Error deleting lock file: ${err.message}, worker index - ${process.env.TEST_WORKER_INDEX}`);
|
|
58
57
|
throw err;
|
|
59
58
|
}
|
|
60
59
|
}
|
|
@@ -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
|
+
}
|
|
@@ -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 */
|
package/build/utils/logger.js
CHANGED
|
@@ -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();
|