@dev-blinq/cucumber_client 1.0.1366-dev → 1.0.1366-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 +107 -107
- 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 +13 -23
- 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 +41 -0
- package/bin/assets/templates/utils_template.txt +2 -45
- package/bin/client/apiTest/apiTest.js +6 -0
- 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 +107 -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 +45 -12
- 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 +9 -3
- package/bin/client/cucumber/steps_definitions.js +6 -3
- package/bin/client/cucumber_selector.js +17 -1
- package/bin/client/local_agent.js +4 -3
- 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 +238 -95
- package/bin/client/recorderv3/implemented_steps.js +8 -0
- package/bin/client/recorderv3/index.js +59 -54
- package/bin/client/recorderv3/scriptTest.js +1 -1
- package/bin/client/recorderv3/services.js +68 -16
- package/bin/client/recorderv3/step_runner.js +315 -205
- package/bin/client/recorderv3/step_utils.js +476 -16
- package/bin/client/recorderv3/update_feature.js +9 -5
- 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 -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 -10
|
@@ -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, "");
|
|
@@ -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
|
}
|
|
@@ -111,6 +536,7 @@ export async function saveRecording({ step, cucumberStep, codePage, projectDir,
|
|
|
111
536
|
}
|
|
112
537
|
}
|
|
113
538
|
|
|
539
|
+
routesPath = path.join(tmpdir(), "blinq_temp_routes");
|
|
114
540
|
if (process.env.TEMP_RUN === "true") {
|
|
115
541
|
console.log("Save routes in temp folder for running:", routesPath);
|
|
116
542
|
if (existsSync(routesPath)) {
|
|
@@ -141,6 +567,7 @@ export async function saveRecording({ step, cucumberStep, codePage, projectDir,
|
|
|
141
567
|
|
|
142
568
|
cucumberStep.text = step.text;
|
|
143
569
|
const recording = new Recording();
|
|
570
|
+
|
|
144
571
|
const steps = step.commands;
|
|
145
572
|
|
|
146
573
|
recording.loadFromObject({ steps, step: cucumberStep });
|
|
@@ -216,12 +643,18 @@ export async function saveRecording({ step, cucumberStep, codePage, projectDir,
|
|
|
216
643
|
if (step.commands && step.commands.length > 0 && step.commands[0]) {
|
|
217
644
|
path = step.commands[0].lastKnownUrlPath;
|
|
218
645
|
}
|
|
646
|
+
let protect = false;
|
|
647
|
+
if (step.commands && step.commands.length > 0 && step.commands[0].type) {
|
|
648
|
+
if (step.commands[0].type === "verify_element_property" || step.commands[0].type === "conditional_wait") {
|
|
649
|
+
protect = true;
|
|
650
|
+
}
|
|
651
|
+
}
|
|
219
652
|
const infraResult = codePage.addInfraCommand(
|
|
220
653
|
methodName,
|
|
221
654
|
description,
|
|
222
655
|
cucumberStep.getVariablesList(),
|
|
223
656
|
generateCodeResult.codeLines,
|
|
224
|
-
|
|
657
|
+
protect,
|
|
225
658
|
"recorder",
|
|
226
659
|
path
|
|
227
660
|
);
|
|
@@ -243,6 +676,7 @@ export async function saveRecording({ step, cucumberStep, codePage, projectDir,
|
|
|
243
676
|
}
|
|
244
677
|
|
|
245
678
|
codePage.removeUnusedElements();
|
|
679
|
+
codePage.mergeSimilarElements();
|
|
246
680
|
cucumberStep.methodName = methodName;
|
|
247
681
|
if (generateCodeResult.locatorsMetadata) {
|
|
248
682
|
codePage.addLocatorsMetadata(generateCodeResult.locatorsMetadata);
|
|
@@ -294,26 +728,35 @@ export const getCommandsForImplementedStep = (stepName, stepsDefinitions, stepPa
|
|
|
294
728
|
if (error) {
|
|
295
729
|
throw new Error(error);
|
|
296
730
|
}
|
|
731
|
+
isUtilStep = codePage.sourceFileName.endsWith("utils.mjs");
|
|
297
732
|
|
|
298
733
|
if (parametersNames.length !== stepParams.length) {
|
|
299
734
|
// console.log("Parameters mismatch", parametersNames, stepParams);
|
|
300
735
|
throw new Error("Parameters mismatch");
|
|
301
736
|
}
|
|
302
|
-
for (let i = 0; i < parametersNames.length; i++) {
|
|
303
|
-
stepParams[i].argumentName = parametersNames[i];
|
|
304
|
-
}
|
|
305
737
|
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
738
|
+
const pattern = step.name;
|
|
739
|
+
if (isUtilStep && pattern === "Verify the file {string} exists") {
|
|
740
|
+
commands.push({
|
|
741
|
+
type: "verify_file_exists",
|
|
742
|
+
parameters: [stepParams[0].text],
|
|
743
|
+
});
|
|
744
|
+
} else {
|
|
745
|
+
for (let i = 0; i < parametersNames.length; i++) {
|
|
746
|
+
stepParams[i].argumentName = parametersNames[i];
|
|
747
|
+
}
|
|
748
|
+
|
|
749
|
+
for (const { code } of codeCommands) {
|
|
750
|
+
const command = invertCodeToCommand(code, elements, stepParams, stepsDefinitions, codePage, stepName)[0];
|
|
751
|
+
if (command === undefined || command.type === null) continue;
|
|
752
|
+
if (command.element) {
|
|
753
|
+
const key = command.element.key;
|
|
754
|
+
if (key && locatorsJson[key]) {
|
|
755
|
+
command.allStrategyLocators = locatorsJson[key];
|
|
756
|
+
}
|
|
314
757
|
}
|
|
758
|
+
commands.push(command);
|
|
315
759
|
}
|
|
316
|
-
commands.push(command);
|
|
317
760
|
}
|
|
318
761
|
} catch (error) {
|
|
319
762
|
console.error(error);
|
|
@@ -372,6 +815,12 @@ export async function updateStepDefinitions({ scenario, featureName, projectDir
|
|
|
372
815
|
const utilsTemplateFilePath = path.join(__dirname, "../../assets", "templates", "utils_template.txt");
|
|
373
816
|
const utilsContent = readFileSync(utilsTemplateFilePath, "utf8");
|
|
374
817
|
writeFileSync(utilsFilePath, utilsContent, "utf8");
|
|
818
|
+
const hooksTemplateFilePath = path.join(__dirname, "../../assets", "templates", "_hooks_template.txt");
|
|
819
|
+
if (existsSync(hooksTemplateFilePath)) {
|
|
820
|
+
const hooksFilePath = path.join(stepDefinitionFolderPath, "_hooks.mjs");
|
|
821
|
+
const hooksContent = readFileSync(hooksTemplateFilePath, "utf8");
|
|
822
|
+
writeFileSync(hooksFilePath, hooksContent, "utf8");
|
|
823
|
+
}
|
|
375
824
|
const steps = scenario.steps;
|
|
376
825
|
|
|
377
826
|
const stepsDefinitions = new StepsDefinitions(projectDir);
|
|
@@ -392,6 +841,7 @@ export async function updateStepDefinitions({ scenario, featureName, projectDir
|
|
|
392
841
|
console.log("Save routes in temp folder for running:", routesPath);
|
|
393
842
|
if (existsSync(routesPath)) {
|
|
394
843
|
console.log("Removing existing temp_routes_folder:", routesPath);
|
|
844
|
+
routesPath = path.join(tmpdir(), `blinq_temp_routes`);
|
|
395
845
|
rmSync(routesPath, { recursive: true });
|
|
396
846
|
}
|
|
397
847
|
mkdirSync(routesPath, { recursive: true });
|
|
@@ -415,6 +865,9 @@ export async function updateStepDefinitions({ scenario, featureName, projectDir
|
|
|
415
865
|
}
|
|
416
866
|
saveRoutes({ step, folderPath: routesPath });
|
|
417
867
|
}
|
|
868
|
+
if (step.commands && Array.isArray(step.commands)) {
|
|
869
|
+
step.commands = step.commands.map((cmd) => toRecordingStep(cmd, scenario.parametersMap));
|
|
870
|
+
}
|
|
418
871
|
continue;
|
|
419
872
|
}
|
|
420
873
|
const cucumberStep = getCucumberStep({ step });
|
|
@@ -422,7 +875,14 @@ export async function updateStepDefinitions({ scenario, featureName, projectDir
|
|
|
422
875
|
const stepDefsFilePath = locateDefinitionPath(featureFolder, pageName);
|
|
423
876
|
// path.join(stepDefinitionFolderPath, pageName + "_page.mjs");
|
|
424
877
|
let codePage = getCodePage(stepDefsFilePath);
|
|
425
|
-
codePage = await saveRecording({
|
|
878
|
+
codePage = await saveRecording({
|
|
879
|
+
step,
|
|
880
|
+
cucumberStep,
|
|
881
|
+
codePage,
|
|
882
|
+
projectDir,
|
|
883
|
+
stepsDefinitions,
|
|
884
|
+
parametersMap: scenario.parametersMap,
|
|
885
|
+
});
|
|
426
886
|
if (!codePage) {
|
|
427
887
|
continue;
|
|
428
888
|
}
|
|
@@ -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 (
|
package/bin/client/recording.js
CHANGED
|
@@ -12,6 +12,7 @@ class ScenarioUploadService {
|
|
|
12
12
|
this.runsApiBaseURL + "/scenarios/create",
|
|
13
13
|
{
|
|
14
14
|
name,
|
|
15
|
+
branch: process.env.GIT_BRANCH ? process.env.GIT_BRANCH : "main",
|
|
15
16
|
},
|
|
16
17
|
{
|
|
17
18
|
headers: {
|
|
@@ -37,7 +38,7 @@ class ScenarioUploadService {
|
|
|
37
38
|
},
|
|
38
39
|
});
|
|
39
40
|
|
|
40
|
-
if(response.status === 401) {
|
|
41
|
+
if (response.status === 401) {
|
|
41
42
|
throw new Error("Your trial plan has ended. Cannot upload reports and perform retraining");
|
|
42
43
|
}
|
|
43
44
|
|
|
@@ -63,7 +64,7 @@ class ScenarioUploadService {
|
|
|
63
64
|
}
|
|
64
65
|
);
|
|
65
66
|
|
|
66
|
-
if(response.status === 403) {
|
|
67
|
+
if (response.status === 403) {
|
|
67
68
|
throw new Error("Your trial plan has ended. Cannot upload reports and perform retraining");
|
|
68
69
|
}
|
|
69
70
|
|