@dev-blinq/cucumber_client 1.0.1313-dev → 1.0.1313-stage
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/bin/assets/bundled_scripts/recorder.js +108 -108
- package/bin/assets/preload/css_gen.js +10 -10
- package/bin/assets/preload/recorderv3.js +3 -1
- package/bin/assets/preload/toolbar.js +27 -29
- package/bin/assets/preload/unique_locators.js +1 -1
- package/bin/assets/preload/yaml.js +288 -275
- package/bin/assets/scripts/aria_snapshot.js +223 -220
- package/bin/assets/scripts/dom_attr.js +329 -329
- package/bin/assets/scripts/dom_parent.js +169 -174
- package/bin/assets/scripts/event_utils.js +94 -94
- package/bin/assets/scripts/pw.js +2050 -1949
- package/bin/assets/scripts/recorder.js +5 -17
- package/bin/assets/scripts/snapshot_capturer.js +153 -146
- package/bin/assets/scripts/unique_locators.js +923 -817
- package/bin/assets/scripts/yaml.js +796 -783
- package/bin/assets/templates/_hooks_template.txt +41 -0
- package/bin/assets/templates/utils_template.txt +1 -44
- package/bin/client/apiTest/apiTest.js +6 -0
- package/bin/client/cli_helpers.js +11 -13
- package/bin/client/code_cleanup/utils.js +5 -1
- package/bin/client/code_gen/api_codegen.js +2 -2
- package/bin/client/code_gen/code_inversion.js +53 -4
- package/bin/client/code_gen/page_reflection.js +839 -906
- package/bin/client/code_gen/playwright_codeget.js +32 -17
- package/bin/client/cucumber/feature.js +89 -27
- package/bin/client/cucumber/feature_data.js +2 -2
- package/bin/client/cucumber/project_to_document.js +9 -3
- package/bin/client/cucumber/steps_definitions.js +90 -87
- package/bin/client/cucumber_selector.js +17 -1
- package/bin/client/local_agent.js +6 -5
- package/bin/client/parse_feature_file.js +23 -26
- package/bin/client/playground/projects/env.json +2 -2
- package/bin/client/project.js +186 -196
- package/bin/client/recorderv3/bvt_recorder.js +159 -75
- package/bin/client/recorderv3/implemented_steps.js +74 -16
- package/bin/client/recorderv3/index.js +65 -54
- package/bin/client/recorderv3/scriptTest.js +1 -1
- package/bin/client/recorderv3/services.js +4 -16
- package/bin/client/recorderv3/step_runner.js +313 -170
- package/bin/client/recorderv3/step_utils.js +508 -4
- package/bin/client/recorderv3/update_feature.js +32 -30
- package/bin/client/run_cucumber.js +5 -1
- package/bin/client/scenario_report.js +0 -5
- package/bin/client/test_scenario.js +0 -1
- package/bin/client/upload-service.js +2 -2
- package/bin/client/utils/socket_logger.js +132 -0
- package/bin/index.js +1 -0
- package/bin/logger.js +3 -2
- package/bin/min/consoleApi.min.cjs +2 -3
- package/bin/min/injectedScript.min.cjs +16 -16
- package/package.json +20 -11
|
@@ -14,6 +14,419 @@ import { createHash } from "crypto";
|
|
|
14
14
|
|
|
15
15
|
const __dirname = path.dirname(url.fileURLToPath(import.meta.url));
|
|
16
16
|
|
|
17
|
+
const convertToIdentifier = (text) => {
|
|
18
|
+
// replace all invalid characters with _
|
|
19
|
+
return text.replace(/[^a-zA-Z0-9_]/g, "_");
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
export const isVariable = (text) => {
|
|
23
|
+
if (typeof text !== "string") return false;
|
|
24
|
+
const isParametric = text.startsWith("<") && text.endsWith(">");
|
|
25
|
+
if (!isParametric) return false;
|
|
26
|
+
const l = text.length;
|
|
27
|
+
if (l < 2) return false;
|
|
28
|
+
const leftindex = text.indexOf("<");
|
|
29
|
+
const rightindex = text.indexOf(">");
|
|
30
|
+
return leftindex === 0 && rightindex === l - 1;
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
export const extractQuotes = (text) => {
|
|
34
|
+
const stringRegex = /"([^"]*)"/g;
|
|
35
|
+
const matches = text.match(stringRegex);
|
|
36
|
+
if (!matches) return [];
|
|
37
|
+
const quotes = [];
|
|
38
|
+
for (const match of matches) {
|
|
39
|
+
const value = match.slice(1, -1);
|
|
40
|
+
quotes.push(value);
|
|
41
|
+
}
|
|
42
|
+
return quotes;
|
|
43
|
+
};
|
|
44
|
+
|
|
45
|
+
const replaceLastOccurence = (str, search, replacement) => {
|
|
46
|
+
const lastIndex = str.lastIndexOf(search);
|
|
47
|
+
if (lastIndex === -1) return str;
|
|
48
|
+
return str.substring(0, lastIndex) + replacement + str.substring(lastIndex + search.length);
|
|
49
|
+
};
|
|
50
|
+
|
|
51
|
+
const _toRecordingStep = (cmd) => {
|
|
52
|
+
switch (cmd.type) {
|
|
53
|
+
case "hover_element": {
|
|
54
|
+
return {
|
|
55
|
+
type: "hover_element",
|
|
56
|
+
element: {
|
|
57
|
+
role: cmd.role,
|
|
58
|
+
name: cmd.label,
|
|
59
|
+
},
|
|
60
|
+
lastKnownUrlPath: cmd.lastKnownUrlPath,
|
|
61
|
+
};
|
|
62
|
+
}
|
|
63
|
+
case "click_element": {
|
|
64
|
+
return {
|
|
65
|
+
type: "click_element",
|
|
66
|
+
element: {
|
|
67
|
+
role: cmd.role,
|
|
68
|
+
name: cmd.label,
|
|
69
|
+
},
|
|
70
|
+
lastKnownUrlPath: cmd.lastKnownUrlPath,
|
|
71
|
+
count: cmd.count ?? 1,
|
|
72
|
+
};
|
|
73
|
+
}
|
|
74
|
+
case "context_click": {
|
|
75
|
+
return {
|
|
76
|
+
type: "context_click",
|
|
77
|
+
element: {
|
|
78
|
+
role: cmd.role,
|
|
79
|
+
name: cmd.label,
|
|
80
|
+
},
|
|
81
|
+
label: cmd.label,
|
|
82
|
+
value: cmd.value,
|
|
83
|
+
lastKnownUrlPath: cmd.lastKnownUrlPath,
|
|
84
|
+
text: cmd.text,
|
|
85
|
+
count: cmd.count ?? 1,
|
|
86
|
+
};
|
|
87
|
+
}
|
|
88
|
+
case "parameterized_click": {
|
|
89
|
+
return {
|
|
90
|
+
type: "parameterized_click",
|
|
91
|
+
element: {
|
|
92
|
+
role: cmd.role,
|
|
93
|
+
name: cmd.label,
|
|
94
|
+
},
|
|
95
|
+
label: cmd.label,
|
|
96
|
+
value: cmd.value,
|
|
97
|
+
lastKnownUrlPath: cmd.lastKnownUrlPath,
|
|
98
|
+
count: cmd.count ?? 1,
|
|
99
|
+
};
|
|
100
|
+
}
|
|
101
|
+
case "fill_element": {
|
|
102
|
+
return {
|
|
103
|
+
type: "fill_element",
|
|
104
|
+
element: {
|
|
105
|
+
role: cmd.role,
|
|
106
|
+
name: cmd.label,
|
|
107
|
+
},
|
|
108
|
+
parameters: [cmd.value, cmd.enter ?? false],
|
|
109
|
+
lastKnownUrlPath: cmd.lastKnownUrlPath,
|
|
110
|
+
};
|
|
111
|
+
}
|
|
112
|
+
case "select_combobox": {
|
|
113
|
+
return {
|
|
114
|
+
type: "select_combobox",
|
|
115
|
+
element: {
|
|
116
|
+
role: "combobox",
|
|
117
|
+
name: cmd.label,
|
|
118
|
+
},
|
|
119
|
+
selectMode: "select",
|
|
120
|
+
parameters: [cmd.value],
|
|
121
|
+
lastKnownUrlPath: cmd.lastKnownUrlPath,
|
|
122
|
+
};
|
|
123
|
+
}
|
|
124
|
+
case "verify_page_contains_text": {
|
|
125
|
+
return {
|
|
126
|
+
type: "verify_page_contains_text",
|
|
127
|
+
parameters: [cmd.value, cmd.isRegex],
|
|
128
|
+
lastKnownUrlPath: cmd.lastKnownUrlPath,
|
|
129
|
+
};
|
|
130
|
+
}
|
|
131
|
+
case "verify_element_contains_text": {
|
|
132
|
+
return {
|
|
133
|
+
type: "verify_element_contains_text",
|
|
134
|
+
element: {
|
|
135
|
+
role: cmd.role,
|
|
136
|
+
name: cmd.label,
|
|
137
|
+
},
|
|
138
|
+
parameters: [cmd.value, cmd.climb],
|
|
139
|
+
lastKnownUrlPath: cmd.lastKnownUrlPath,
|
|
140
|
+
};
|
|
141
|
+
}
|
|
142
|
+
case "close_page": {
|
|
143
|
+
return {
|
|
144
|
+
type: "close_page",
|
|
145
|
+
lastKnownUrlPath: cmd.lastKnownUrlPath,
|
|
146
|
+
};
|
|
147
|
+
}
|
|
148
|
+
case "check_element": {
|
|
149
|
+
return {
|
|
150
|
+
type: "check_element",
|
|
151
|
+
element: {
|
|
152
|
+
role: cmd.role,
|
|
153
|
+
name: cmd.label,
|
|
154
|
+
},
|
|
155
|
+
check: cmd.check,
|
|
156
|
+
lastKnownUrlPath: cmd.lastKnownUrlPath,
|
|
157
|
+
};
|
|
158
|
+
}
|
|
159
|
+
case "press_key": {
|
|
160
|
+
return {
|
|
161
|
+
type: "press_key",
|
|
162
|
+
element: {
|
|
163
|
+
role: cmd.role,
|
|
164
|
+
name: cmd.label,
|
|
165
|
+
},
|
|
166
|
+
key: cmd.value,
|
|
167
|
+
lastKnownUrlPath: cmd.lastKnownUrlPath,
|
|
168
|
+
};
|
|
169
|
+
}
|
|
170
|
+
case "load_user": {
|
|
171
|
+
return {
|
|
172
|
+
type: "load_data",
|
|
173
|
+
parameters: ["users", cmd.value],
|
|
174
|
+
lastKnownUrlPath: cmd.lastKnownUrlPath,
|
|
175
|
+
};
|
|
176
|
+
}
|
|
177
|
+
case "load_csv": {
|
|
178
|
+
return {
|
|
179
|
+
type: "load_data",
|
|
180
|
+
parameters: ["csv", `${cmd.label}:${cmd.value}`],
|
|
181
|
+
lastKnownUrlPath: cmd.lastKnownUrlPath,
|
|
182
|
+
};
|
|
183
|
+
}
|
|
184
|
+
case "set_date_time": {
|
|
185
|
+
return {
|
|
186
|
+
type: "set_date_time",
|
|
187
|
+
element: {
|
|
188
|
+
role: cmd.role,
|
|
189
|
+
name: cmd.label,
|
|
190
|
+
},
|
|
191
|
+
parameters: [cmd.value],
|
|
192
|
+
lastKnownUrlPath: cmd.lastKnownUrlPath,
|
|
193
|
+
};
|
|
194
|
+
}
|
|
195
|
+
case "set_input": {
|
|
196
|
+
return {
|
|
197
|
+
type: "set_input",
|
|
198
|
+
element: {
|
|
199
|
+
role: cmd.role,
|
|
200
|
+
name: cmd.label,
|
|
201
|
+
},
|
|
202
|
+
value: cmd.value,
|
|
203
|
+
parameters: [cmd.value],
|
|
204
|
+
lastKnownUrlPath: cmd.lastKnownUrlPath,
|
|
205
|
+
};
|
|
206
|
+
}
|
|
207
|
+
case "extract_attribute": {
|
|
208
|
+
return {
|
|
209
|
+
type: "extract_attribute",
|
|
210
|
+
element: {
|
|
211
|
+
role: cmd.role,
|
|
212
|
+
name: cmd.label,
|
|
213
|
+
},
|
|
214
|
+
parameters: [cmd.selectedField, cmd.variableName],
|
|
215
|
+
lastKnownUrlPath: cmd.lastKnownUrlPath,
|
|
216
|
+
regex: cmd.regex,
|
|
217
|
+
trimSpaces: cmd.trimSpaces,
|
|
218
|
+
};
|
|
219
|
+
}
|
|
220
|
+
case "extract_property": {
|
|
221
|
+
return {
|
|
222
|
+
type: "extract_property",
|
|
223
|
+
element: {
|
|
224
|
+
role: cmd.role,
|
|
225
|
+
name: cmd.label,
|
|
226
|
+
},
|
|
227
|
+
parameters: [cmd.selectedField, cmd.variableName],
|
|
228
|
+
lastKnownUrlPath: cmd.lastKnownUrlPath,
|
|
229
|
+
regex: cmd.regex,
|
|
230
|
+
trimSpaces: cmd.trimSpaces,
|
|
231
|
+
};
|
|
232
|
+
}
|
|
233
|
+
case "verify_element_attribute": {
|
|
234
|
+
return {
|
|
235
|
+
type: "verify_element_attribute",
|
|
236
|
+
element: {
|
|
237
|
+
role: cmd.role,
|
|
238
|
+
name: cmd.label,
|
|
239
|
+
},
|
|
240
|
+
parameters: [cmd.selectedField, cmd.value],
|
|
241
|
+
lastKnownUrlPath: cmd.lastKnownUrlPath,
|
|
242
|
+
};
|
|
243
|
+
}
|
|
244
|
+
case "verify_element_property": {
|
|
245
|
+
return {
|
|
246
|
+
type: "verify_element_property",
|
|
247
|
+
element: {
|
|
248
|
+
role: cmd.role,
|
|
249
|
+
name: cmd.label,
|
|
250
|
+
},
|
|
251
|
+
parameters: [cmd.selectedField, cmd.value],
|
|
252
|
+
lastKnownUrlPath: cmd.lastKnownUrlPath,
|
|
253
|
+
};
|
|
254
|
+
}
|
|
255
|
+
case "conditional_wait": {
|
|
256
|
+
return {
|
|
257
|
+
type: "conditional_wait",
|
|
258
|
+
element: {
|
|
259
|
+
role: cmd.role,
|
|
260
|
+
name: cmd.label,
|
|
261
|
+
},
|
|
262
|
+
parameters: [cmd.timeout, cmd.selectedField, cmd.value],
|
|
263
|
+
lastKnownUrlPath: cmd.lastKnownUrlPath,
|
|
264
|
+
};
|
|
265
|
+
}
|
|
266
|
+
case "navigate": {
|
|
267
|
+
return {
|
|
268
|
+
type: "navigate",
|
|
269
|
+
parameters: [cmd.value],
|
|
270
|
+
lastKnownUrlPath: cmd.lastKnownUrlPath,
|
|
271
|
+
};
|
|
272
|
+
}
|
|
273
|
+
case "browser_go_back": {
|
|
274
|
+
return {
|
|
275
|
+
type: "browser_go_back",
|
|
276
|
+
};
|
|
277
|
+
}
|
|
278
|
+
case "browser_go_forward": {
|
|
279
|
+
return {
|
|
280
|
+
type: "browser_go_forward",
|
|
281
|
+
};
|
|
282
|
+
}
|
|
283
|
+
case "set_input_files": {
|
|
284
|
+
return {
|
|
285
|
+
type: "set_input_files",
|
|
286
|
+
element: {
|
|
287
|
+
role: cmd.role,
|
|
288
|
+
name: cmd.label,
|
|
289
|
+
},
|
|
290
|
+
parameters: [cmd.files],
|
|
291
|
+
lastKnownUrlPath: cmd.lastKnownUrlPath,
|
|
292
|
+
};
|
|
293
|
+
}
|
|
294
|
+
case "verify_page_snapshot": {
|
|
295
|
+
return {
|
|
296
|
+
type: "verify_page_snapshot",
|
|
297
|
+
parameters: [cmd.value],
|
|
298
|
+
selectors: cmd.selectors,
|
|
299
|
+
};
|
|
300
|
+
}
|
|
301
|
+
default: {
|
|
302
|
+
return {
|
|
303
|
+
type: cmd.type,
|
|
304
|
+
parameters: [cmd.value],
|
|
305
|
+
lastKnownUrlPath: cmd.lastKnownUrlPath,
|
|
306
|
+
};
|
|
307
|
+
}
|
|
308
|
+
}
|
|
309
|
+
};
|
|
310
|
+
|
|
311
|
+
function getBestStrategy(allStrategyLocators) {
|
|
312
|
+
const orderedPriorities = ["custom", "context", "basic", "text_with_index", "ignore_digit", "no_text"];
|
|
313
|
+
for (const strategy of orderedPriorities) {
|
|
314
|
+
if (allStrategyLocators[strategy] && allStrategyLocators[strategy].length > 0) {
|
|
315
|
+
return strategy;
|
|
316
|
+
}
|
|
317
|
+
}
|
|
318
|
+
return null;
|
|
319
|
+
}
|
|
320
|
+
|
|
321
|
+
const _parameterizeLocators = (locators, replacementFromValue, replacementToValue) => {
|
|
322
|
+
for (const loc of locators) {
|
|
323
|
+
if (loc?.css?.includes(replacementFromValue)) {
|
|
324
|
+
loc.css = loc.css.replaceAll(replacementFromValue, replacementToValue);
|
|
325
|
+
}
|
|
326
|
+
if (loc?.text?.includes(replacementFromValue)) {
|
|
327
|
+
loc.text = loc.text.replaceAll(replacementFromValue, replacementToValue);
|
|
328
|
+
}
|
|
329
|
+
if (loc?.climb && typeof loc.climb === "string" && loc.climb?.includes(replacementFromValue)) {
|
|
330
|
+
loc.climb = loc.climb.replaceAll(replacementFromValue, replacementToValue);
|
|
331
|
+
}
|
|
332
|
+
}
|
|
333
|
+
return locators;
|
|
334
|
+
};
|
|
335
|
+
const parameterizeLocators = ({ cmd, locs, isValueVariable, isTextVariable, parametersMap }) => {
|
|
336
|
+
if (isValueVariable) {
|
|
337
|
+
const variable = cmd.value.slice(1, -1);
|
|
338
|
+
const val = parametersMap[variable];
|
|
339
|
+
const replacementFromValue = val.trim();
|
|
340
|
+
const replacementToValue = `{${variable}}`;
|
|
341
|
+
locs = _parameterizeLocators(locs, replacementFromValue, replacementToValue);
|
|
342
|
+
}
|
|
343
|
+
if (isTextVariable) {
|
|
344
|
+
const variable = cmd.text.slice(1, -1);
|
|
345
|
+
const val = parametersMap[variable];
|
|
346
|
+
const replacementFromValue = val.trim();
|
|
347
|
+
const replacementToValue = `{${variable}}`;
|
|
348
|
+
locs = _parameterizeLocators(locs, replacementFromValue, replacementToValue);
|
|
349
|
+
}
|
|
350
|
+
return locs;
|
|
351
|
+
};
|
|
352
|
+
|
|
353
|
+
//TODO: IMPORTAN
|
|
354
|
+
export const toRecordingStep = (cmd, parametersMap) => {
|
|
355
|
+
if (cmd.type === "api") {
|
|
356
|
+
return {
|
|
357
|
+
type: "api",
|
|
358
|
+
value: cmd.value,
|
|
359
|
+
};
|
|
360
|
+
}
|
|
361
|
+
const step = _toRecordingStep(cmd);
|
|
362
|
+
const cmdID = {
|
|
363
|
+
cmdId: cmd.id,
|
|
364
|
+
};
|
|
365
|
+
Object.assign(step, cmdID);
|
|
366
|
+
|
|
367
|
+
const locatorsObject = JSON.parse(JSON.stringify(cmd.locators ?? null));
|
|
368
|
+
|
|
369
|
+
if (!locatorsObject) return step;
|
|
370
|
+
|
|
371
|
+
const element_name = cmd?.locators?.element_name ?? `${cmd.label} ${cmd.role ?? "Text"}`;
|
|
372
|
+
locatorsObject.element_name = element_name;
|
|
373
|
+
|
|
374
|
+
const isValueVariable = isVariable(cmd.value);
|
|
375
|
+
const isTextVariable = isVariable(cmd.text);
|
|
376
|
+
const allStrategyLocators = JSON.parse(JSON.stringify(cmd?.allStrategyLocators ?? null));
|
|
377
|
+
step.locators = locatorsObject;
|
|
378
|
+
step.allStrategyLocators = allStrategyLocators;
|
|
379
|
+
step.isLocatorsAssigned = true;
|
|
380
|
+
|
|
381
|
+
if (!isValueVariable && !isTextVariable) {
|
|
382
|
+
return step;
|
|
383
|
+
}
|
|
384
|
+
|
|
385
|
+
if (isValueVariable) {
|
|
386
|
+
step.dataSource = "parameters";
|
|
387
|
+
step.dataKey = convertToIdentifier(cmd.value.slice(1, -1));
|
|
388
|
+
}
|
|
389
|
+
|
|
390
|
+
if (!allStrategyLocators) {
|
|
391
|
+
let locs = locatorsObject.locators;
|
|
392
|
+
locs = parameterizeLocators({
|
|
393
|
+
cmd,
|
|
394
|
+
locs,
|
|
395
|
+
isValueVariable,
|
|
396
|
+
isTextVariable,
|
|
397
|
+
parametersMap,
|
|
398
|
+
});
|
|
399
|
+
locatorsObject.locators = locs;
|
|
400
|
+
return {
|
|
401
|
+
...step,
|
|
402
|
+
locators: locatorsObject,
|
|
403
|
+
};
|
|
404
|
+
}
|
|
405
|
+
|
|
406
|
+
for (const key in allStrategyLocators) {
|
|
407
|
+
if (key === "strategy") continue;
|
|
408
|
+
if (key === "no_text" || key === "custom") continue;
|
|
409
|
+
const locators = allStrategyLocators[key];
|
|
410
|
+
if (locators.length === 0) continue;
|
|
411
|
+
parameterizeLocators({
|
|
412
|
+
cmd,
|
|
413
|
+
locs: locators,
|
|
414
|
+
isValueVariable,
|
|
415
|
+
isTextVariable,
|
|
416
|
+
parametersMap,
|
|
417
|
+
});
|
|
418
|
+
}
|
|
419
|
+
|
|
420
|
+
locatorsObject.locators = allStrategyLocators[allStrategyLocators.strategy] ?? locatorsObject.locators;
|
|
421
|
+
|
|
422
|
+
return {
|
|
423
|
+
...step,
|
|
424
|
+
locators: locatorsObject,
|
|
425
|
+
allStrategyLocators,
|
|
426
|
+
isLocatorsAssigned: true,
|
|
427
|
+
};
|
|
428
|
+
};
|
|
429
|
+
|
|
17
430
|
export const toMethodName = (str) => {
|
|
18
431
|
// Remove any non-word characters (excluding underscore) and trim spaces
|
|
19
432
|
let cleanStr = str.trim().replace(/[^\w\s]/gi, "");
|
|
@@ -70,10 +483,13 @@ function makeStepTextUnique(step, stepsDefinitions) {
|
|
|
70
483
|
step.text = stepText;
|
|
71
484
|
}
|
|
72
485
|
|
|
73
|
-
export async function saveRecording({ step, cucumberStep, codePage, projectDir, stepsDefinitions }) {
|
|
486
|
+
export async function saveRecording({ step, cucumberStep, codePage, projectDir, stepsDefinitions, parametersMap }) {
|
|
487
|
+
if (step.commands && Array.isArray(step.commands)) {
|
|
488
|
+
step.commands = step.commands.map((cmd) => toRecordingStep(cmd, parametersMap));
|
|
489
|
+
}
|
|
74
490
|
let routesPath = path.join(tmpdir(), "blinq_temp_routes");
|
|
75
491
|
|
|
76
|
-
if (process.env.TEMP_RUN) {
|
|
492
|
+
if (process.env.TEMP_RUN === "true") {
|
|
77
493
|
if (existsSync(routesPath)) {
|
|
78
494
|
rmSync(routesPath, { recursive: true });
|
|
79
495
|
}
|
|
@@ -105,13 +521,44 @@ export async function saveRecording({ step, cucumberStep, codePage, projectDir,
|
|
|
105
521
|
codePage = getCodePage(stepDef.file);
|
|
106
522
|
} else {
|
|
107
523
|
const isUtilStep = makeStepTextUnique(step, stepsDefinitions);
|
|
524
|
+
|
|
108
525
|
if (isUtilStep) {
|
|
109
526
|
return;
|
|
110
527
|
}
|
|
111
528
|
}
|
|
112
529
|
|
|
530
|
+
routesPath = path.join(tmpdir(), "blinq_temp_routes");
|
|
531
|
+
if (process.env.TEMP_RUN === "true") {
|
|
532
|
+
console.log("Save routes in temp folder for running:", routesPath);
|
|
533
|
+
if (existsSync(routesPath)) {
|
|
534
|
+
console.log("Removing existing temp_routes_folder:", routesPath);
|
|
535
|
+
rmSync(routesPath, { recursive: true });
|
|
536
|
+
}
|
|
537
|
+
mkdirSync(routesPath, { recursive: true });
|
|
538
|
+
console.log("Created temp_routes_folder:", routesPath);
|
|
539
|
+
saveRoutes({ step, folderPath: routesPath });
|
|
540
|
+
} else {
|
|
541
|
+
console.log("Saving routes in project directory:", projectDir);
|
|
542
|
+
if (existsSync(routesPath)) {
|
|
543
|
+
// remove the folder
|
|
544
|
+
try {
|
|
545
|
+
rmSync(routesPath, { recursive: true });
|
|
546
|
+
console.log("Removed temp_routes_folder:", routesPath);
|
|
547
|
+
} catch (error) {
|
|
548
|
+
console.error("Error removing temp_routes folder", error);
|
|
549
|
+
}
|
|
550
|
+
}
|
|
551
|
+
routesPath = path.join(projectDir, "data", "routes");
|
|
552
|
+
console.log("Saving routes to:", routesPath);
|
|
553
|
+
if (!existsSync(routesPath)) {
|
|
554
|
+
mkdirSync(routesPath, { recursive: true });
|
|
555
|
+
}
|
|
556
|
+
saveRoutes({ step, folderPath: routesPath });
|
|
557
|
+
}
|
|
558
|
+
|
|
113
559
|
cucumberStep.text = step.text;
|
|
114
560
|
const recording = new Recording();
|
|
561
|
+
|
|
115
562
|
const steps = step.commands;
|
|
116
563
|
|
|
117
564
|
recording.loadFromObject({ steps, step: cucumberStep });
|
|
@@ -187,12 +634,18 @@ export async function saveRecording({ step, cucumberStep, codePage, projectDir,
|
|
|
187
634
|
if (step.commands && step.commands.length > 0 && step.commands[0]) {
|
|
188
635
|
path = step.commands[0].lastKnownUrlPath;
|
|
189
636
|
}
|
|
637
|
+
let protect = false;
|
|
638
|
+
if (step.commands && step.commands.length > 0 && step.commands[0].type) {
|
|
639
|
+
if (step.commands[0].type === "verify_element_property" || step.commands[0].type === "conditional_wait") {
|
|
640
|
+
protect = true;
|
|
641
|
+
}
|
|
642
|
+
}
|
|
190
643
|
const infraResult = codePage.addInfraCommand(
|
|
191
644
|
methodName,
|
|
192
645
|
description,
|
|
193
646
|
cucumberStep.getVariablesList(),
|
|
194
647
|
generateCodeResult.codeLines,
|
|
195
|
-
|
|
648
|
+
protect,
|
|
196
649
|
"recorder",
|
|
197
650
|
path
|
|
198
651
|
);
|
|
@@ -214,6 +667,7 @@ export async function saveRecording({ step, cucumberStep, codePage, projectDir,
|
|
|
214
667
|
}
|
|
215
668
|
|
|
216
669
|
codePage.removeUnusedElements();
|
|
670
|
+
codePage.mergeSimilarElements();
|
|
217
671
|
cucumberStep.methodName = methodName;
|
|
218
672
|
if (generateCodeResult.locatorsMetadata) {
|
|
219
673
|
codePage.addLocatorsMetadata(generateCodeResult.locatorsMetadata);
|
|
@@ -343,6 +797,12 @@ export async function updateStepDefinitions({ scenario, featureName, projectDir
|
|
|
343
797
|
const utilsTemplateFilePath = path.join(__dirname, "../../assets", "templates", "utils_template.txt");
|
|
344
798
|
const utilsContent = readFileSync(utilsTemplateFilePath, "utf8");
|
|
345
799
|
writeFileSync(utilsFilePath, utilsContent, "utf8");
|
|
800
|
+
const hooksTemplateFilePath = path.join(__dirname, "../../assets", "templates", "_hooks_template.txt");
|
|
801
|
+
if (existsSync(hooksTemplateFilePath)) {
|
|
802
|
+
const hooksFilePath = path.join(stepDefinitionFolderPath, "_hooks.mjs");
|
|
803
|
+
const hooksContent = readFileSync(hooksTemplateFilePath, "utf8");
|
|
804
|
+
writeFileSync(hooksFilePath, hooksContent, "utf8");
|
|
805
|
+
}
|
|
346
806
|
const steps = scenario.steps;
|
|
347
807
|
|
|
348
808
|
const stepsDefinitions = new StepsDefinitions(projectDir);
|
|
@@ -358,6 +818,38 @@ export async function updateStepDefinitions({ scenario, featureName, projectDir
|
|
|
358
818
|
}
|
|
359
819
|
}
|
|
360
820
|
if ((step.isImplemented && !step.shouldOverride) || step.commands.length === 0) {
|
|
821
|
+
let routesPath = path.join(tmpdir(), `blinq_temp_routes`);
|
|
822
|
+
if (process.env.TEMP_RUN === "true") {
|
|
823
|
+
console.log("Save routes in temp folder for running:", routesPath);
|
|
824
|
+
if (existsSync(routesPath)) {
|
|
825
|
+
console.log("Removing existing temp_routes_folder:", routesPath);
|
|
826
|
+
routesPath = path.join(tmpdir(), `blinq_temp_routes`);
|
|
827
|
+
rmSync(routesPath, { recursive: true });
|
|
828
|
+
}
|
|
829
|
+
mkdirSync(routesPath, { recursive: true });
|
|
830
|
+
console.log("Created temp_routes_folder:", routesPath);
|
|
831
|
+
saveRoutes({ step, folderPath: routesPath });
|
|
832
|
+
} else {
|
|
833
|
+
console.log("Saving routes in project directory:", projectDir);
|
|
834
|
+
if (existsSync(routesPath)) {
|
|
835
|
+
// remove the folder
|
|
836
|
+
try {
|
|
837
|
+
rmSync(routesPath, { recursive: true });
|
|
838
|
+
console.log("Removed temp_routes_folder:", routesPath);
|
|
839
|
+
} catch (error) {
|
|
840
|
+
console.error("Error removing temp_routes folder", error);
|
|
841
|
+
}
|
|
842
|
+
}
|
|
843
|
+
routesPath = path.join(projectDir, "data", "routes");
|
|
844
|
+
console.log("Saving routes to:", routesPath);
|
|
845
|
+
if (!existsSync(routesPath)) {
|
|
846
|
+
mkdirSync(routesPath, { recursive: true });
|
|
847
|
+
}
|
|
848
|
+
saveRoutes({ step, folderPath: routesPath });
|
|
849
|
+
}
|
|
850
|
+
if (step.commands && Array.isArray(step.commands)) {
|
|
851
|
+
step.commands = step.commands.map((cmd) => toRecordingStep(cmd, scenario.parametersMap));
|
|
852
|
+
}
|
|
361
853
|
continue;
|
|
362
854
|
}
|
|
363
855
|
const cucumberStep = getCucumberStep({ step });
|
|
@@ -365,7 +857,14 @@ export async function updateStepDefinitions({ scenario, featureName, projectDir
|
|
|
365
857
|
const stepDefsFilePath = locateDefinitionPath(featureFolder, pageName);
|
|
366
858
|
// path.join(stepDefinitionFolderPath, pageName + "_page.mjs");
|
|
367
859
|
let codePage = getCodePage(stepDefsFilePath);
|
|
368
|
-
codePage = await saveRecording({
|
|
860
|
+
codePage = await saveRecording({
|
|
861
|
+
step,
|
|
862
|
+
cucumberStep,
|
|
863
|
+
codePage,
|
|
864
|
+
projectDir,
|
|
865
|
+
stepsDefinitions,
|
|
866
|
+
parametersMap: scenario.parametersMap,
|
|
867
|
+
});
|
|
369
868
|
if (!codePage) {
|
|
370
869
|
continue;
|
|
371
870
|
}
|
|
@@ -385,6 +884,8 @@ export function saveRoutes({ step, folderPath }) {
|
|
|
385
884
|
const cucumberStep = getCucumberStep({ step });
|
|
386
885
|
const template = cucumberStep.getTemplate();
|
|
387
886
|
const stepNameHash = createHash("sha256").update(template).digest("hex");
|
|
887
|
+
console.log("Saving routes for step:", step.text, "with hash:", stepNameHash);
|
|
888
|
+
|
|
388
889
|
const routeItemsWithFilters = routeItems.map((routeItem) => {
|
|
389
890
|
const oldFilters = routeItem.filters;
|
|
390
891
|
const queryParamsObject = {};
|
|
@@ -399,10 +900,13 @@ export function saveRoutes({ step, folderPath }) {
|
|
|
399
900
|
});
|
|
400
901
|
|
|
401
902
|
const routesFilePath = path.join(folderPath, stepNameHash + ".json");
|
|
903
|
+
console.log("Routes file path:", routesFilePath);
|
|
402
904
|
const routesData = {
|
|
403
905
|
template,
|
|
404
906
|
routes: routeItemsWithFilters,
|
|
405
907
|
};
|
|
908
|
+
console.log("Routes data to save:", routesData);
|
|
909
|
+
|
|
406
910
|
if (!existsSync(folderPath)) {
|
|
407
911
|
mkdirSync(folderPath, { recursive: true });
|
|
408
912
|
}
|