@dev-blinq/cucumber_client 1.0.1430-dev → 1.0.1430-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 +73 -73
- package/bin/assets/preload/css_gen.js +10 -10
- 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 +70 -45
- package/bin/assets/scripts/snapshot_capturer.js +147 -147
- package/bin/assets/scripts/unique_locators.js +170 -49
- package/bin/assets/scripts/yaml.js +796 -783
- package/bin/assets/templates/_hooks_template.txt +6 -2
- package/bin/assets/templates/utils_template.txt +16 -16
- package/bin/client/code_cleanup/find_step_definition_references.js +0 -1
- package/bin/client/code_gen/api_codegen.js +2 -2
- package/bin/client/code_gen/code_inversion.js +63 -2
- package/bin/client/code_gen/function_signature.js +4 -0
- package/bin/client/code_gen/page_reflection.js +52 -11
- package/bin/client/code_gen/playwright_codeget.js +28 -22
- package/bin/client/cucumber/feature_data.js +2 -2
- package/bin/client/cucumber/project_to_document.js +8 -2
- package/bin/client/cucumber/steps_definitions.js +19 -3
- package/bin/client/local_agent.js +3 -2
- package/bin/client/parse_feature_file.js +23 -26
- package/bin/client/playground/projects/env.json +2 -2
- package/bin/client/recorderv3/bvt_init.js +363 -0
- package/bin/client/recorderv3/bvt_recorder.js +1009 -47
- package/bin/client/recorderv3/implemented_steps.js +2 -0
- package/bin/client/recorderv3/index.js +3 -283
- package/bin/client/recorderv3/scriptTest.js +1 -1
- package/bin/client/recorderv3/services.js +818 -142
- package/bin/client/recorderv3/step_runner.js +28 -8
- package/bin/client/recorderv3/step_utils.js +514 -39
- package/bin/client/recorderv3/update_feature.js +32 -13
- package/bin/client/recorderv3/wbr_entry.js +61 -0
- package/bin/client/recording.js +1 -0
- package/bin/client/upload-service.js +4 -2
- package/bin/client/utils/socket_logger.js +1 -1
- package/bin/index.js +4 -1
- package/package.json +6 -4
|
@@ -14,6 +14,431 @@ 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, stepText) => {
|
|
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
|
+
valueInStepText: stepText && typeof stepText === "string" ? stepText.includes(`"${cmd.value}"`) : false,
|
|
254
|
+
};
|
|
255
|
+
}
|
|
256
|
+
case "conditional_wait": {
|
|
257
|
+
return {
|
|
258
|
+
type: "conditional_wait",
|
|
259
|
+
element: {
|
|
260
|
+
role: cmd.role,
|
|
261
|
+
name: cmd.label,
|
|
262
|
+
},
|
|
263
|
+
parameters: [cmd.timeout, cmd.selectedField, cmd.value],
|
|
264
|
+
lastKnownUrlPath: cmd.lastKnownUrlPath,
|
|
265
|
+
valueInStepText: stepText && typeof stepText === "string" ? stepText.includes(`"${cmd.value}"`) : false,
|
|
266
|
+
};
|
|
267
|
+
}
|
|
268
|
+
case "navigate": {
|
|
269
|
+
return {
|
|
270
|
+
type: "navigate",
|
|
271
|
+
parameters: [cmd.value],
|
|
272
|
+
lastKnownUrlPath: cmd.lastKnownUrlPath,
|
|
273
|
+
};
|
|
274
|
+
}
|
|
275
|
+
case "browser_go_back": {
|
|
276
|
+
return {
|
|
277
|
+
type: "browser_go_back",
|
|
278
|
+
};
|
|
279
|
+
}
|
|
280
|
+
case "browser_go_forward": {
|
|
281
|
+
return {
|
|
282
|
+
type: "browser_go_forward",
|
|
283
|
+
};
|
|
284
|
+
}
|
|
285
|
+
case "set_input_files": {
|
|
286
|
+
return {
|
|
287
|
+
type: "set_input_files",
|
|
288
|
+
element: {
|
|
289
|
+
role: cmd.role,
|
|
290
|
+
name: cmd.label,
|
|
291
|
+
},
|
|
292
|
+
parameters: [cmd.files],
|
|
293
|
+
lastKnownUrlPath: cmd.lastKnownUrlPath,
|
|
294
|
+
};
|
|
295
|
+
}
|
|
296
|
+
case "verify_page_snapshot": {
|
|
297
|
+
return {
|
|
298
|
+
type: "verify_page_snapshot",
|
|
299
|
+
parameters: [cmd.value],
|
|
300
|
+
selectors: cmd.selectors,
|
|
301
|
+
data: cmd.data,
|
|
302
|
+
valueInStepText: stepText && typeof stepText === "string" ? stepText.includes(`"${cmd.value}"`) : false,
|
|
303
|
+
};
|
|
304
|
+
}
|
|
305
|
+
default: {
|
|
306
|
+
return {
|
|
307
|
+
type: cmd.type,
|
|
308
|
+
parameters: [cmd.value],
|
|
309
|
+
lastKnownUrlPath: cmd.lastKnownUrlPath,
|
|
310
|
+
};
|
|
311
|
+
}
|
|
312
|
+
}
|
|
313
|
+
};
|
|
314
|
+
|
|
315
|
+
function getBestStrategy(allStrategyLocators) {
|
|
316
|
+
const orderedPriorities = ["custom", "context", "basic", "text_with_index", "ignore_digit", "no_text"];
|
|
317
|
+
for (const strategy of orderedPriorities) {
|
|
318
|
+
if (allStrategyLocators[strategy] && allStrategyLocators[strategy].length > 0) {
|
|
319
|
+
return strategy;
|
|
320
|
+
}
|
|
321
|
+
}
|
|
322
|
+
return null;
|
|
323
|
+
}
|
|
324
|
+
|
|
325
|
+
const _parameterizeLocators = (locators, replacementFromValue, replacementToValue) => {
|
|
326
|
+
for (const loc of locators) {
|
|
327
|
+
if (loc?.css?.includes(replacementFromValue)) {
|
|
328
|
+
loc.css = loc.css.replaceAll(replacementFromValue, replacementToValue);
|
|
329
|
+
}
|
|
330
|
+
if (loc?.text?.includes(replacementFromValue)) {
|
|
331
|
+
loc.text = loc.text.replaceAll(replacementFromValue, replacementToValue);
|
|
332
|
+
}
|
|
333
|
+
if (loc?.climb && typeof loc.climb === "string" && loc.climb?.includes(replacementFromValue)) {
|
|
334
|
+
loc.climb = loc.climb.replaceAll(replacementFromValue, replacementToValue);
|
|
335
|
+
}
|
|
336
|
+
}
|
|
337
|
+
return locators;
|
|
338
|
+
};
|
|
339
|
+
const parameterizeLocators = ({ cmd, locs, isValueVariable, isTargetValueVariable, parametersMap }) => {
|
|
340
|
+
if (isValueVariable) {
|
|
341
|
+
const variable = cmd.value.slice(1, -1);
|
|
342
|
+
// const val = parametersMap[variable];
|
|
343
|
+
if (typeof cmd.text === "string") {
|
|
344
|
+
const replacementFromValue = cmd.text.trim().replace(/\s+/g, " ") ?? ""; // val.trim();
|
|
345
|
+
if (replacementFromValue.length > 0) {
|
|
346
|
+
const replacementToValue = `{${variable}}`;
|
|
347
|
+
locs = _parameterizeLocators(locs, replacementFromValue, replacementToValue);
|
|
348
|
+
}
|
|
349
|
+
}
|
|
350
|
+
}
|
|
351
|
+
if (isTargetValueVariable) {
|
|
352
|
+
const variable = cmd.targetValue.slice(1, -1);
|
|
353
|
+
// const val = parametersMap[variable];
|
|
354
|
+
if (typeof cmd.targetText === "string") {
|
|
355
|
+
const replacementFromValue = cmd.targetText.trim().replace(/\s+/g, " ") ?? ""; // val.trim();
|
|
356
|
+
if (replacementFromValue.length > 0) {
|
|
357
|
+
const replacementToValue = `{${variable}}`;
|
|
358
|
+
locs = _parameterizeLocators(locs, replacementFromValue, replacementToValue);
|
|
359
|
+
}
|
|
360
|
+
}
|
|
361
|
+
}
|
|
362
|
+
return locs;
|
|
363
|
+
};
|
|
364
|
+
|
|
365
|
+
//TODO: IMPORTAN
|
|
366
|
+
export const toRecordingStep = (cmd, parametersMap, stepText) => {
|
|
367
|
+
if (cmd.type === "api") {
|
|
368
|
+
return {
|
|
369
|
+
type: "api",
|
|
370
|
+
value: cmd.value,
|
|
371
|
+
};
|
|
372
|
+
}
|
|
373
|
+
const step = _toRecordingStep(cmd, stepText);
|
|
374
|
+
const cmdID = {
|
|
375
|
+
cmdId: cmd.id,
|
|
376
|
+
};
|
|
377
|
+
Object.assign(step, cmdID);
|
|
378
|
+
|
|
379
|
+
const locatorsObject = JSON.parse(JSON.stringify(cmd.locators ?? null));
|
|
380
|
+
|
|
381
|
+
if (!locatorsObject) return step;
|
|
382
|
+
|
|
383
|
+
const element_name = cmd?.locators?.element_name ?? `${cmd.label} ${cmd.role ?? "Text"}`;
|
|
384
|
+
locatorsObject.element_name = element_name;
|
|
385
|
+
|
|
386
|
+
const isValueVariable = isVariable(cmd.value);
|
|
387
|
+
const isTargetValueVariable = isVariable(cmd.targetValue);
|
|
388
|
+
const allStrategyLocators = JSON.parse(JSON.stringify(cmd?.allStrategyLocators ?? null));
|
|
389
|
+
step.locators = locatorsObject;
|
|
390
|
+
step.allStrategyLocators = allStrategyLocators;
|
|
391
|
+
step.isLocatorsAssigned = true;
|
|
392
|
+
|
|
393
|
+
if (!isValueVariable && !isTargetValueVariable) {
|
|
394
|
+
return step;
|
|
395
|
+
}
|
|
396
|
+
|
|
397
|
+
if (isValueVariable) {
|
|
398
|
+
step.dataSource = "parameters";
|
|
399
|
+
step.dataKey = convertToIdentifier(cmd.value.slice(1, -1));
|
|
400
|
+
}
|
|
401
|
+
|
|
402
|
+
if (!allStrategyLocators) {
|
|
403
|
+
let locs = locatorsObject.locators;
|
|
404
|
+
locs = parameterizeLocators({
|
|
405
|
+
cmd,
|
|
406
|
+
locs,
|
|
407
|
+
isValueVariable,
|
|
408
|
+
isTargetValueVariable,
|
|
409
|
+
parametersMap,
|
|
410
|
+
});
|
|
411
|
+
locatorsObject.locators = locs;
|
|
412
|
+
return {
|
|
413
|
+
...step,
|
|
414
|
+
locators: locatorsObject,
|
|
415
|
+
};
|
|
416
|
+
}
|
|
417
|
+
|
|
418
|
+
for (const key in allStrategyLocators) {
|
|
419
|
+
if (key === "strategy") continue;
|
|
420
|
+
if (key === "no_text" || key === "custom") continue;
|
|
421
|
+
const locators = allStrategyLocators[key];
|
|
422
|
+
if (locators.length === 0) continue;
|
|
423
|
+
parameterizeLocators({
|
|
424
|
+
cmd,
|
|
425
|
+
locs: locators,
|
|
426
|
+
isValueVariable,
|
|
427
|
+
isTargetValueVariable,
|
|
428
|
+
parametersMap,
|
|
429
|
+
});
|
|
430
|
+
}
|
|
431
|
+
|
|
432
|
+
locatorsObject.locators = allStrategyLocators[allStrategyLocators.strategy] ?? locatorsObject.locators;
|
|
433
|
+
|
|
434
|
+
return {
|
|
435
|
+
...step,
|
|
436
|
+
locators: locatorsObject,
|
|
437
|
+
allStrategyLocators,
|
|
438
|
+
isLocatorsAssigned: true,
|
|
439
|
+
};
|
|
440
|
+
};
|
|
441
|
+
|
|
17
442
|
export const toMethodName = (str) => {
|
|
18
443
|
// Remove any non-word characters (excluding underscore) and trim spaces
|
|
19
444
|
let cleanStr = str.trim().replace(/[^\w\s]/gi, "");
|
|
@@ -36,7 +461,7 @@ export function getCodePage(stepDefsFilePath) {
|
|
|
36
461
|
export function getCucumberStep({ step }) {
|
|
37
462
|
const cucumberStep = new Step();
|
|
38
463
|
cucumberStep.loadFromJson({
|
|
39
|
-
text: step.text,
|
|
464
|
+
text: step.renamedText ? step.renamedText : step.text,
|
|
40
465
|
keyword: step.keyword,
|
|
41
466
|
keywordType: step.keywordType,
|
|
42
467
|
parameters: [],
|
|
@@ -54,7 +479,7 @@ export function getCucumberStep({ step }) {
|
|
|
54
479
|
|
|
55
480
|
function makeStepTextUnique(step, stepsDefinitions) {
|
|
56
481
|
// const utilsFilePath = path.join("features", "step_definitions", "utils.mjs");
|
|
57
|
-
let stepText = step.text;
|
|
482
|
+
let stepText = step.renamedText ? step.renamedText : step.text;
|
|
58
483
|
let stepIndex = 1;
|
|
59
484
|
// console.log("makeStepTextUnique", step.text);
|
|
60
485
|
let stepDef = stepsDefinitions.findMatchingStep(stepText);
|
|
@@ -70,10 +495,13 @@ function makeStepTextUnique(step, stepsDefinitions) {
|
|
|
70
495
|
step.text = stepText;
|
|
71
496
|
}
|
|
72
497
|
|
|
73
|
-
export async function saveRecording({ step, cucumberStep, codePage, projectDir, stepsDefinitions }) {
|
|
498
|
+
export async function saveRecording({ step, cucumberStep, codePage, projectDir, stepsDefinitions, parametersMap }) {
|
|
499
|
+
if (step.commands && Array.isArray(step.commands)) {
|
|
500
|
+
step.commands = step.commands.map((cmd) => toRecordingStep(cmd, parametersMap, step.text));
|
|
501
|
+
}
|
|
74
502
|
let routesPath = path.join(tmpdir(), "blinq_temp_routes");
|
|
75
503
|
|
|
76
|
-
if (process.env.TEMP_RUN) {
|
|
504
|
+
if (process.env.TEMP_RUN === "true") {
|
|
77
505
|
if (existsSync(routesPath)) {
|
|
78
506
|
rmSync(routesPath, { recursive: true });
|
|
79
507
|
}
|
|
@@ -84,9 +512,9 @@ export async function saveRecording({ step, cucumberStep, codePage, projectDir,
|
|
|
84
512
|
// remove the folder
|
|
85
513
|
try {
|
|
86
514
|
rmSync(routesPath, { recursive: true });
|
|
87
|
-
|
|
515
|
+
//
|
|
88
516
|
} catch (error) {
|
|
89
|
-
|
|
517
|
+
//
|
|
90
518
|
}
|
|
91
519
|
routesPath = path.join(projectDir, "data", "routes");
|
|
92
520
|
if (!existsSync(routesPath)) {
|
|
@@ -107,32 +535,37 @@ export async function saveRecording({ step, cucumberStep, codePage, projectDir,
|
|
|
107
535
|
const isUtilStep = makeStepTextUnique(step, stepsDefinitions);
|
|
108
536
|
|
|
109
537
|
if (isUtilStep) {
|
|
110
|
-
|
|
538
|
+
if (!step.renamedText) {
|
|
539
|
+
return;
|
|
540
|
+
}
|
|
541
|
+
step.text = step.text.trim();
|
|
542
|
+
const { functionName } = stepsDefinitions.findMatchingStep(step.renamedText);
|
|
543
|
+
step.renamedText = functionName;
|
|
544
|
+
const newImportLine = `import { ${functionName} } from "./utils.mjs";\n`;
|
|
545
|
+
|
|
546
|
+
if (!codePage.fileContent.includes(newImportLine)) {
|
|
547
|
+
codePage.fileContent = newImportLine + codePage.fileContent;
|
|
548
|
+
}
|
|
111
549
|
}
|
|
112
550
|
}
|
|
113
551
|
|
|
552
|
+
routesPath = path.join(tmpdir(), "blinq_temp_routes");
|
|
114
553
|
if (process.env.TEMP_RUN === "true") {
|
|
115
|
-
console.log("Save routes in temp folder for running:", routesPath);
|
|
116
554
|
if (existsSync(routesPath)) {
|
|
117
|
-
console.log("Removing existing temp_routes_folder:", routesPath);
|
|
118
555
|
rmSync(routesPath, { recursive: true });
|
|
119
556
|
}
|
|
120
557
|
mkdirSync(routesPath, { recursive: true });
|
|
121
|
-
console.log("Created temp_routes_folder:", routesPath);
|
|
122
558
|
saveRoutes({ step, folderPath: routesPath });
|
|
123
559
|
} else {
|
|
124
|
-
console.log("Saving routes in project directory:", projectDir);
|
|
125
560
|
if (existsSync(routesPath)) {
|
|
126
561
|
// remove the folder
|
|
127
562
|
try {
|
|
128
563
|
rmSync(routesPath, { recursive: true });
|
|
129
|
-
console.log("Removed temp_routes_folder:", routesPath);
|
|
130
564
|
} catch (error) {
|
|
131
|
-
|
|
565
|
+
//
|
|
132
566
|
}
|
|
133
567
|
}
|
|
134
568
|
routesPath = path.join(projectDir, "data", "routes");
|
|
135
|
-
console.log("Saving routes to:", routesPath);
|
|
136
569
|
if (!existsSync(routesPath)) {
|
|
137
570
|
mkdirSync(routesPath, { recursive: true });
|
|
138
571
|
}
|
|
@@ -141,6 +574,7 @@ export async function saveRecording({ step, cucumberStep, codePage, projectDir,
|
|
|
141
574
|
|
|
142
575
|
cucumberStep.text = step.text;
|
|
143
576
|
const recording = new Recording();
|
|
577
|
+
|
|
144
578
|
const steps = step.commands;
|
|
145
579
|
|
|
146
580
|
recording.loadFromObject({ steps, step: cucumberStep });
|
|
@@ -191,7 +625,7 @@ export async function saveRecording({ step, cucumberStep, codePage, projectDir,
|
|
|
191
625
|
stepsDefinitions
|
|
192
626
|
);
|
|
193
627
|
|
|
194
|
-
if (!step.isImplemented) {
|
|
628
|
+
if (!step.renamedText && !(step.isImplemented && step.shouldOverride)) {
|
|
195
629
|
stepsDefinitions.addStep({
|
|
196
630
|
name: step.text,
|
|
197
631
|
file: result.codePage.sourceFileName,
|
|
@@ -209,7 +643,10 @@ export async function saveRecording({ step, cucumberStep, codePage, projectDir,
|
|
|
209
643
|
}
|
|
210
644
|
codePage = generateCodeResult.page;
|
|
211
645
|
methodName = generateCodeResult.methodName;
|
|
212
|
-
|
|
646
|
+
|
|
647
|
+
if (!step.renamedText) {
|
|
648
|
+
codePage.insertElements(generateCodeResult.elements);
|
|
649
|
+
}
|
|
213
650
|
|
|
214
651
|
const description = cucumberStep.text;
|
|
215
652
|
let path = null;
|
|
@@ -222,15 +659,32 @@ export async function saveRecording({ step, cucumberStep, codePage, projectDir,
|
|
|
222
659
|
protect = true;
|
|
223
660
|
}
|
|
224
661
|
}
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
662
|
+
|
|
663
|
+
if (step.renamedText) {
|
|
664
|
+
codePage.addInfraCommandUtil(
|
|
665
|
+
methodName,
|
|
666
|
+
description,
|
|
667
|
+
cucumberStep.parameters,
|
|
668
|
+
generateCodeResult.codeLines,
|
|
669
|
+
step.renamedText,
|
|
670
|
+
step.text,
|
|
671
|
+
parametersMap,
|
|
672
|
+
protect,
|
|
673
|
+
"recorder",
|
|
674
|
+
path
|
|
675
|
+
);
|
|
676
|
+
} else {
|
|
677
|
+
codePage.addInfraCommand(
|
|
678
|
+
methodName,
|
|
679
|
+
description,
|
|
680
|
+
cucumberStep.getVariablesList(),
|
|
681
|
+
generateCodeResult.codeLines,
|
|
682
|
+
protect,
|
|
683
|
+
"recorder",
|
|
684
|
+
path
|
|
685
|
+
);
|
|
686
|
+
}
|
|
687
|
+
|
|
234
688
|
const keyword = (cucumberStep.keywordAlias ?? cucumberStep.keyword).trim();
|
|
235
689
|
const stepResult = codePage.addCucumberStep(
|
|
236
690
|
keyword,
|
|
@@ -240,7 +694,7 @@ export async function saveRecording({ step, cucumberStep, codePage, projectDir,
|
|
|
240
694
|
step.finalTimeout
|
|
241
695
|
);
|
|
242
696
|
|
|
243
|
-
if (!step.isImplemented) {
|
|
697
|
+
if (!step.renamedText && !(step.isImplemented && step.shouldOverride)) {
|
|
244
698
|
stepsDefinitions.addStep({
|
|
245
699
|
name: step.text,
|
|
246
700
|
file: codePage.sourceFileName,
|
|
@@ -249,6 +703,7 @@ export async function saveRecording({ step, cucumberStep, codePage, projectDir,
|
|
|
249
703
|
}
|
|
250
704
|
|
|
251
705
|
codePage.removeUnusedElements();
|
|
706
|
+
codePage.mergeSimilarElements();
|
|
252
707
|
cucumberStep.methodName = methodName;
|
|
253
708
|
if (generateCodeResult.locatorsMetadata) {
|
|
254
709
|
codePage.addLocatorsMetadata(generateCodeResult.locatorsMetadata);
|
|
@@ -300,26 +755,35 @@ export const getCommandsForImplementedStep = (stepName, stepsDefinitions, stepPa
|
|
|
300
755
|
if (error) {
|
|
301
756
|
throw new Error(error);
|
|
302
757
|
}
|
|
758
|
+
isUtilStep = codePage.sourceFileName.endsWith("utils.mjs");
|
|
303
759
|
|
|
304
760
|
if (parametersNames.length !== stepParams.length) {
|
|
305
761
|
// console.log("Parameters mismatch", parametersNames, stepParams);
|
|
306
762
|
throw new Error("Parameters mismatch");
|
|
307
763
|
}
|
|
308
|
-
for (let i = 0; i < parametersNames.length; i++) {
|
|
309
|
-
stepParams[i].argumentName = parametersNames[i];
|
|
310
|
-
}
|
|
311
764
|
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
765
|
+
const pattern = step.name;
|
|
766
|
+
if (isUtilStep && pattern === "Verify the file {string} exists") {
|
|
767
|
+
commands.push({
|
|
768
|
+
type: "verify_file_exists",
|
|
769
|
+
parameters: [stepParams[0].text],
|
|
770
|
+
});
|
|
771
|
+
} else {
|
|
772
|
+
for (let i = 0; i < parametersNames.length; i++) {
|
|
773
|
+
stepParams[i].argumentName = parametersNames[i];
|
|
774
|
+
}
|
|
775
|
+
|
|
776
|
+
for (const { code } of codeCommands) {
|
|
777
|
+
const command = invertCodeToCommand(code, elements, stepParams, stepsDefinitions, codePage, stepName)[0];
|
|
778
|
+
if (command === undefined || command.type === null) continue;
|
|
779
|
+
if (command.element) {
|
|
780
|
+
const key = command.element.key;
|
|
781
|
+
if (key && locatorsJson[key]) {
|
|
782
|
+
command.allStrategyLocators = locatorsJson[key];
|
|
783
|
+
}
|
|
320
784
|
}
|
|
785
|
+
commands.push(command);
|
|
321
786
|
}
|
|
322
|
-
commands.push(command);
|
|
323
787
|
}
|
|
324
788
|
} catch (error) {
|
|
325
789
|
console.error(error);
|
|
@@ -404,6 +868,7 @@ export async function updateStepDefinitions({ scenario, featureName, projectDir
|
|
|
404
868
|
console.log("Save routes in temp folder for running:", routesPath);
|
|
405
869
|
if (existsSync(routesPath)) {
|
|
406
870
|
console.log("Removing existing temp_routes_folder:", routesPath);
|
|
871
|
+
routesPath = path.join(tmpdir(), `blinq_temp_routes`);
|
|
407
872
|
rmSync(routesPath, { recursive: true });
|
|
408
873
|
}
|
|
409
874
|
mkdirSync(routesPath, { recursive: true });
|
|
@@ -427,6 +892,9 @@ export async function updateStepDefinitions({ scenario, featureName, projectDir
|
|
|
427
892
|
}
|
|
428
893
|
saveRoutes({ step, folderPath: routesPath });
|
|
429
894
|
}
|
|
895
|
+
if (step.commands && Array.isArray(step.commands)) {
|
|
896
|
+
step.commands = step.commands.map((cmd) => toRecordingStep(cmd, scenario.parametersMap));
|
|
897
|
+
}
|
|
430
898
|
continue;
|
|
431
899
|
}
|
|
432
900
|
const cucumberStep = getCucumberStep({ step });
|
|
@@ -434,7 +902,14 @@ export async function updateStepDefinitions({ scenario, featureName, projectDir
|
|
|
434
902
|
const stepDefsFilePath = locateDefinitionPath(featureFolder, pageName);
|
|
435
903
|
// path.join(stepDefinitionFolderPath, pageName + "_page.mjs");
|
|
436
904
|
let codePage = getCodePage(stepDefsFilePath);
|
|
437
|
-
codePage = await saveRecording({
|
|
905
|
+
codePage = await saveRecording({
|
|
906
|
+
step,
|
|
907
|
+
cucumberStep,
|
|
908
|
+
codePage,
|
|
909
|
+
projectDir,
|
|
910
|
+
stepsDefinitions,
|
|
911
|
+
parametersMap: scenario.parametersMap,
|
|
912
|
+
});
|
|
438
913
|
if (!codePage) {
|
|
439
914
|
continue;
|
|
440
915
|
}
|