@dev-blinq/cucumber_client 1.0.1316-dev → 1.0.1316-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 +156 -48
- 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 -76
- 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 +512 -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,423 @@ 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, isTargetValueVariable, parametersMap }) => {
|
|
336
|
+
if (isValueVariable) {
|
|
337
|
+
const variable = cmd.value.slice(1, -1);
|
|
338
|
+
// const val = parametersMap[variable];
|
|
339
|
+
const replacementFromValue = cmd.text.trim().replace(/\s+/, " ") ?? ""; // val.trim();
|
|
340
|
+
if (replacementFromValue.length > 0) {
|
|
341
|
+
const replacementToValue = `{${variable}}`;
|
|
342
|
+
locs = _parameterizeLocators(locs, replacementFromValue, replacementToValue);
|
|
343
|
+
}
|
|
344
|
+
}
|
|
345
|
+
if (isTargetValueVariable) {
|
|
346
|
+
const variable = cmd.targetValue.slice(1, -1);
|
|
347
|
+
// const val = parametersMap[variable];
|
|
348
|
+
const replacementFromValue = cmd.targetText.trim().replace(/\s+/, " ") ?? ""; // val.trim();
|
|
349
|
+
if (replacementFromValue.length > 0) {
|
|
350
|
+
const replacementToValue = `{${variable}}`;
|
|
351
|
+
locs = _parameterizeLocators(locs, replacementFromValue, replacementToValue);
|
|
352
|
+
}
|
|
353
|
+
}
|
|
354
|
+
return locs;
|
|
355
|
+
};
|
|
356
|
+
|
|
357
|
+
//TODO: IMPORTAN
|
|
358
|
+
export const toRecordingStep = (cmd, parametersMap) => {
|
|
359
|
+
if (cmd.type === "api") {
|
|
360
|
+
return {
|
|
361
|
+
type: "api",
|
|
362
|
+
value: cmd.value,
|
|
363
|
+
};
|
|
364
|
+
}
|
|
365
|
+
const step = _toRecordingStep(cmd);
|
|
366
|
+
const cmdID = {
|
|
367
|
+
cmdId: cmd.id,
|
|
368
|
+
};
|
|
369
|
+
Object.assign(step, cmdID);
|
|
370
|
+
|
|
371
|
+
const locatorsObject = JSON.parse(JSON.stringify(cmd.locators ?? null));
|
|
372
|
+
|
|
373
|
+
if (!locatorsObject) return step;
|
|
374
|
+
|
|
375
|
+
const element_name = cmd?.locators?.element_name ?? `${cmd.label} ${cmd.role ?? "Text"}`;
|
|
376
|
+
locatorsObject.element_name = element_name;
|
|
377
|
+
|
|
378
|
+
const isValueVariable = isVariable(cmd.value);
|
|
379
|
+
const isTargetValueVariable = isVariable(cmd.targetValue);
|
|
380
|
+
const allStrategyLocators = JSON.parse(JSON.stringify(cmd?.allStrategyLocators ?? null));
|
|
381
|
+
step.locators = locatorsObject;
|
|
382
|
+
step.allStrategyLocators = allStrategyLocators;
|
|
383
|
+
step.isLocatorsAssigned = true;
|
|
384
|
+
|
|
385
|
+
if (!isValueVariable && !isTargetValueVariable) {
|
|
386
|
+
return step;
|
|
387
|
+
}
|
|
388
|
+
|
|
389
|
+
if (isValueVariable) {
|
|
390
|
+
step.dataSource = "parameters";
|
|
391
|
+
step.dataKey = convertToIdentifier(cmd.value.slice(1, -1));
|
|
392
|
+
}
|
|
393
|
+
|
|
394
|
+
if (!allStrategyLocators) {
|
|
395
|
+
let locs = locatorsObject.locators;
|
|
396
|
+
locs = parameterizeLocators({
|
|
397
|
+
cmd,
|
|
398
|
+
locs,
|
|
399
|
+
isValueVariable,
|
|
400
|
+
isTargetValueVariable,
|
|
401
|
+
parametersMap,
|
|
402
|
+
});
|
|
403
|
+
locatorsObject.locators = locs;
|
|
404
|
+
return {
|
|
405
|
+
...step,
|
|
406
|
+
locators: locatorsObject,
|
|
407
|
+
};
|
|
408
|
+
}
|
|
409
|
+
|
|
410
|
+
for (const key in allStrategyLocators) {
|
|
411
|
+
if (key === "strategy") continue;
|
|
412
|
+
if (key === "no_text" || key === "custom") continue;
|
|
413
|
+
const locators = allStrategyLocators[key];
|
|
414
|
+
if (locators.length === 0) continue;
|
|
415
|
+
parameterizeLocators({
|
|
416
|
+
cmd,
|
|
417
|
+
locs: locators,
|
|
418
|
+
isValueVariable,
|
|
419
|
+
isTargetValueVariable,
|
|
420
|
+
parametersMap,
|
|
421
|
+
});
|
|
422
|
+
}
|
|
423
|
+
|
|
424
|
+
locatorsObject.locators = allStrategyLocators[allStrategyLocators.strategy] ?? locatorsObject.locators;
|
|
425
|
+
|
|
426
|
+
return {
|
|
427
|
+
...step,
|
|
428
|
+
locators: locatorsObject,
|
|
429
|
+
allStrategyLocators,
|
|
430
|
+
isLocatorsAssigned: true,
|
|
431
|
+
};
|
|
432
|
+
};
|
|
433
|
+
|
|
17
434
|
export const toMethodName = (str) => {
|
|
18
435
|
// Remove any non-word characters (excluding underscore) and trim spaces
|
|
19
436
|
let cleanStr = str.trim().replace(/[^\w\s]/gi, "");
|
|
@@ -70,10 +487,13 @@ function makeStepTextUnique(step, stepsDefinitions) {
|
|
|
70
487
|
step.text = stepText;
|
|
71
488
|
}
|
|
72
489
|
|
|
73
|
-
export async function saveRecording({ step, cucumberStep, codePage, projectDir, stepsDefinitions }) {
|
|
490
|
+
export async function saveRecording({ step, cucumberStep, codePage, projectDir, stepsDefinitions, parametersMap }) {
|
|
491
|
+
if (step.commands && Array.isArray(step.commands)) {
|
|
492
|
+
step.commands = step.commands.map((cmd) => toRecordingStep(cmd, parametersMap));
|
|
493
|
+
}
|
|
74
494
|
let routesPath = path.join(tmpdir(), "blinq_temp_routes");
|
|
75
495
|
|
|
76
|
-
if (process.env.TEMP_RUN) {
|
|
496
|
+
if (process.env.TEMP_RUN === "true") {
|
|
77
497
|
if (existsSync(routesPath)) {
|
|
78
498
|
rmSync(routesPath, { recursive: true });
|
|
79
499
|
}
|
|
@@ -105,13 +525,44 @@ export async function saveRecording({ step, cucumberStep, codePage, projectDir,
|
|
|
105
525
|
codePage = getCodePage(stepDef.file);
|
|
106
526
|
} else {
|
|
107
527
|
const isUtilStep = makeStepTextUnique(step, stepsDefinitions);
|
|
528
|
+
|
|
108
529
|
if (isUtilStep) {
|
|
109
530
|
return;
|
|
110
531
|
}
|
|
111
532
|
}
|
|
112
533
|
|
|
534
|
+
routesPath = path.join(tmpdir(), "blinq_temp_routes");
|
|
535
|
+
if (process.env.TEMP_RUN === "true") {
|
|
536
|
+
console.log("Save routes in temp folder for running:", routesPath);
|
|
537
|
+
if (existsSync(routesPath)) {
|
|
538
|
+
console.log("Removing existing temp_routes_folder:", routesPath);
|
|
539
|
+
rmSync(routesPath, { recursive: true });
|
|
540
|
+
}
|
|
541
|
+
mkdirSync(routesPath, { recursive: true });
|
|
542
|
+
console.log("Created temp_routes_folder:", routesPath);
|
|
543
|
+
saveRoutes({ step, folderPath: routesPath });
|
|
544
|
+
} else {
|
|
545
|
+
console.log("Saving routes in project directory:", projectDir);
|
|
546
|
+
if (existsSync(routesPath)) {
|
|
547
|
+
// remove the folder
|
|
548
|
+
try {
|
|
549
|
+
rmSync(routesPath, { recursive: true });
|
|
550
|
+
console.log("Removed temp_routes_folder:", routesPath);
|
|
551
|
+
} catch (error) {
|
|
552
|
+
console.error("Error removing temp_routes folder", error);
|
|
553
|
+
}
|
|
554
|
+
}
|
|
555
|
+
routesPath = path.join(projectDir, "data", "routes");
|
|
556
|
+
console.log("Saving routes to:", routesPath);
|
|
557
|
+
if (!existsSync(routesPath)) {
|
|
558
|
+
mkdirSync(routesPath, { recursive: true });
|
|
559
|
+
}
|
|
560
|
+
saveRoutes({ step, folderPath: routesPath });
|
|
561
|
+
}
|
|
562
|
+
|
|
113
563
|
cucumberStep.text = step.text;
|
|
114
564
|
const recording = new Recording();
|
|
565
|
+
|
|
115
566
|
const steps = step.commands;
|
|
116
567
|
|
|
117
568
|
recording.loadFromObject({ steps, step: cucumberStep });
|
|
@@ -187,12 +638,18 @@ export async function saveRecording({ step, cucumberStep, codePage, projectDir,
|
|
|
187
638
|
if (step.commands && step.commands.length > 0 && step.commands[0]) {
|
|
188
639
|
path = step.commands[0].lastKnownUrlPath;
|
|
189
640
|
}
|
|
641
|
+
let protect = false;
|
|
642
|
+
if (step.commands && step.commands.length > 0 && step.commands[0].type) {
|
|
643
|
+
if (step.commands[0].type === "verify_element_property" || step.commands[0].type === "conditional_wait") {
|
|
644
|
+
protect = true;
|
|
645
|
+
}
|
|
646
|
+
}
|
|
190
647
|
const infraResult = codePage.addInfraCommand(
|
|
191
648
|
methodName,
|
|
192
649
|
description,
|
|
193
650
|
cucumberStep.getVariablesList(),
|
|
194
651
|
generateCodeResult.codeLines,
|
|
195
|
-
|
|
652
|
+
protect,
|
|
196
653
|
"recorder",
|
|
197
654
|
path
|
|
198
655
|
);
|
|
@@ -214,6 +671,7 @@ export async function saveRecording({ step, cucumberStep, codePage, projectDir,
|
|
|
214
671
|
}
|
|
215
672
|
|
|
216
673
|
codePage.removeUnusedElements();
|
|
674
|
+
codePage.mergeSimilarElements();
|
|
217
675
|
cucumberStep.methodName = methodName;
|
|
218
676
|
if (generateCodeResult.locatorsMetadata) {
|
|
219
677
|
codePage.addLocatorsMetadata(generateCodeResult.locatorsMetadata);
|
|
@@ -343,6 +801,12 @@ export async function updateStepDefinitions({ scenario, featureName, projectDir
|
|
|
343
801
|
const utilsTemplateFilePath = path.join(__dirname, "../../assets", "templates", "utils_template.txt");
|
|
344
802
|
const utilsContent = readFileSync(utilsTemplateFilePath, "utf8");
|
|
345
803
|
writeFileSync(utilsFilePath, utilsContent, "utf8");
|
|
804
|
+
const hooksTemplateFilePath = path.join(__dirname, "../../assets", "templates", "_hooks_template.txt");
|
|
805
|
+
if (existsSync(hooksTemplateFilePath)) {
|
|
806
|
+
const hooksFilePath = path.join(stepDefinitionFolderPath, "_hooks.mjs");
|
|
807
|
+
const hooksContent = readFileSync(hooksTemplateFilePath, "utf8");
|
|
808
|
+
writeFileSync(hooksFilePath, hooksContent, "utf8");
|
|
809
|
+
}
|
|
346
810
|
const steps = scenario.steps;
|
|
347
811
|
|
|
348
812
|
const stepsDefinitions = new StepsDefinitions(projectDir);
|
|
@@ -358,6 +822,38 @@ export async function updateStepDefinitions({ scenario, featureName, projectDir
|
|
|
358
822
|
}
|
|
359
823
|
}
|
|
360
824
|
if ((step.isImplemented && !step.shouldOverride) || step.commands.length === 0) {
|
|
825
|
+
let routesPath = path.join(tmpdir(), `blinq_temp_routes`);
|
|
826
|
+
if (process.env.TEMP_RUN === "true") {
|
|
827
|
+
console.log("Save routes in temp folder for running:", routesPath);
|
|
828
|
+
if (existsSync(routesPath)) {
|
|
829
|
+
console.log("Removing existing temp_routes_folder:", routesPath);
|
|
830
|
+
routesPath = path.join(tmpdir(), `blinq_temp_routes`);
|
|
831
|
+
rmSync(routesPath, { recursive: true });
|
|
832
|
+
}
|
|
833
|
+
mkdirSync(routesPath, { recursive: true });
|
|
834
|
+
console.log("Created temp_routes_folder:", routesPath);
|
|
835
|
+
saveRoutes({ step, folderPath: routesPath });
|
|
836
|
+
} else {
|
|
837
|
+
console.log("Saving routes in project directory:", projectDir);
|
|
838
|
+
if (existsSync(routesPath)) {
|
|
839
|
+
// remove the folder
|
|
840
|
+
try {
|
|
841
|
+
rmSync(routesPath, { recursive: true });
|
|
842
|
+
console.log("Removed temp_routes_folder:", routesPath);
|
|
843
|
+
} catch (error) {
|
|
844
|
+
console.error("Error removing temp_routes folder", error);
|
|
845
|
+
}
|
|
846
|
+
}
|
|
847
|
+
routesPath = path.join(projectDir, "data", "routes");
|
|
848
|
+
console.log("Saving routes to:", routesPath);
|
|
849
|
+
if (!existsSync(routesPath)) {
|
|
850
|
+
mkdirSync(routesPath, { recursive: true });
|
|
851
|
+
}
|
|
852
|
+
saveRoutes({ step, folderPath: routesPath });
|
|
853
|
+
}
|
|
854
|
+
if (step.commands && Array.isArray(step.commands)) {
|
|
855
|
+
step.commands = step.commands.map((cmd) => toRecordingStep(cmd, scenario.parametersMap));
|
|
856
|
+
}
|
|
361
857
|
continue;
|
|
362
858
|
}
|
|
363
859
|
const cucumberStep = getCucumberStep({ step });
|
|
@@ -365,7 +861,14 @@ export async function updateStepDefinitions({ scenario, featureName, projectDir
|
|
|
365
861
|
const stepDefsFilePath = locateDefinitionPath(featureFolder, pageName);
|
|
366
862
|
// path.join(stepDefinitionFolderPath, pageName + "_page.mjs");
|
|
367
863
|
let codePage = getCodePage(stepDefsFilePath);
|
|
368
|
-
codePage = await saveRecording({
|
|
864
|
+
codePage = await saveRecording({
|
|
865
|
+
step,
|
|
866
|
+
cucumberStep,
|
|
867
|
+
codePage,
|
|
868
|
+
projectDir,
|
|
869
|
+
stepsDefinitions,
|
|
870
|
+
parametersMap: scenario.parametersMap,
|
|
871
|
+
});
|
|
369
872
|
if (!codePage) {
|
|
370
873
|
continue;
|
|
371
874
|
}
|
|
@@ -385,6 +888,8 @@ export function saveRoutes({ step, folderPath }) {
|
|
|
385
888
|
const cucumberStep = getCucumberStep({ step });
|
|
386
889
|
const template = cucumberStep.getTemplate();
|
|
387
890
|
const stepNameHash = createHash("sha256").update(template).digest("hex");
|
|
891
|
+
console.log("Saving routes for step:", step.text, "with hash:", stepNameHash);
|
|
892
|
+
|
|
388
893
|
const routeItemsWithFilters = routeItems.map((routeItem) => {
|
|
389
894
|
const oldFilters = routeItem.filters;
|
|
390
895
|
const queryParamsObject = {};
|
|
@@ -399,10 +904,13 @@ export function saveRoutes({ step, folderPath }) {
|
|
|
399
904
|
});
|
|
400
905
|
|
|
401
906
|
const routesFilePath = path.join(folderPath, stepNameHash + ".json");
|
|
907
|
+
console.log("Routes file path:", routesFilePath);
|
|
402
908
|
const routesData = {
|
|
403
909
|
template,
|
|
404
910
|
routes: routeItemsWithFilters,
|
|
405
911
|
};
|
|
912
|
+
console.log("Routes data to save:", routesData);
|
|
913
|
+
|
|
406
914
|
if (!existsSync(folderPath)) {
|
|
407
915
|
mkdirSync(folderPath, { recursive: true });
|
|
408
916
|
}
|