artes 1.7.20 → 1.7.21
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 +781 -781
- package/assets/styles.css +4 -4
- package/cucumber.config.js +253 -253
- package/docs/ciExecutors.md +198 -198
- package/docs/emulationDevicesList.md +152 -152
- package/docs/functionDefinitions.md +2401 -2401
- package/docs/stepDefinitions.md +435 -435
- package/executer.js +266 -266
- package/index.js +51 -51
- package/package.json +56 -56
- package/src/helper/contextManager/browserManager.js +74 -74
- package/src/helper/contextManager/requestManager.js +23 -23
- package/src/helper/controller/elementController.js +230 -230
- package/src/helper/controller/findDuplicateTestNames.js +69 -69
- package/src/helper/controller/getEnvInfo.js +97 -97
- package/src/helper/controller/getExecutor.js +109 -109
- package/src/helper/controller/pomCollector.js +83 -83
- package/src/helper/controller/reportCustomizer.js +511 -511
- package/src/helper/controller/screenComparer.js +96 -96
- package/src/helper/controller/status-formatter.js +137 -137
- package/src/helper/controller/testCoverageCalculator.js +111 -111
- package/src/helper/executers/cleaner.js +23 -23
- package/src/helper/executers/exporter.js +19 -19
- package/src/helper/executers/helper.js +193 -193
- package/src/helper/executers/projectCreator.js +226 -226
- package/src/helper/executers/reportGenerator.js +91 -91
- package/src/helper/executers/testRunner.js +28 -28
- package/src/helper/executers/versionChecker.js +31 -31
- package/src/helper/imports/commons.js +69 -69
- package/src/helper/stepFunctions/APIActions.js +582 -582
- package/src/helper/stepFunctions/assertions.js +986 -986
- package/src/helper/stepFunctions/browserActions.js +87 -87
- package/src/helper/stepFunctions/elementInteractions.js +60 -60
- package/src/helper/stepFunctions/exporter.js +19 -19
- package/src/helper/stepFunctions/frameActions.js +72 -72
- package/src/helper/stepFunctions/keyboardActions.js +66 -66
- package/src/helper/stepFunctions/mouseActions.js +84 -84
- package/src/helper/stepFunctions/pageActions.js +43 -43
- package/src/hooks/context.js +18 -18
- package/src/hooks/hooks.js +287 -287
- package/src/stepDefinitions/API.steps.js +404 -404
- package/src/stepDefinitions/assertions.steps.js +1358 -1349
- package/src/stepDefinitions/browser.steps.js +74 -74
- package/src/stepDefinitions/frameActions.steps.js +76 -76
- package/src/stepDefinitions/keyboardActions.steps.js +264 -264
- package/src/stepDefinitions/mouseActions.steps.js +374 -374
- package/src/stepDefinitions/page.steps.js +71 -71
- package/src/stepDefinitions/random.steps.js +199 -199
- package/src/stepDefinitions/report.steps.js +5 -5
|
@@ -1,230 +1,230 @@
|
|
|
1
|
-
const { context } = require("../../hooks/context");
|
|
2
|
-
const path = require("path");
|
|
3
|
-
|
|
4
|
-
let elements = {};
|
|
5
|
-
|
|
6
|
-
function addElements(newElements) {
|
|
7
|
-
elements = { ...elements, ...newElements };
|
|
8
|
-
}
|
|
9
|
-
|
|
10
|
-
// async function locatorExistenceChecker(locator){
|
|
11
|
-
// const locatorCount = await locator.count();
|
|
12
|
-
// console.log(locator, locatorCount)
|
|
13
|
-
// return locatorCount ==0 ? false : true;
|
|
14
|
-
// }
|
|
15
|
-
|
|
16
|
-
function selectorSeparator(element) {
|
|
17
|
-
if (typeof element !== "string") return element;
|
|
18
|
-
|
|
19
|
-
const selector = element?.split("=");
|
|
20
|
-
const validTypes = [
|
|
21
|
-
"xpath",
|
|
22
|
-
"name",
|
|
23
|
-
"placeholder",
|
|
24
|
-
"text",
|
|
25
|
-
"label",
|
|
26
|
-
"role",
|
|
27
|
-
"alt",
|
|
28
|
-
"title",
|
|
29
|
-
"testid",
|
|
30
|
-
];
|
|
31
|
-
|
|
32
|
-
if (selector && validTypes.includes(selector[0]?.trim())) {
|
|
33
|
-
return [
|
|
34
|
-
selector[0].trim(),
|
|
35
|
-
selector[1] !== undefined ? selector[1].trim() : "",
|
|
36
|
-
];
|
|
37
|
-
} else {
|
|
38
|
-
return selector.join("=");
|
|
39
|
-
}
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
function getSelector(element) {
|
|
43
|
-
element = resolveVariable(element);
|
|
44
|
-
|
|
45
|
-
const selector =
|
|
46
|
-
elements?.[element]?.selector || elements?.[element] || element;
|
|
47
|
-
return resolveVariable(selectorSeparator(selector));
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
function getElement(element) {
|
|
51
|
-
if (!context.page) {
|
|
52
|
-
throw new Error("Page context is not initialized.");
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
const selector = getSelector(element);
|
|
56
|
-
const waitTime = elements[element]?.waitTime * 1000 || 0;
|
|
57
|
-
|
|
58
|
-
let locator;
|
|
59
|
-
switch (selector[0]) {
|
|
60
|
-
case "xpath":
|
|
61
|
-
locator = context.page.locator(`xpath=${selector[1]}`, { exact: true });
|
|
62
|
-
break;
|
|
63
|
-
case "name":
|
|
64
|
-
locator = context.page.locator(`[name="${selector[1]}"]`, {
|
|
65
|
-
exact: true,
|
|
66
|
-
});
|
|
67
|
-
break;
|
|
68
|
-
case "placeholder":
|
|
69
|
-
locator = context.page.getByPlaceholder(selector[1], { exact: true });
|
|
70
|
-
break;
|
|
71
|
-
case "text":
|
|
72
|
-
locator = context.page.getByText(selector[1], { exact: true });
|
|
73
|
-
break;
|
|
74
|
-
case "label":
|
|
75
|
-
locator = context.page.getByLabel(selector[1], { exact: true });
|
|
76
|
-
break;
|
|
77
|
-
case "role":
|
|
78
|
-
locator = context.page.getByRole(selector[1], { exact: true });
|
|
79
|
-
break;
|
|
80
|
-
case "alt":
|
|
81
|
-
locator = context.page.getByAltText(selector[1], { exact: true });
|
|
82
|
-
break;
|
|
83
|
-
case "title":
|
|
84
|
-
locator = context.page.getByTitle(selector[1], { exact: true });
|
|
85
|
-
break;
|
|
86
|
-
case "testid":
|
|
87
|
-
locator = context.page.getByTestId(selector[1], { exact: true });
|
|
88
|
-
break;
|
|
89
|
-
default:
|
|
90
|
-
locator = context.page.locator(selector, { exact: true });
|
|
91
|
-
break;
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
return locator;
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
function normalizeCrossplatformPath(inputPath) {
|
|
98
|
-
return path.normalize(inputPath.replace(/\\/g, "/"));
|
|
99
|
-
}
|
|
100
|
-
|
|
101
|
-
function pathToCamelCase(path) {
|
|
102
|
-
const cleaned = path.replace(/\[(\d+)\]/g, "_$1");
|
|
103
|
-
const parts = cleaned.split(".");
|
|
104
|
-
return parts
|
|
105
|
-
.map((part, index) => {
|
|
106
|
-
if (index === 0) return part;
|
|
107
|
-
return part.charAt(0).toUpperCase() + part.slice(1);
|
|
108
|
-
})
|
|
109
|
-
.join("");
|
|
110
|
-
}
|
|
111
|
-
|
|
112
|
-
function extractVarsFromResponse(responseBody, vars, customVarNames) {
|
|
113
|
-
function getValueByPath(obj, path) {
|
|
114
|
-
if (typeof obj === "string") return obj;
|
|
115
|
-
|
|
116
|
-
const keys = path.split(".").flatMap((key) => {
|
|
117
|
-
const arrayMatch = key.match(/^([^\[]+)\[(\d+)\]$/);
|
|
118
|
-
if (arrayMatch) {
|
|
119
|
-
return [arrayMatch[1], parseInt(arrayMatch[2])];
|
|
120
|
-
}
|
|
121
|
-
return [key];
|
|
122
|
-
});
|
|
123
|
-
|
|
124
|
-
let current = obj;
|
|
125
|
-
for (const key of keys) {
|
|
126
|
-
if (current == null) return undefined;
|
|
127
|
-
|
|
128
|
-
if (typeof key === "number") {
|
|
129
|
-
if (!Array.isArray(current)) return undefined;
|
|
130
|
-
current = current[key];
|
|
131
|
-
} else if (typeof current === "object" && key in current) {
|
|
132
|
-
current = current[key];
|
|
133
|
-
} else {
|
|
134
|
-
return undefined;
|
|
135
|
-
}
|
|
136
|
-
}
|
|
137
|
-
|
|
138
|
-
return current;
|
|
139
|
-
}
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
const varPaths = vars.split(",").map((v) => v.trim());
|
|
143
|
-
let customNames = [];
|
|
144
|
-
|
|
145
|
-
if (!customVarNames) {
|
|
146
|
-
customNames = varPaths.map(pathToCamelCase);
|
|
147
|
-
} else if (typeof customVarNames === "string") {
|
|
148
|
-
customNames = customVarNames.split(",").map((n) => n.trim());
|
|
149
|
-
} else if (Array.isArray(customVarNames)) {
|
|
150
|
-
customNames = customVarNames;
|
|
151
|
-
} else {
|
|
152
|
-
throw new Error("customVarNames must be a string or an array");
|
|
153
|
-
}
|
|
154
|
-
|
|
155
|
-
if (customNames.length !== varPaths.length) {
|
|
156
|
-
customNames = varPaths.map(pathToCamelCase);
|
|
157
|
-
}
|
|
158
|
-
|
|
159
|
-
varPaths.forEach((path, index) => {
|
|
160
|
-
const value = getValueByPath(responseBody, path);
|
|
161
|
-
if (value !== undefined) {
|
|
162
|
-
saveVar(value, customNames[index], path);
|
|
163
|
-
}
|
|
164
|
-
});
|
|
165
|
-
}
|
|
166
|
-
|
|
167
|
-
function saveVar(value, customName, path) {
|
|
168
|
-
if (!customName) {
|
|
169
|
-
const flatKey = path
|
|
170
|
-
.split(".")
|
|
171
|
-
.map((part, i) =>
|
|
172
|
-
i === 0 ? part : part[0].toUpperCase() + part.slice(1),
|
|
173
|
-
)
|
|
174
|
-
.join("");
|
|
175
|
-
|
|
176
|
-
context.vars[flatKey] = value;
|
|
177
|
-
} else {
|
|
178
|
-
context.vars[customName] = value;
|
|
179
|
-
}
|
|
180
|
-
}
|
|
181
|
-
|
|
182
|
-
function resolveVariable(template) {
|
|
183
|
-
if (typeof template === "string") {
|
|
184
|
-
return template.replace(/{{\s*(\w+)\s*}}/g, (_, varName) => {
|
|
185
|
-
let value = context.vars[varName];
|
|
186
|
-
|
|
187
|
-
if (value !== undefined) {
|
|
188
|
-
if (typeof value !== "string") {
|
|
189
|
-
try {
|
|
190
|
-
value = JSON.stringify(value);
|
|
191
|
-
} catch {
|
|
192
|
-
value = String(value);
|
|
193
|
-
}
|
|
194
|
-
}
|
|
195
|
-
|
|
196
|
-
return value
|
|
197
|
-
.replace(/\n/g, "\\n")
|
|
198
|
-
.replace(/\r/g, "\\r")
|
|
199
|
-
.replace(/\t/g, "\\t");
|
|
200
|
-
}
|
|
201
|
-
|
|
202
|
-
return `{{${varName}}}`;
|
|
203
|
-
});
|
|
204
|
-
}
|
|
205
|
-
|
|
206
|
-
if (Array.isArray(template)) {
|
|
207
|
-
return template.map((item) => resolveVariable(item));
|
|
208
|
-
}
|
|
209
|
-
|
|
210
|
-
if (template && typeof template === "object") {
|
|
211
|
-
const result = {};
|
|
212
|
-
for (const key in template) {
|
|
213
|
-
result[key] = resolveVariable(template[key]);
|
|
214
|
-
}
|
|
215
|
-
return result;
|
|
216
|
-
}
|
|
217
|
-
|
|
218
|
-
return template;
|
|
219
|
-
}
|
|
220
|
-
|
|
221
|
-
module.exports = {
|
|
222
|
-
getElement,
|
|
223
|
-
addElements,
|
|
224
|
-
getSelector,
|
|
225
|
-
extractVarsFromResponse,
|
|
226
|
-
pathToCamelCase,
|
|
227
|
-
normalizeCrossplatformPath,
|
|
228
|
-
saveVar,
|
|
229
|
-
resolveVariable,
|
|
230
|
-
};
|
|
1
|
+
const { context } = require("../../hooks/context");
|
|
2
|
+
const path = require("path");
|
|
3
|
+
|
|
4
|
+
let elements = {};
|
|
5
|
+
|
|
6
|
+
function addElements(newElements) {
|
|
7
|
+
elements = { ...elements, ...newElements };
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
// async function locatorExistenceChecker(locator){
|
|
11
|
+
// const locatorCount = await locator.count();
|
|
12
|
+
// console.log(locator, locatorCount)
|
|
13
|
+
// return locatorCount ==0 ? false : true;
|
|
14
|
+
// }
|
|
15
|
+
|
|
16
|
+
function selectorSeparator(element) {
|
|
17
|
+
if (typeof element !== "string") return element;
|
|
18
|
+
|
|
19
|
+
const selector = element?.split("=");
|
|
20
|
+
const validTypes = [
|
|
21
|
+
"xpath",
|
|
22
|
+
"name",
|
|
23
|
+
"placeholder",
|
|
24
|
+
"text",
|
|
25
|
+
"label",
|
|
26
|
+
"role",
|
|
27
|
+
"alt",
|
|
28
|
+
"title",
|
|
29
|
+
"testid",
|
|
30
|
+
];
|
|
31
|
+
|
|
32
|
+
if (selector && validTypes.includes(selector[0]?.trim())) {
|
|
33
|
+
return [
|
|
34
|
+
selector[0].trim(),
|
|
35
|
+
selector[1] !== undefined ? selector[1].trim() : "",
|
|
36
|
+
];
|
|
37
|
+
} else {
|
|
38
|
+
return selector.join("=");
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
function getSelector(element) {
|
|
43
|
+
element = resolveVariable(element);
|
|
44
|
+
|
|
45
|
+
const selector =
|
|
46
|
+
elements?.[element]?.selector || elements?.[element] || element;
|
|
47
|
+
return resolveVariable(selectorSeparator(selector));
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
function getElement(element) {
|
|
51
|
+
if (!context.page) {
|
|
52
|
+
throw new Error("Page context is not initialized.");
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
const selector = getSelector(element);
|
|
56
|
+
const waitTime = elements[element]?.waitTime * 1000 || 0;
|
|
57
|
+
|
|
58
|
+
let locator;
|
|
59
|
+
switch (selector[0]) {
|
|
60
|
+
case "xpath":
|
|
61
|
+
locator = context.page.locator(`xpath=${selector[1]}`, { exact: true });
|
|
62
|
+
break;
|
|
63
|
+
case "name":
|
|
64
|
+
locator = context.page.locator(`[name="${selector[1]}"]`, {
|
|
65
|
+
exact: true,
|
|
66
|
+
});
|
|
67
|
+
break;
|
|
68
|
+
case "placeholder":
|
|
69
|
+
locator = context.page.getByPlaceholder(selector[1], { exact: true });
|
|
70
|
+
break;
|
|
71
|
+
case "text":
|
|
72
|
+
locator = context.page.getByText(selector[1], { exact: true });
|
|
73
|
+
break;
|
|
74
|
+
case "label":
|
|
75
|
+
locator = context.page.getByLabel(selector[1], { exact: true });
|
|
76
|
+
break;
|
|
77
|
+
case "role":
|
|
78
|
+
locator = context.page.getByRole(selector[1], { exact: true });
|
|
79
|
+
break;
|
|
80
|
+
case "alt":
|
|
81
|
+
locator = context.page.getByAltText(selector[1], { exact: true });
|
|
82
|
+
break;
|
|
83
|
+
case "title":
|
|
84
|
+
locator = context.page.getByTitle(selector[1], { exact: true });
|
|
85
|
+
break;
|
|
86
|
+
case "testid":
|
|
87
|
+
locator = context.page.getByTestId(selector[1], { exact: true });
|
|
88
|
+
break;
|
|
89
|
+
default:
|
|
90
|
+
locator = context.page.locator(selector, { exact: true });
|
|
91
|
+
break;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
return locator;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
function normalizeCrossplatformPath(inputPath) {
|
|
98
|
+
return path.normalize(inputPath.replace(/\\/g, "/"));
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
function pathToCamelCase(path) {
|
|
102
|
+
const cleaned = path.replace(/\[(\d+)\]/g, "_$1");
|
|
103
|
+
const parts = cleaned.split(".");
|
|
104
|
+
return parts
|
|
105
|
+
.map((part, index) => {
|
|
106
|
+
if (index === 0) return part;
|
|
107
|
+
return part.charAt(0).toUpperCase() + part.slice(1);
|
|
108
|
+
})
|
|
109
|
+
.join("");
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
function extractVarsFromResponse(responseBody, vars, customVarNames) {
|
|
113
|
+
function getValueByPath(obj, path) {
|
|
114
|
+
if (typeof obj === "string") return obj;
|
|
115
|
+
|
|
116
|
+
const keys = path.split(".").flatMap((key) => {
|
|
117
|
+
const arrayMatch = key.match(/^([^\[]+)\[(\d+)\]$/);
|
|
118
|
+
if (arrayMatch) {
|
|
119
|
+
return [arrayMatch[1], parseInt(arrayMatch[2])];
|
|
120
|
+
}
|
|
121
|
+
return [key];
|
|
122
|
+
});
|
|
123
|
+
|
|
124
|
+
let current = obj;
|
|
125
|
+
for (const key of keys) {
|
|
126
|
+
if (current == null) return undefined;
|
|
127
|
+
|
|
128
|
+
if (typeof key === "number") {
|
|
129
|
+
if (!Array.isArray(current)) return undefined;
|
|
130
|
+
current = current[key];
|
|
131
|
+
} else if (typeof current === "object" && key in current) {
|
|
132
|
+
current = current[key];
|
|
133
|
+
} else {
|
|
134
|
+
return undefined;
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
return current;
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
|
|
142
|
+
const varPaths = vars.split(",").map((v) => v.trim());
|
|
143
|
+
let customNames = [];
|
|
144
|
+
|
|
145
|
+
if (!customVarNames) {
|
|
146
|
+
customNames = varPaths.map(pathToCamelCase);
|
|
147
|
+
} else if (typeof customVarNames === "string") {
|
|
148
|
+
customNames = customVarNames.split(",").map((n) => n.trim());
|
|
149
|
+
} else if (Array.isArray(customVarNames)) {
|
|
150
|
+
customNames = customVarNames;
|
|
151
|
+
} else {
|
|
152
|
+
throw new Error("customVarNames must be a string or an array");
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
if (customNames.length !== varPaths.length) {
|
|
156
|
+
customNames = varPaths.map(pathToCamelCase);
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
varPaths.forEach((path, index) => {
|
|
160
|
+
const value = getValueByPath(responseBody, path);
|
|
161
|
+
if (value !== undefined) {
|
|
162
|
+
saveVar(value, customNames[index], path);
|
|
163
|
+
}
|
|
164
|
+
});
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
function saveVar(value, customName, path) {
|
|
168
|
+
if (!customName) {
|
|
169
|
+
const flatKey = path
|
|
170
|
+
.split(".")
|
|
171
|
+
.map((part, i) =>
|
|
172
|
+
i === 0 ? part : part[0].toUpperCase() + part.slice(1),
|
|
173
|
+
)
|
|
174
|
+
.join("");
|
|
175
|
+
|
|
176
|
+
context.vars[flatKey] = value;
|
|
177
|
+
} else {
|
|
178
|
+
context.vars[customName] = value;
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
function resolveVariable(template) {
|
|
183
|
+
if (typeof template === "string") {
|
|
184
|
+
return template.replace(/{{\s*(\w+)\s*}}/g, (_, varName) => {
|
|
185
|
+
let value = context.vars[varName];
|
|
186
|
+
|
|
187
|
+
if (value !== undefined) {
|
|
188
|
+
if (typeof value !== "string") {
|
|
189
|
+
try {
|
|
190
|
+
value = JSON.stringify(value);
|
|
191
|
+
} catch {
|
|
192
|
+
value = String(value);
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
return value
|
|
197
|
+
.replace(/\n/g, "\\n")
|
|
198
|
+
.replace(/\r/g, "\\r")
|
|
199
|
+
.replace(/\t/g, "\\t");
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
return `{{${varName}}}`;
|
|
203
|
+
});
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
if (Array.isArray(template)) {
|
|
207
|
+
return template.map((item) => resolveVariable(item));
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
if (template && typeof template === "object") {
|
|
211
|
+
const result = {};
|
|
212
|
+
for (const key in template) {
|
|
213
|
+
result[key] = resolveVariable(template[key]);
|
|
214
|
+
}
|
|
215
|
+
return result;
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
return template;
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
module.exports = {
|
|
222
|
+
getElement,
|
|
223
|
+
addElements,
|
|
224
|
+
getSelector,
|
|
225
|
+
extractVarsFromResponse,
|
|
226
|
+
pathToCamelCase,
|
|
227
|
+
normalizeCrossplatformPath,
|
|
228
|
+
saveVar,
|
|
229
|
+
resolveVariable,
|
|
230
|
+
};
|
|
@@ -1,69 +1,69 @@
|
|
|
1
|
-
const fs = require("fs");
|
|
2
|
-
const path = require("path");
|
|
3
|
-
|
|
4
|
-
function findDuplicateTestNames() {
|
|
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] = [];
|
|
33
|
-
}
|
|
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}`);
|
|
59
|
-
});
|
|
60
|
-
console.log("");
|
|
61
|
-
});
|
|
62
|
-
console.log("\x1b[0m");
|
|
63
|
-
console.log("");
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
return duplicates;
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
module.exports = { findDuplicateTestNames };
|
|
1
|
+
const fs = require("fs");
|
|
2
|
+
const path = require("path");
|
|
3
|
+
|
|
4
|
+
function findDuplicateTestNames() {
|
|
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] = [];
|
|
33
|
+
}
|
|
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}`);
|
|
59
|
+
});
|
|
60
|
+
console.log("");
|
|
61
|
+
});
|
|
62
|
+
console.log("\x1b[0m");
|
|
63
|
+
console.log("");
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
return duplicates;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
module.exports = { findDuplicateTestNames };
|