artes 1.5.9 → 1.5.11
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/README.md +21 -3
- package/cucumber.config.js +16 -14
- package/executer.js +58 -33
- package/package.json +1 -1
- package/src/helper/controller/elementController.js +4 -7
- package/src/helper/controller/findDuplicateTestNames.js +60 -46
- package/src/helper/controller/getEnvInfo.js +77 -64
- package/src/helper/controller/getExecutor.js +24 -23
- package/src/helper/controller/reportCustomizer.js +174 -74
- package/src/helper/controller/reportUploader.js +33 -0
- package/src/helper/controller/screenComparer.js +97 -74
- package/src/helper/controller/status-formatter.js +34 -35
- package/src/helper/controller/testCoverageCalculator.js +79 -76
- package/src/helper/executers/cleaner.js +4 -6
- package/src/helper/executers/helper.js +17 -2
- package/src/helper/executers/projectCreator.js +11 -6
- package/src/helper/executers/reportGenerator.js +17 -8
- package/src/helper/imports/commons.js +3 -3
- package/src/helper/stepFunctions/APIActions.js +2 -2
- package/src/helper/stepFunctions/assertions.js +91 -87
- package/src/helper/stepFunctions/elementInteractions.js +1 -1
- package/src/helper/stepFunctions/mouseActions.js +2 -1
- package/src/hooks/hooks.js +51 -46
- package/src/stepDefinitions/API.steps.js +3 -3
- package/src/stepDefinitions/assertions.steps.js +355 -205
- package/src/stepDefinitions/keyboardActions.steps.js +8 -9
- package/src/stepDefinitions/mouseActions.steps.js +35 -35
- package/src/stepDefinitions/random.steps.js +7 -4
package/README.md
CHANGED
|
@@ -115,9 +115,14 @@ npx artes [options]
|
|
|
115
115
|
| `-rwt, --reportWithTrace` | Add trace to the report | `artes -rwt` or `artes --reportWithTrace` |
|
|
116
116
|
| `--singleFileReport` | Generate single file allure report | `artes -r --singleFileReport` |
|
|
117
117
|
| `--zip` | Zip the report folder after generation | `artes -r --zip` |
|
|
118
|
+
| `--uploadReport` | Upload the generated report to Artes Reporting System | `artes --uploadReport --reporterURL "https://example.com"` |
|
|
119
|
+
| `--reporterURL` | URL of the Artes Reporting System to upload the report | `artes --uploadReport --reporterURL "https://example.com"` |
|
|
120
|
+
| `--projectName` | Name of the project in the Artes Reporting System (default: `"Artes Report"`) | `artes --uploadReport --reporterURL "https://example.com" --projectName "My Project"` |
|
|
121
|
+
| `--projectType` | Type of the project for reporting purposes (default: `"Artes"`) | `artes --uploadReport --reporterURL "https://example.com" --projectType "API"` |
|
|
122
|
+
| `--reportPath` | Path to the report zip file to upload (default: `./report.zip`) | `artes --uploadReport --reporterURL "https://example.com" --reportPath "./my_report.zip"` |
|
|
118
123
|
| 🖼️ `--logo` | Set a custom logo in the report sidebar. Accepts an absolute path, a relative path, or a direct image URL | `artes --logo /abs/path/logo.png`<br>`artes --logo logo.png`<br>`artes --logo 'https://example.com/logo.png'` |
|
|
119
124
|
| 🏢 `--brandName` | Set the brand name displayed next to the logo in the report sidebar | `artes --brandName 'My Company'` |
|
|
120
|
-
| 📄 `--reportName` |
|
|
125
|
+
| 📄 `--reportName` | Report name displayed on the summary widget and in the Artes Reporting System | `artes --reportName 'Alma UI'`
|
|
121
126
|
| 📁 `--features` | Specify one or more feature files' relative paths to run (comma-separated) | `artes --features "tests/features/Alma,tests/features/Banan.feature"` |
|
|
122
127
|
| 📜 `--stepDef` | Specify one or more step definition files' relative paths to use (comma-separated) | `artes --stepDef "tests/steps/login.js,tests/steps/home.js"` |
|
|
123
128
|
| 🔖 `--tags` | Run tests with specified Cucumber tags | `artes --tags "@smoke or @wip"` |
|
|
@@ -615,13 +620,26 @@ Artes supports environment-specific configurations through environment variables
|
|
|
615
620
|
|
|
616
621
|
| Option | Default Value | Description |
|
|
617
622
|
| ------------- | ------------------------------ | ------------------------------------------------------ |
|
|
618
|
-
| `device` | `""`
|
|
623
|
+
| `device` | `""` | [Device List](./docs/emulationDevicesList.md) |
|
|
619
624
|
|
|
620
625
|
|
|
621
|
-
## 📊
|
|
626
|
+
## 📊 Reporting
|
|
622
627
|
|
|
623
628
|
Artes can generate Allure reports. After running tests with the `-r` flag, the reports will be stored in the `report` folder in HTML format. You can view them in your browser after the tests complete.
|
|
624
629
|
|
|
630
|
+
## 📊 Integration with Artes Reporting System
|
|
631
|
+
|
|
632
|
+
Artes has a built-in integration with the Artes Reporting System. By configuring the options below, you can automatically upload your test reports and keep your pipeline stages clean and organized.
|
|
633
|
+
|
|
634
|
+
| **Option** | **Default Value** | **Description** |
|
|
635
|
+
| ---------------- | ----------------------------- | ---------------------------------------------------------------------- |
|
|
636
|
+
| `uploadReport` | `false` | Automatically upload the report to Artes Reporting System after tests. |
|
|
637
|
+
| `reporterURL` | `""` | URL of the Artes Reporting System instance to upload the report to. |
|
|
638
|
+
| `projectName` | `"Artes Report"` | Name of the project in the Artes Reporting System. |
|
|
639
|
+
| `projectType` | `"Artes"` | Type/category of the project (e.g., UI, API). |
|
|
640
|
+
| `reportName` | `"Artes Report"` | Display name of the report in the Artes Reporting System. |
|
|
641
|
+
| `reportPath` | `"./report.zip"` | Path to the report zip file to be uploaded. |
|
|
642
|
+
|
|
625
643
|
---
|
|
626
644
|
|
|
627
645
|
## 🐳 Docker Image for CI/CD
|
package/cucumber.config.js
CHANGED
|
@@ -14,7 +14,11 @@ try {
|
|
|
14
14
|
console.log("Proceeding with default config.");
|
|
15
15
|
}
|
|
16
16
|
|
|
17
|
-
const defaultFormats = [
|
|
17
|
+
const defaultFormats = [
|
|
18
|
+
"rerun:@rerun.txt",
|
|
19
|
+
"progress-bar",
|
|
20
|
+
"./src/helper/controller/status-formatter.js:null",
|
|
21
|
+
];
|
|
18
22
|
|
|
19
23
|
const userFormatsFromEnv = process.env.REPORT_FORMAT
|
|
20
24
|
? JSON.parse(process.env.REPORT_FORMAT)
|
|
@@ -52,7 +56,6 @@ function resolveEnv(artesConfig) {
|
|
|
52
56
|
const env = resolveEnv(artesConfig);
|
|
53
57
|
|
|
54
58
|
function loadVariables(cliVariables, artesConfigVariables) {
|
|
55
|
-
|
|
56
59
|
if (cliVariables) {
|
|
57
60
|
try {
|
|
58
61
|
cliVariables = JSON.parse(cliVariables);
|
|
@@ -72,13 +75,12 @@ function loadVariables(cliVariables, artesConfigVariables) {
|
|
|
72
75
|
|
|
73
76
|
const resolveFeaturePaths = (basePath, value) => {
|
|
74
77
|
return value
|
|
75
|
-
.split(
|
|
76
|
-
.map(p => p.trim())
|
|
78
|
+
.split(",")
|
|
79
|
+
.map((p) => p.trim())
|
|
77
80
|
.filter(Boolean)
|
|
78
|
-
.map(p => path.join(basePath, p));
|
|
81
|
+
.map((p) => path.join(basePath, p));
|
|
79
82
|
};
|
|
80
83
|
|
|
81
|
-
|
|
82
84
|
module.exports = {
|
|
83
85
|
default: {
|
|
84
86
|
// File paths and patterns
|
|
@@ -88,13 +90,13 @@ module.exports = {
|
|
|
88
90
|
timeout: process.env.TIMEOUT
|
|
89
91
|
? Number(process.env.TIMEOUT) * 1000
|
|
90
92
|
: artesConfig.timeout * 1000 || 30 * 1000, // Default timeout in seconds
|
|
91
|
-
|
|
93
|
+
paths: process.env.RERUN
|
|
92
94
|
? [path.join("../../", process.env.RERUN)]
|
|
93
95
|
: process.env.FEATURES
|
|
94
96
|
? resolveFeaturePaths(moduleConfig.projectPath, process.env.FEATURES)
|
|
95
97
|
: artesConfig.features
|
|
96
98
|
? resolveFeaturePaths(moduleConfig.projectPath, artesConfig.features)
|
|
97
|
-
: [moduleConfig.featuresPath], // Paths to feature files
|
|
99
|
+
: [moduleConfig.featuresPath], // Paths to feature files
|
|
98
100
|
require: [
|
|
99
101
|
process.env.STEP_DEFINITIONS
|
|
100
102
|
? [path.join(moduleConfig.projectPath, process.env.STEP_DEFINITIONS)]
|
|
@@ -173,14 +175,14 @@ module.exports = {
|
|
|
173
175
|
},
|
|
174
176
|
report: {
|
|
175
177
|
logo: process.env.LOGO
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
178
|
+
? process.env.LOGO
|
|
179
|
+
: artesConfig?.logo || "./logo.png",
|
|
180
|
+
brandName: process.env.BRAND_NAME
|
|
179
181
|
? process.env.BRAND_NAME
|
|
180
182
|
: artesConfig?.brandName || "ARTES",
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
183
|
+
reportName: process.env.REPORT_NAME
|
|
184
|
+
? process.env.REPORT_NAME
|
|
185
|
+
: artesConfig?.reportName || "ARTES REPORT",
|
|
184
186
|
singleFileReport:
|
|
185
187
|
process.env.SINGLE_FILE_REPORT == "true"
|
|
186
188
|
? true
|
package/executer.js
CHANGED
|
@@ -10,10 +10,15 @@ const {
|
|
|
10
10
|
const { logPomWarnings } = require("./src/helper/controller/pomCollector");
|
|
11
11
|
const fs = require("fs");
|
|
12
12
|
const path = require("path");
|
|
13
|
-
const {
|
|
13
|
+
const {
|
|
14
|
+
testCoverageCalculator,
|
|
15
|
+
} = require("./src/helper/controller/testCoverageCalculator");
|
|
14
16
|
const { getExecutor } = require("./src/helper/controller/getExecutor");
|
|
15
|
-
const {
|
|
17
|
+
const {
|
|
18
|
+
findDuplicateTestNames,
|
|
19
|
+
} = require("./src/helper/controller/findDuplicateTestNames");
|
|
16
20
|
const { getEnvInfo } = require("artes/src/helper/controller/getEnvInfo");
|
|
21
|
+
const { uploadReport } = require("./src/helper/controller/reportUploader");
|
|
17
22
|
|
|
18
23
|
|
|
19
24
|
const artesConfigPath = path.resolve(process.cwd(), "artes.config.js");
|
|
@@ -43,9 +48,14 @@ const flags = {
|
|
|
43
48
|
reportWithTrace: args.includes("-rwt") || args.includes("--reportWithTrace"),
|
|
44
49
|
singleFileReport: args.includes("--singleFileReport"),
|
|
45
50
|
customLogo: args.includes("--logo"),
|
|
46
|
-
customBrandName:args.includes("--brandName"),
|
|
47
|
-
customReportName:args.includes("--reportName"),
|
|
51
|
+
customBrandName: args.includes("--brandName"),
|
|
52
|
+
customReportName: args.includes("--reportName"),
|
|
48
53
|
zip: args.includes("--zip"),
|
|
54
|
+
uploadReport: args.includes("--uploadReport"),
|
|
55
|
+
reporterURL: args.includes("--reporterURL"),
|
|
56
|
+
projectName: args.includes("--projectName"),
|
|
57
|
+
projectType: args.includes("--projectType"),
|
|
58
|
+
reportPath: args.includes("--reportPath"),
|
|
49
59
|
features: args.includes("--features"),
|
|
50
60
|
stepDef: args.includes("--stepDef"),
|
|
51
61
|
tags: args.includes("--tags"),
|
|
@@ -68,9 +78,12 @@ const flags = {
|
|
|
68
78
|
slowMo: args.includes("--slowMo"),
|
|
69
79
|
};
|
|
70
80
|
|
|
71
|
-
|
|
72
81
|
const env = getArgValue("--env");
|
|
73
82
|
const vars = getArgValue("--saveVar");
|
|
83
|
+
const reporterURL = getArgValue("--reporterURL");
|
|
84
|
+
const projectType = getArgValue("--projectType");
|
|
85
|
+
const projectName = getArgValue("--projectName");
|
|
86
|
+
const reportPath = getArgValue("--reportPath");
|
|
74
87
|
const logo = getArgValue("--logo");
|
|
75
88
|
const brandName = getArgValue("--brandName");
|
|
76
89
|
const reportName = getArgValue("--reportName");
|
|
@@ -90,7 +103,6 @@ const height = getArgValue("--height");
|
|
|
90
103
|
const timeout = getArgValue("--timeout");
|
|
91
104
|
const slowMo = getArgValue("--slowMo");
|
|
92
105
|
|
|
93
|
-
|
|
94
106
|
flags.env ? (process.env.ENV = env) : "";
|
|
95
107
|
|
|
96
108
|
vars ? (process.env.VARS = vars) : "";
|
|
@@ -172,9 +184,7 @@ flags.timeout ? (process.env.TIMEOUT = timeout) : "";
|
|
|
172
184
|
|
|
173
185
|
flags.slowMo ? (process.env.SLOWMO = slowMo) : "";
|
|
174
186
|
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
function main() {
|
|
187
|
+
async function main() {
|
|
178
188
|
if (flags.help) return showHelp();
|
|
179
189
|
if (flags.version) return showVersion();
|
|
180
190
|
if (flags.create) return createProject(flags.createYes, flags.noDeps);
|
|
@@ -185,57 +195,72 @@ function main() {
|
|
|
185
195
|
|
|
186
196
|
findDuplicateTestNames();
|
|
187
197
|
|
|
188
|
-
const testCoverage = testCoverageCalculator()
|
|
198
|
+
const testCoverage = testCoverageCalculator();
|
|
189
199
|
|
|
190
|
-
const testPercentage =
|
|
200
|
+
const testPercentage = process.env.PERCENTAGE
|
|
201
|
+
? Number(process.env.PERCENTAGE)
|
|
202
|
+
: artesConfig.testPercentage || 0;
|
|
191
203
|
|
|
192
204
|
if (testPercentage > 0) {
|
|
193
|
-
|
|
194
|
-
const meetsThreshold = testCoverage.percentage >= testPercentage
|
|
205
|
+
const meetsThreshold = testCoverage.percentage >= testPercentage;
|
|
195
206
|
|
|
196
207
|
if (meetsThreshold) {
|
|
197
208
|
console.log(
|
|
198
|
-
|
|
209
|
+
`\x1b[32mTests passed required ${testPercentage}% success rate with ${testCoverage.percentage.toFixed(2)}%!\x1b[0m`,
|
|
199
210
|
);
|
|
200
211
|
process.env.EXIT_CODE = parseInt(0, 10);
|
|
201
212
|
} else {
|
|
202
213
|
console.log(
|
|
203
|
-
|
|
214
|
+
`\x1b[31mTests failed required ${testPercentage}% success rate with ${testCoverage.percentage.toFixed(2)}%!\x1b[0m`,
|
|
204
215
|
);
|
|
205
216
|
process.env.EXIT_CODE = parseInt(1, 10);
|
|
206
217
|
}
|
|
207
218
|
}
|
|
208
219
|
|
|
220
|
+
const source = path.join(
|
|
221
|
+
process.cwd(),
|
|
222
|
+
"node_modules",
|
|
223
|
+
"artes",
|
|
224
|
+
"@rerun.txt",
|
|
225
|
+
);
|
|
226
|
+
const destination = path.join(process.cwd(), "@rerun.txt");
|
|
209
227
|
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
if (fs.existsSync(source)) {
|
|
214
|
-
fs.renameSync(source, destination);
|
|
215
|
-
}
|
|
228
|
+
if (fs.existsSync(source)) {
|
|
229
|
+
fs.renameSync(source, destination);
|
|
230
|
+
}
|
|
216
231
|
|
|
217
232
|
if (
|
|
218
233
|
flags.reportWithTrace ||
|
|
219
234
|
artesConfig.reportWithTrace ||
|
|
220
235
|
flags.report ||
|
|
221
236
|
artesConfig.report
|
|
222
|
-
){
|
|
223
|
-
|
|
237
|
+
) {
|
|
224
238
|
getExecutor();
|
|
225
|
-
getEnvInfo()
|
|
239
|
+
getEnvInfo();
|
|
226
240
|
generateReport();
|
|
227
|
-
|
|
228
241
|
}
|
|
229
242
|
|
|
230
|
-
|
|
243
|
+
if (
|
|
244
|
+
!(process.env.TRACE === "true"
|
|
231
245
|
? process.env.TRACE
|
|
232
|
-
: artesConfig.trace || false)
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
}
|
|
238
|
-
|
|
246
|
+
: artesConfig.trace || false)
|
|
247
|
+
) {
|
|
248
|
+
fs.rmSync(path.join(process.cwd(), "traces"), {
|
|
249
|
+
recursive: true,
|
|
250
|
+
force: true,
|
|
251
|
+
});
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
if (flags.uploadReport || artesConfig.uploadReport) {
|
|
255
|
+
await uploadReport({
|
|
256
|
+
reporterURL: reporterURL || artesConfig.reporterURL,
|
|
257
|
+
projectName: projectName || artesConfig.projectName || "Artes Report",
|
|
258
|
+
projectType: projectType || artesConfig.projectType || "Artes",
|
|
259
|
+
reportName: reportName || artesConfig.reportName || "Artes Report",
|
|
260
|
+
reportPath: reportPath || artesConfig.reportPath || path.join(process.cwd(), "report.zip")
|
|
261
|
+
});
|
|
262
|
+
}
|
|
263
|
+
|
|
239
264
|
cleanUp();
|
|
240
265
|
process.exit(process.env.EXIT_CODE);
|
|
241
266
|
}
|
package/package.json
CHANGED
|
@@ -38,9 +38,8 @@ function selectorSeparator(element) {
|
|
|
38
38
|
}
|
|
39
39
|
}
|
|
40
40
|
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
element = resolveVariable(element)
|
|
41
|
+
function getSelector(element) {
|
|
42
|
+
element = resolveVariable(element);
|
|
44
43
|
|
|
45
44
|
const selector =
|
|
46
45
|
elements?.[element]?.selector || elements?.[element] || element;
|
|
@@ -94,9 +93,7 @@ function getElement(element) {
|
|
|
94
93
|
return locator;
|
|
95
94
|
}
|
|
96
95
|
|
|
97
|
-
|
|
98
96
|
function extractVarsFromResponse(responseBody, vars, customVarNames) {
|
|
99
|
-
|
|
100
97
|
function getValueByPath(obj, path) {
|
|
101
98
|
const keys = path.split(".");
|
|
102
99
|
let current = obj;
|
|
@@ -124,13 +121,13 @@ function extractVarsFromResponse(responseBody, vars, customVarNames) {
|
|
|
124
121
|
.join("");
|
|
125
122
|
}
|
|
126
123
|
|
|
127
|
-
const varPaths = vars.split(",").map(v => v.trim());
|
|
124
|
+
const varPaths = vars.split(",").map((v) => v.trim());
|
|
128
125
|
let customNames = [];
|
|
129
126
|
|
|
130
127
|
if (!customVarNames) {
|
|
131
128
|
customNames = varPaths.map(pathToCamelCase);
|
|
132
129
|
} else if (typeof customVarNames === "string") {
|
|
133
|
-
customNames = customVarNames.split(",").map(n => n.trim());
|
|
130
|
+
customNames = customVarNames.split(",").map((n) => n.trim());
|
|
134
131
|
} else if (Array.isArray(customVarNames)) {
|
|
135
132
|
customNames = customVarNames;
|
|
136
133
|
} else {
|
|
@@ -2,53 +2,67 @@ const fs = require("fs");
|
|
|
2
2
|
const path = require("path");
|
|
3
3
|
|
|
4
4
|
function findDuplicateTestNames() {
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
5
|
+
const testStatusFile = path.join(
|
|
6
|
+
process.cwd(),
|
|
7
|
+
"node_modules",
|
|
8
|
+
"artes",
|
|
9
|
+
"test-status",
|
|
10
|
+
"test-status.txt",
|
|
11
|
+
);
|
|
12
|
+
|
|
13
|
+
if (!fs.existsSync(testStatusFile)) {
|
|
14
|
+
console.error("test-status.txt not found");
|
|
15
|
+
return;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
const content = fs.readFileSync(testStatusFile, "utf8");
|
|
19
|
+
const lines = content.split("\n").filter((line) => line.trim());
|
|
20
|
+
|
|
21
|
+
const testNameToEntries = {};
|
|
22
|
+
|
|
23
|
+
lines.forEach((line) => {
|
|
24
|
+
const parts = line.split(" | ");
|
|
25
|
+
if (parts.length < 5) return;
|
|
26
|
+
|
|
27
|
+
const testName = parts[2].trim();
|
|
28
|
+
const filePath = parts[4].trim();
|
|
29
|
+
const uuid = parts[3].trim();
|
|
30
|
+
|
|
31
|
+
if (!testNameToEntries[testName]) {
|
|
32
|
+
testNameToEntries[testName] = [];
|
|
10
33
|
}
|
|
11
|
-
|
|
12
|
-
const
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
}
|
|
37
|
-
});
|
|
38
|
-
|
|
39
|
-
if (Object.keys(duplicates).length > 0) {
|
|
40
|
-
console.warn('\n\x1b[33m[WARNING] Duplicate scenarios names found: This will effect your reporting');
|
|
41
|
-
Object.entries(duplicates).forEach(([testName, files]) => {
|
|
42
|
-
console.log(`\x1b[33m"${testName}" exists in:`);
|
|
43
|
-
files.forEach(file => {
|
|
44
|
-
console.log(` - ${file}`);
|
|
45
|
-
});
|
|
46
|
-
console.log('');
|
|
34
|
+
|
|
35
|
+
const alreadyExists = testNameToEntries[testName].some(
|
|
36
|
+
(e) => e.uuid === uuid,
|
|
37
|
+
);
|
|
38
|
+
if (!alreadyExists) {
|
|
39
|
+
testNameToEntries[testName].push({ filePath, uuid });
|
|
40
|
+
}
|
|
41
|
+
});
|
|
42
|
+
|
|
43
|
+
const duplicates = {};
|
|
44
|
+
|
|
45
|
+
Object.entries(testNameToEntries).forEach(([testName, entries]) => {
|
|
46
|
+
if (entries.length > 1) {
|
|
47
|
+
duplicates[testName] = entries.map((e) => e.filePath);
|
|
48
|
+
}
|
|
49
|
+
});
|
|
50
|
+
|
|
51
|
+
if (Object.keys(duplicates).length > 0) {
|
|
52
|
+
console.warn(
|
|
53
|
+
"\n\x1b[33m[WARNING] Duplicate scenario names found: This will affect your reporting",
|
|
54
|
+
);
|
|
55
|
+
Object.entries(duplicates).forEach(([testName, files]) => {
|
|
56
|
+
console.log(`\x1b[33m"${testName}" exists in:`);
|
|
57
|
+
files.forEach((file) => {
|
|
58
|
+
console.log(` - ${file}`);
|
|
47
59
|
});
|
|
48
|
-
console.log("
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
return duplicates;
|
|
60
|
+
console.log("");
|
|
61
|
+
});
|
|
62
|
+
console.log("\x1b[0m");
|
|
52
63
|
}
|
|
53
64
|
|
|
54
|
-
|
|
65
|
+
return duplicates;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
module.exports = { findDuplicateTestNames };
|
|
@@ -3,71 +3,84 @@ const fs = require("fs");
|
|
|
3
3
|
const path = require("path");
|
|
4
4
|
const { moduleConfig } = require("artes/src/helper/imports/commons");
|
|
5
5
|
|
|
6
|
-
|
|
7
6
|
async function getEnvInfo() {
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
"Hostname": os.hostname(),
|
|
27
|
-
|
|
28
|
-
// ── Node ────────────────────────────────
|
|
29
|
-
"Node_Version": process.version,
|
|
30
|
-
"NPM_Version": process.env.npm_config_user_agent ?? "N/A",
|
|
31
|
-
"Working_Dir": process.cwd(),
|
|
32
|
-
|
|
33
|
-
// ── Browser ─────────────────────────────
|
|
34
|
-
"Browser_Name": cucumberConfig.browser.browserType,
|
|
35
|
-
"Browser_Version": browserInfo.BROWSER_VERSION,
|
|
36
|
-
"Screen_Size": `w: ${browserInfo.BROWSER_WIDTH}px h:${browserInfo.BROWSER_HEIGHT}px`,
|
|
37
|
-
"Headless": cucumberConfig.browser.headless ?? "N/A",
|
|
38
|
-
|
|
39
|
-
// ── Test Config ─────────────────────────
|
|
40
|
-
"Base_URL": cucumberConfig.baseURL || "N/A",
|
|
41
|
-
"Environment": cucumberConfig.env || "local",
|
|
42
|
-
"Timeout": cucumberConfig.default.timeout ?? "N/A",
|
|
43
|
-
|
|
44
|
-
// ── Git ─────────────────────────────────
|
|
45
|
-
"Git_Branch": process.env.GIT_BRANCH ?? process.env.BRANCH_NAME ?? "N/A",
|
|
46
|
-
"Git_Commit": process.env.GIT_COMMIT ?? process.env.GIT_SHA ?? "N/A",
|
|
47
|
-
"Git_Author": process.env.GIT_AUTHOR ?? "N/A",
|
|
48
|
-
|
|
49
|
-
// ── Timestamps ──────────────────────────
|
|
50
|
-
"Run_Date": new Date().toLocaleDateString(),
|
|
51
|
-
"Run_Time": new Date().toLocaleTimeString(),
|
|
52
|
-
"Timezone": Intl.DateTimeFormat().resolvedOptions().timeZone,
|
|
53
|
-
};
|
|
54
|
-
|
|
55
|
-
const allureResultsDir = path.join(moduleConfig.modulePath, "allure-result");
|
|
56
|
-
|
|
57
|
-
if (!fs.existsSync(allureResultsDir)) {
|
|
58
|
-
fs.mkdirSync(allureResultsDir, { recursive: true });
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
const propertiesContent = Object.entries(environment)
|
|
62
|
-
.map(([key, value]) => `${key}=${value}`)
|
|
63
|
-
.join("\n");
|
|
64
|
-
|
|
65
|
-
fs.writeFileSync(
|
|
66
|
-
path.join(allureResultsDir, "environment.properties"),
|
|
67
|
-
propertiesContent
|
|
7
|
+
delete require.cache[require.resolve("../../../cucumber.config.js")];
|
|
8
|
+
const cucumberConfig = require("../../../cucumber.config.js");
|
|
9
|
+
|
|
10
|
+
let baseURL = "";
|
|
11
|
+
|
|
12
|
+
if (typeof cucumberConfig.baseURL === "object") {
|
|
13
|
+
const env = (cucumberConfig.env || "").trim();
|
|
14
|
+
baseURL = cucumberConfig.baseURL[env];
|
|
15
|
+
} else {
|
|
16
|
+
baseURL = cucumberConfig.baseURL;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
if (fs.existsSync(path.join(moduleConfig.modulePath, "browser-info.json"))) {
|
|
20
|
+
browserInfo = JSON.parse(
|
|
21
|
+
fs.readFileSync(
|
|
22
|
+
path.join(moduleConfig.modulePath, "browser-info.json"),
|
|
23
|
+
"utf8",
|
|
24
|
+
),
|
|
68
25
|
);
|
|
69
|
-
|
|
70
|
-
return environment;
|
|
71
26
|
}
|
|
72
27
|
|
|
73
|
-
|
|
28
|
+
const environment = {
|
|
29
|
+
// ── System ──────────────────────────────
|
|
30
|
+
OS_Name: os.type(),
|
|
31
|
+
OS_Version: os.release(),
|
|
32
|
+
OS_Platform: process.platform,
|
|
33
|
+
OS_Arch: os.arch(),
|
|
34
|
+
CPU_Cores: os.cpus().length,
|
|
35
|
+
CPU_Model: os.cpus()[0]?.model ?? "N/A",
|
|
36
|
+
RAM_Total: `${(os.totalmem() / 1024 / 1024 / 1024).toFixed(2)} GB`,
|
|
37
|
+
RAM_Free: `${(os.freemem() / 1024 / 1024 / 1024).toFixed(2)} GB`,
|
|
38
|
+
Hostname: os.hostname(),
|
|
39
|
+
|
|
40
|
+
// ── Node ────────────────────────────────
|
|
41
|
+
Node_Version: process.version,
|
|
42
|
+
NPM_Version: process.env.npm_config_user_agent ?? "N/A",
|
|
43
|
+
Working_Dir: process.cwd(),
|
|
44
|
+
|
|
45
|
+
// ── Browser ─────────────────────────────
|
|
46
|
+
Browser_Name: cucumberConfig.browser.browserType,
|
|
47
|
+
Browser_Version: browserInfo.BROWSER_VERSION,
|
|
48
|
+
Screen_Size: `w: ${browserInfo.BROWSER_WIDTH}px h:${browserInfo.BROWSER_HEIGHT}px`,
|
|
49
|
+
Headless: cucumberConfig.browser.headless ?? "N/A",
|
|
50
|
+
|
|
51
|
+
// ── Test Config ─────────────────────────
|
|
52
|
+
Base_URL: baseURL || "N/A",
|
|
53
|
+
Environment: cucumberConfig.env || "local",
|
|
54
|
+
Parallel_Runner: cucumberConfig.default.parallel,
|
|
55
|
+
Timeout: cucumberConfig.default.timeout ?? "N/A",
|
|
56
|
+
|
|
57
|
+
// ── Git ─────────────────────────────────
|
|
58
|
+
Git_Branch: process.env.GIT_BRANCH ?? process.env.BRANCH_NAME ?? "N/A",
|
|
59
|
+
Git_Commit: process.env.GIT_COMMIT ?? process.env.GIT_SHA ?? "N/A",
|
|
60
|
+
Git_Author: process.env.GIT_AUTHOR ?? "N/A",
|
|
61
|
+
|
|
62
|
+
// ── Timestamps ──────────────────────────
|
|
63
|
+
Run_Date: new Date().toLocaleDateString(),
|
|
64
|
+
Run_Time: new Date().toLocaleTimeString(),
|
|
65
|
+
Timezone: Intl.DateTimeFormat().resolvedOptions().timeZone,
|
|
66
|
+
};
|
|
67
|
+
|
|
68
|
+
const allureResultsDir = path.join(moduleConfig.modulePath, "allure-result");
|
|
69
|
+
|
|
70
|
+
if (!fs.existsSync(allureResultsDir)) {
|
|
71
|
+
fs.mkdirSync(allureResultsDir, { recursive: true });
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
const propertiesContent = Object.entries(environment)
|
|
75
|
+
.map(([key, value]) => `${key}=${value}`)
|
|
76
|
+
.join("\n");
|
|
77
|
+
|
|
78
|
+
fs.writeFileSync(
|
|
79
|
+
path.join(allureResultsDir, "environment.properties"),
|
|
80
|
+
propertiesContent,
|
|
81
|
+
);
|
|
82
|
+
|
|
83
|
+
return environment;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
module.exports = { getEnvInfo };
|