@dev-blinq/cucumber_client 1.0.1410-dev → 1.0.1410-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 +105 -105
- 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 +163 -44
- 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_cleanup/utils.js +5 -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 +846 -906
- package/bin/client/code_gen/playwright_codeget.js +27 -3
- package/bin/client/cucumber/feature.js +4 -0
- 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/cucumber_selector.js +4 -0
- 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/project.js +186 -202
- package/bin/client/recorderv3/bvt_init.js +363 -0
- package/bin/client/recorderv3/bvt_recorder.js +1056 -93
- package/bin/client/recorderv3/implemented_steps.js +2 -0
- package/bin/client/recorderv3/index.js +4 -311
- package/bin/client/recorderv3/scriptTest.js +1 -1
- package/bin/client/recorderv3/services.js +814 -154
- package/bin/client/recorderv3/step_runner.js +36 -10
- package/bin/client/recorderv3/step_utils.js +503 -51
- package/bin/client/recorderv3/update_feature.js +9 -5
- package/bin/client/recorderv3/wbr_entry.js +61 -0
- package/bin/client/recording.js +1 -0
- package/bin/client/upload-service.js +3 -2
- package/bin/client/utils/socket_logger.js +132 -0
- package/bin/index.js +4 -1
- 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 +19 -9
|
@@ -14,6 +14,428 @@ 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
|
+
data: cmd.data,
|
|
300
|
+
};
|
|
301
|
+
}
|
|
302
|
+
default: {
|
|
303
|
+
return {
|
|
304
|
+
type: cmd.type,
|
|
305
|
+
parameters: [cmd.value],
|
|
306
|
+
lastKnownUrlPath: cmd.lastKnownUrlPath,
|
|
307
|
+
};
|
|
308
|
+
}
|
|
309
|
+
}
|
|
310
|
+
};
|
|
311
|
+
|
|
312
|
+
function getBestStrategy(allStrategyLocators) {
|
|
313
|
+
const orderedPriorities = ["custom", "context", "basic", "text_with_index", "ignore_digit", "no_text"];
|
|
314
|
+
for (const strategy of orderedPriorities) {
|
|
315
|
+
if (allStrategyLocators[strategy] && allStrategyLocators[strategy].length > 0) {
|
|
316
|
+
return strategy;
|
|
317
|
+
}
|
|
318
|
+
}
|
|
319
|
+
return null;
|
|
320
|
+
}
|
|
321
|
+
|
|
322
|
+
const _parameterizeLocators = (locators, replacementFromValue, replacementToValue) => {
|
|
323
|
+
for (const loc of locators) {
|
|
324
|
+
if (loc?.css?.includes(replacementFromValue)) {
|
|
325
|
+
loc.css = loc.css.replaceAll(replacementFromValue, replacementToValue);
|
|
326
|
+
}
|
|
327
|
+
if (loc?.text?.includes(replacementFromValue)) {
|
|
328
|
+
loc.text = loc.text.replaceAll(replacementFromValue, replacementToValue);
|
|
329
|
+
}
|
|
330
|
+
if (loc?.climb && typeof loc.climb === "string" && loc.climb?.includes(replacementFromValue)) {
|
|
331
|
+
loc.climb = loc.climb.replaceAll(replacementFromValue, replacementToValue);
|
|
332
|
+
}
|
|
333
|
+
}
|
|
334
|
+
return locators;
|
|
335
|
+
};
|
|
336
|
+
const parameterizeLocators = ({ cmd, locs, isValueVariable, isTargetValueVariable, parametersMap }) => {
|
|
337
|
+
if (isValueVariable) {
|
|
338
|
+
const variable = cmd.value.slice(1, -1);
|
|
339
|
+
// const val = parametersMap[variable];
|
|
340
|
+
if (typeof cmd.text === "string") {
|
|
341
|
+
const replacementFromValue = cmd.text.trim().replace(/\s+/g, " ") ?? ""; // val.trim();
|
|
342
|
+
if (replacementFromValue.length > 0) {
|
|
343
|
+
const replacementToValue = `{${variable}}`;
|
|
344
|
+
locs = _parameterizeLocators(locs, replacementFromValue, replacementToValue);
|
|
345
|
+
}
|
|
346
|
+
}
|
|
347
|
+
}
|
|
348
|
+
if (isTargetValueVariable) {
|
|
349
|
+
const variable = cmd.targetValue.slice(1, -1);
|
|
350
|
+
// const val = parametersMap[variable];
|
|
351
|
+
if (typeof cmd.targetText === "string") {
|
|
352
|
+
const replacementFromValue = cmd.targetText.trim().replace(/\s+/g, " ") ?? ""; // val.trim();
|
|
353
|
+
if (replacementFromValue.length > 0) {
|
|
354
|
+
const replacementToValue = `{${variable}}`;
|
|
355
|
+
locs = _parameterizeLocators(locs, replacementFromValue, replacementToValue);
|
|
356
|
+
}
|
|
357
|
+
}
|
|
358
|
+
}
|
|
359
|
+
return locs;
|
|
360
|
+
};
|
|
361
|
+
|
|
362
|
+
//TODO: IMPORTAN
|
|
363
|
+
export const toRecordingStep = (cmd, parametersMap) => {
|
|
364
|
+
if (cmd.type === "api") {
|
|
365
|
+
return {
|
|
366
|
+
type: "api",
|
|
367
|
+
value: cmd.value,
|
|
368
|
+
};
|
|
369
|
+
}
|
|
370
|
+
const step = _toRecordingStep(cmd);
|
|
371
|
+
const cmdID = {
|
|
372
|
+
cmdId: cmd.id,
|
|
373
|
+
};
|
|
374
|
+
Object.assign(step, cmdID);
|
|
375
|
+
|
|
376
|
+
const locatorsObject = JSON.parse(JSON.stringify(cmd.locators ?? null));
|
|
377
|
+
|
|
378
|
+
if (!locatorsObject) return step;
|
|
379
|
+
|
|
380
|
+
const element_name = cmd?.locators?.element_name ?? `${cmd.label} ${cmd.role ?? "Text"}`;
|
|
381
|
+
locatorsObject.element_name = element_name;
|
|
382
|
+
|
|
383
|
+
const isValueVariable = isVariable(cmd.value);
|
|
384
|
+
const isTargetValueVariable = isVariable(cmd.targetValue);
|
|
385
|
+
const allStrategyLocators = JSON.parse(JSON.stringify(cmd?.allStrategyLocators ?? null));
|
|
386
|
+
step.locators = locatorsObject;
|
|
387
|
+
step.allStrategyLocators = allStrategyLocators;
|
|
388
|
+
step.isLocatorsAssigned = true;
|
|
389
|
+
|
|
390
|
+
if (!isValueVariable && !isTargetValueVariable) {
|
|
391
|
+
return step;
|
|
392
|
+
}
|
|
393
|
+
|
|
394
|
+
if (isValueVariable) {
|
|
395
|
+
step.dataSource = "parameters";
|
|
396
|
+
step.dataKey = convertToIdentifier(cmd.value.slice(1, -1));
|
|
397
|
+
}
|
|
398
|
+
|
|
399
|
+
if (!allStrategyLocators) {
|
|
400
|
+
let locs = locatorsObject.locators;
|
|
401
|
+
locs = parameterizeLocators({
|
|
402
|
+
cmd,
|
|
403
|
+
locs,
|
|
404
|
+
isValueVariable,
|
|
405
|
+
isTargetValueVariable,
|
|
406
|
+
parametersMap,
|
|
407
|
+
});
|
|
408
|
+
locatorsObject.locators = locs;
|
|
409
|
+
return {
|
|
410
|
+
...step,
|
|
411
|
+
locators: locatorsObject,
|
|
412
|
+
};
|
|
413
|
+
}
|
|
414
|
+
|
|
415
|
+
for (const key in allStrategyLocators) {
|
|
416
|
+
if (key === "strategy") continue;
|
|
417
|
+
if (key === "no_text" || key === "custom") continue;
|
|
418
|
+
const locators = allStrategyLocators[key];
|
|
419
|
+
if (locators.length === 0) continue;
|
|
420
|
+
parameterizeLocators({
|
|
421
|
+
cmd,
|
|
422
|
+
locs: locators,
|
|
423
|
+
isValueVariable,
|
|
424
|
+
isTargetValueVariable,
|
|
425
|
+
parametersMap,
|
|
426
|
+
});
|
|
427
|
+
}
|
|
428
|
+
|
|
429
|
+
locatorsObject.locators = allStrategyLocators[allStrategyLocators.strategy] ?? locatorsObject.locators;
|
|
430
|
+
|
|
431
|
+
return {
|
|
432
|
+
...step,
|
|
433
|
+
locators: locatorsObject,
|
|
434
|
+
allStrategyLocators,
|
|
435
|
+
isLocatorsAssigned: true,
|
|
436
|
+
};
|
|
437
|
+
};
|
|
438
|
+
|
|
17
439
|
export const toMethodName = (str) => {
|
|
18
440
|
// Remove any non-word characters (excluding underscore) and trim spaces
|
|
19
441
|
let cleanStr = str.trim().replace(/[^\w\s]/gi, "");
|
|
@@ -54,7 +476,7 @@ export function getCucumberStep({ step }) {
|
|
|
54
476
|
|
|
55
477
|
function makeStepTextUnique(step, stepsDefinitions) {
|
|
56
478
|
// const utilsFilePath = path.join("features", "step_definitions", "utils.mjs");
|
|
57
|
-
let stepText = step.text;
|
|
479
|
+
let stepText = step.renamedText ? step.renamedText : step.text;
|
|
58
480
|
let stepIndex = 1;
|
|
59
481
|
// console.log("makeStepTextUnique", step.text);
|
|
60
482
|
let stepDef = stepsDefinitions.findMatchingStep(stepText);
|
|
@@ -70,10 +492,13 @@ function makeStepTextUnique(step, stepsDefinitions) {
|
|
|
70
492
|
step.text = stepText;
|
|
71
493
|
}
|
|
72
494
|
|
|
73
|
-
export async function saveRecording({ step, cucumberStep, codePage, projectDir, stepsDefinitions }) {
|
|
495
|
+
export async function saveRecording({ step, cucumberStep, codePage, projectDir, stepsDefinitions, parametersMap }) {
|
|
496
|
+
if (step.commands && Array.isArray(step.commands)) {
|
|
497
|
+
step.commands = step.commands.map((cmd) => toRecordingStep(cmd, parametersMap));
|
|
498
|
+
}
|
|
74
499
|
let routesPath = path.join(tmpdir(), "blinq_temp_routes");
|
|
75
500
|
|
|
76
|
-
if (process.env.TEMP_RUN) {
|
|
501
|
+
if (process.env.TEMP_RUN === "true") {
|
|
77
502
|
if (existsSync(routesPath)) {
|
|
78
503
|
rmSync(routesPath, { recursive: true });
|
|
79
504
|
}
|
|
@@ -84,9 +509,9 @@ export async function saveRecording({ step, cucumberStep, codePage, projectDir,
|
|
|
84
509
|
// remove the folder
|
|
85
510
|
try {
|
|
86
511
|
rmSync(routesPath, { recursive: true });
|
|
87
|
-
|
|
512
|
+
//
|
|
88
513
|
} catch (error) {
|
|
89
|
-
|
|
514
|
+
//
|
|
90
515
|
}
|
|
91
516
|
routesPath = path.join(projectDir, "data", "routes");
|
|
92
517
|
if (!existsSync(routesPath)) {
|
|
@@ -107,32 +532,36 @@ export async function saveRecording({ step, cucumberStep, codePage, projectDir,
|
|
|
107
532
|
const isUtilStep = makeStepTextUnique(step, stepsDefinitions);
|
|
108
533
|
|
|
109
534
|
if (isUtilStep) {
|
|
110
|
-
|
|
535
|
+
if (!step.renamedText) {
|
|
536
|
+
return;
|
|
537
|
+
}
|
|
538
|
+
const { functionName } = stepsDefinitions.findMatchingStep(step.renamedText);
|
|
539
|
+
step.renamedText = functionName;
|
|
540
|
+
const newImportLine = `import { ${functionName} } from "./utils.mjs";\n`;
|
|
541
|
+
|
|
542
|
+
if (!codePage.fileContent.includes(newImportLine)) {
|
|
543
|
+
codePage.fileContent = newImportLine + codePage.fileContent;
|
|
544
|
+
}
|
|
111
545
|
}
|
|
112
546
|
}
|
|
113
547
|
|
|
548
|
+
routesPath = path.join(tmpdir(), "blinq_temp_routes");
|
|
114
549
|
if (process.env.TEMP_RUN === "true") {
|
|
115
|
-
console.log("Save routes in temp folder for running:", routesPath);
|
|
116
550
|
if (existsSync(routesPath)) {
|
|
117
|
-
console.log("Removing existing temp_routes_folder:", routesPath);
|
|
118
551
|
rmSync(routesPath, { recursive: true });
|
|
119
552
|
}
|
|
120
553
|
mkdirSync(routesPath, { recursive: true });
|
|
121
|
-
console.log("Created temp_routes_folder:", routesPath);
|
|
122
554
|
saveRoutes({ step, folderPath: routesPath });
|
|
123
555
|
} else {
|
|
124
|
-
console.log("Saving routes in project directory:", projectDir);
|
|
125
556
|
if (existsSync(routesPath)) {
|
|
126
557
|
// remove the folder
|
|
127
558
|
try {
|
|
128
559
|
rmSync(routesPath, { recursive: true });
|
|
129
|
-
console.log("Removed temp_routes_folder:", routesPath);
|
|
130
560
|
} catch (error) {
|
|
131
|
-
|
|
561
|
+
//
|
|
132
562
|
}
|
|
133
563
|
}
|
|
134
564
|
routesPath = path.join(projectDir, "data", "routes");
|
|
135
|
-
console.log("Saving routes to:", routesPath);
|
|
136
565
|
if (!existsSync(routesPath)) {
|
|
137
566
|
mkdirSync(routesPath, { recursive: true });
|
|
138
567
|
}
|
|
@@ -141,13 +570,14 @@ export async function saveRecording({ step, cucumberStep, codePage, projectDir,
|
|
|
141
570
|
|
|
142
571
|
cucumberStep.text = step.text;
|
|
143
572
|
const recording = new Recording();
|
|
573
|
+
|
|
144
574
|
const steps = step.commands;
|
|
145
575
|
|
|
146
576
|
recording.loadFromObject({ steps, step: cucumberStep });
|
|
147
577
|
|
|
148
578
|
const userData = {}; // TODO: get user data
|
|
149
579
|
|
|
150
|
-
let methodName = toMethodName(step.text);
|
|
580
|
+
let methodName = step.renamedText ? step.renamedText : toMethodName(step.text);
|
|
151
581
|
if (step.isApiStep) {
|
|
152
582
|
const {
|
|
153
583
|
url,
|
|
@@ -191,13 +621,11 @@ export async function saveRecording({ step, cucumberStep, codePage, projectDir,
|
|
|
191
621
|
stepsDefinitions
|
|
192
622
|
);
|
|
193
623
|
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
});
|
|
200
|
-
}
|
|
624
|
+
stepsDefinitions.addStep({
|
|
625
|
+
name: step.text,
|
|
626
|
+
file: result.codePage.sourceFileName,
|
|
627
|
+
source: "recorder",
|
|
628
|
+
});
|
|
201
629
|
|
|
202
630
|
cucumberStep.methodName = result.methodName;
|
|
203
631
|
return result.codePage;
|
|
@@ -209,7 +637,10 @@ export async function saveRecording({ step, cucumberStep, codePage, projectDir,
|
|
|
209
637
|
}
|
|
210
638
|
codePage = generateCodeResult.page;
|
|
211
639
|
methodName = generateCodeResult.methodName;
|
|
212
|
-
|
|
640
|
+
|
|
641
|
+
if (!step.renamedText) {
|
|
642
|
+
codePage.insertElements(generateCodeResult.elements);
|
|
643
|
+
}
|
|
213
644
|
|
|
214
645
|
const description = cucumberStep.text;
|
|
215
646
|
let path = null;
|
|
@@ -222,15 +653,17 @@ export async function saveRecording({ step, cucumberStep, codePage, projectDir,
|
|
|
222
653
|
protect = true;
|
|
223
654
|
}
|
|
224
655
|
}
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
656
|
+
if (!step.renamedText) {
|
|
657
|
+
const infraResult = codePage.addInfraCommand(
|
|
658
|
+
methodName,
|
|
659
|
+
description,
|
|
660
|
+
cucumberStep.getVariablesList(),
|
|
661
|
+
generateCodeResult.codeLines,
|
|
662
|
+
protect,
|
|
663
|
+
"recorder",
|
|
664
|
+
path
|
|
665
|
+
);
|
|
666
|
+
}
|
|
234
667
|
const keyword = (cucumberStep.keywordAlias ?? cucumberStep.keyword).trim();
|
|
235
668
|
const stepResult = codePage.addCucumberStep(
|
|
236
669
|
keyword,
|
|
@@ -240,15 +673,14 @@ export async function saveRecording({ step, cucumberStep, codePage, projectDir,
|
|
|
240
673
|
step.finalTimeout
|
|
241
674
|
);
|
|
242
675
|
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
});
|
|
249
|
-
}
|
|
676
|
+
stepsDefinitions.addStep({
|
|
677
|
+
name: step.text,
|
|
678
|
+
file: codePage.sourceFileName,
|
|
679
|
+
source: "recorder",
|
|
680
|
+
});
|
|
250
681
|
|
|
251
682
|
codePage.removeUnusedElements();
|
|
683
|
+
codePage.mergeSimilarElements();
|
|
252
684
|
cucumberStep.methodName = methodName;
|
|
253
685
|
if (generateCodeResult.locatorsMetadata) {
|
|
254
686
|
codePage.addLocatorsMetadata(generateCodeResult.locatorsMetadata);
|
|
@@ -300,26 +732,35 @@ export const getCommandsForImplementedStep = (stepName, stepsDefinitions, stepPa
|
|
|
300
732
|
if (error) {
|
|
301
733
|
throw new Error(error);
|
|
302
734
|
}
|
|
735
|
+
isUtilStep = codePage.sourceFileName.endsWith("utils.mjs");
|
|
303
736
|
|
|
304
737
|
if (parametersNames.length !== stepParams.length) {
|
|
305
738
|
// console.log("Parameters mismatch", parametersNames, stepParams);
|
|
306
739
|
throw new Error("Parameters mismatch");
|
|
307
740
|
}
|
|
308
|
-
for (let i = 0; i < parametersNames.length; i++) {
|
|
309
|
-
stepParams[i].argumentName = parametersNames[i];
|
|
310
|
-
}
|
|
311
741
|
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
742
|
+
const pattern = step.name;
|
|
743
|
+
if (isUtilStep && pattern === "Verify the file {string} exists") {
|
|
744
|
+
commands.push({
|
|
745
|
+
type: "verify_file_exists",
|
|
746
|
+
parameters: [stepParams[0].text],
|
|
747
|
+
});
|
|
748
|
+
} else {
|
|
749
|
+
for (let i = 0; i < parametersNames.length; i++) {
|
|
750
|
+
stepParams[i].argumentName = parametersNames[i];
|
|
751
|
+
}
|
|
752
|
+
|
|
753
|
+
for (const { code } of codeCommands) {
|
|
754
|
+
const command = invertCodeToCommand(code, elements, stepParams, stepsDefinitions, codePage, stepName)[0];
|
|
755
|
+
if (command === undefined || command.type === null) continue;
|
|
756
|
+
if (command.element) {
|
|
757
|
+
const key = command.element.key;
|
|
758
|
+
if (key && locatorsJson[key]) {
|
|
759
|
+
command.allStrategyLocators = locatorsJson[key];
|
|
760
|
+
}
|
|
320
761
|
}
|
|
762
|
+
commands.push(command);
|
|
321
763
|
}
|
|
322
|
-
commands.push(command);
|
|
323
764
|
}
|
|
324
765
|
} catch (error) {
|
|
325
766
|
console.error(error);
|
|
@@ -404,6 +845,7 @@ export async function updateStepDefinitions({ scenario, featureName, projectDir
|
|
|
404
845
|
console.log("Save routes in temp folder for running:", routesPath);
|
|
405
846
|
if (existsSync(routesPath)) {
|
|
406
847
|
console.log("Removing existing temp_routes_folder:", routesPath);
|
|
848
|
+
routesPath = path.join(tmpdir(), `blinq_temp_routes`);
|
|
407
849
|
rmSync(routesPath, { recursive: true });
|
|
408
850
|
}
|
|
409
851
|
mkdirSync(routesPath, { recursive: true });
|
|
@@ -427,6 +869,9 @@ export async function updateStepDefinitions({ scenario, featureName, projectDir
|
|
|
427
869
|
}
|
|
428
870
|
saveRoutes({ step, folderPath: routesPath });
|
|
429
871
|
}
|
|
872
|
+
if (step.commands && Array.isArray(step.commands)) {
|
|
873
|
+
step.commands = step.commands.map((cmd) => toRecordingStep(cmd, scenario.parametersMap));
|
|
874
|
+
}
|
|
430
875
|
continue;
|
|
431
876
|
}
|
|
432
877
|
const cucumberStep = getCucumberStep({ step });
|
|
@@ -434,7 +879,14 @@ export async function updateStepDefinitions({ scenario, featureName, projectDir
|
|
|
434
879
|
const stepDefsFilePath = locateDefinitionPath(featureFolder, pageName);
|
|
435
880
|
// path.join(stepDefinitionFolderPath, pageName + "_page.mjs");
|
|
436
881
|
let codePage = getCodePage(stepDefsFilePath);
|
|
437
|
-
codePage = await saveRecording({
|
|
882
|
+
codePage = await saveRecording({
|
|
883
|
+
step,
|
|
884
|
+
cucumberStep,
|
|
885
|
+
codePage,
|
|
886
|
+
projectDir,
|
|
887
|
+
stepsDefinitions,
|
|
888
|
+
parametersMap: scenario.parametersMap,
|
|
889
|
+
});
|
|
438
890
|
if (!codePage) {
|
|
439
891
|
continue;
|
|
440
892
|
}
|
|
@@ -129,10 +129,14 @@ export function getExamplesContent(parametersMap) {
|
|
|
129
129
|
function getTagsContent(scenario, featureFileObject) {
|
|
130
130
|
let oldTags = featureFileObject?.scenarios?.find((s) => s.name === scenario.name)?.tags ?? [];
|
|
131
131
|
for (const tag of scenario.tags) {
|
|
132
|
-
if (
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
132
|
+
if (tag === "global_test_data") {
|
|
133
|
+
if (!oldTags.includes("global_test_data")) {
|
|
134
|
+
oldTags.push("global_test_data");
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
if (tag === "remove_global_test_data") {
|
|
139
|
+
oldTags = oldTags.filter((t) => t !== "global_test_data");
|
|
136
140
|
}
|
|
137
141
|
}
|
|
138
142
|
|
|
@@ -231,7 +235,7 @@ const GherkinToObject = (gherkin) => {
|
|
|
231
235
|
skipEmptyLines();
|
|
232
236
|
|
|
233
237
|
if (idx >= lines.length) {
|
|
234
|
-
return
|
|
238
|
+
return scenario;
|
|
235
239
|
}
|
|
236
240
|
|
|
237
241
|
while (
|