@dev-blinq/cucumber_client 1.0.1362-dev → 1.0.1362-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 +25 -11
- 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 +213 -90
- 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 +4 -16
- package/bin/client/recorderv3/step_runner.js +315 -205
- package/bin/client/recorderv3/step_utils.js +475 -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 +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 -10
|
@@ -14,6 +14,427 @@ 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
|
+
if (typeof cmd.text === "string") {
|
|
340
|
+
const replacementFromValue = cmd.text.trim().replace(/\s+/g, " ") ?? ""; // val.trim();
|
|
341
|
+
if (replacementFromValue.length > 0) {
|
|
342
|
+
const replacementToValue = `{${variable}}`;
|
|
343
|
+
locs = _parameterizeLocators(locs, replacementFromValue, replacementToValue);
|
|
344
|
+
}
|
|
345
|
+
}
|
|
346
|
+
}
|
|
347
|
+
if (isTargetValueVariable) {
|
|
348
|
+
const variable = cmd.targetValue.slice(1, -1);
|
|
349
|
+
// const val = parametersMap[variable];
|
|
350
|
+
if (typeof cmd.targetText === "string") {
|
|
351
|
+
const replacementFromValue = cmd.targetText.trim().replace(/\s+/g, " ") ?? ""; // val.trim();
|
|
352
|
+
if (replacementFromValue.length > 0) {
|
|
353
|
+
const replacementToValue = `{${variable}}`;
|
|
354
|
+
locs = _parameterizeLocators(locs, replacementFromValue, replacementToValue);
|
|
355
|
+
}
|
|
356
|
+
}
|
|
357
|
+
}
|
|
358
|
+
return locs;
|
|
359
|
+
};
|
|
360
|
+
|
|
361
|
+
//TODO: IMPORTAN
|
|
362
|
+
export const toRecordingStep = (cmd, parametersMap) => {
|
|
363
|
+
if (cmd.type === "api") {
|
|
364
|
+
return {
|
|
365
|
+
type: "api",
|
|
366
|
+
value: cmd.value,
|
|
367
|
+
};
|
|
368
|
+
}
|
|
369
|
+
const step = _toRecordingStep(cmd);
|
|
370
|
+
const cmdID = {
|
|
371
|
+
cmdId: cmd.id,
|
|
372
|
+
};
|
|
373
|
+
Object.assign(step, cmdID);
|
|
374
|
+
|
|
375
|
+
const locatorsObject = JSON.parse(JSON.stringify(cmd.locators ?? null));
|
|
376
|
+
|
|
377
|
+
if (!locatorsObject) return step;
|
|
378
|
+
|
|
379
|
+
const element_name = cmd?.locators?.element_name ?? `${cmd.label} ${cmd.role ?? "Text"}`;
|
|
380
|
+
locatorsObject.element_name = element_name;
|
|
381
|
+
|
|
382
|
+
const isValueVariable = isVariable(cmd.value);
|
|
383
|
+
const isTargetValueVariable = isVariable(cmd.targetValue);
|
|
384
|
+
const allStrategyLocators = JSON.parse(JSON.stringify(cmd?.allStrategyLocators ?? null));
|
|
385
|
+
step.locators = locatorsObject;
|
|
386
|
+
step.allStrategyLocators = allStrategyLocators;
|
|
387
|
+
step.isLocatorsAssigned = true;
|
|
388
|
+
|
|
389
|
+
if (!isValueVariable && !isTargetValueVariable) {
|
|
390
|
+
return step;
|
|
391
|
+
}
|
|
392
|
+
|
|
393
|
+
if (isValueVariable) {
|
|
394
|
+
step.dataSource = "parameters";
|
|
395
|
+
step.dataKey = convertToIdentifier(cmd.value.slice(1, -1));
|
|
396
|
+
}
|
|
397
|
+
|
|
398
|
+
if (!allStrategyLocators) {
|
|
399
|
+
let locs = locatorsObject.locators;
|
|
400
|
+
locs = parameterizeLocators({
|
|
401
|
+
cmd,
|
|
402
|
+
locs,
|
|
403
|
+
isValueVariable,
|
|
404
|
+
isTargetValueVariable,
|
|
405
|
+
parametersMap,
|
|
406
|
+
});
|
|
407
|
+
locatorsObject.locators = locs;
|
|
408
|
+
return {
|
|
409
|
+
...step,
|
|
410
|
+
locators: locatorsObject,
|
|
411
|
+
};
|
|
412
|
+
}
|
|
413
|
+
|
|
414
|
+
for (const key in allStrategyLocators) {
|
|
415
|
+
if (key === "strategy") continue;
|
|
416
|
+
if (key === "no_text" || key === "custom") continue;
|
|
417
|
+
const locators = allStrategyLocators[key];
|
|
418
|
+
if (locators.length === 0) continue;
|
|
419
|
+
parameterizeLocators({
|
|
420
|
+
cmd,
|
|
421
|
+
locs: locators,
|
|
422
|
+
isValueVariable,
|
|
423
|
+
isTargetValueVariable,
|
|
424
|
+
parametersMap,
|
|
425
|
+
});
|
|
426
|
+
}
|
|
427
|
+
|
|
428
|
+
locatorsObject.locators = allStrategyLocators[allStrategyLocators.strategy] ?? locatorsObject.locators;
|
|
429
|
+
|
|
430
|
+
return {
|
|
431
|
+
...step,
|
|
432
|
+
locators: locatorsObject,
|
|
433
|
+
allStrategyLocators,
|
|
434
|
+
isLocatorsAssigned: true,
|
|
435
|
+
};
|
|
436
|
+
};
|
|
437
|
+
|
|
17
438
|
export const toMethodName = (str) => {
|
|
18
439
|
// Remove any non-word characters (excluding underscore) and trim spaces
|
|
19
440
|
let cleanStr = str.trim().replace(/[^\w\s]/gi, "");
|
|
@@ -70,10 +491,13 @@ function makeStepTextUnique(step, stepsDefinitions) {
|
|
|
70
491
|
step.text = stepText;
|
|
71
492
|
}
|
|
72
493
|
|
|
73
|
-
export async function saveRecording({ step, cucumberStep, codePage, projectDir, stepsDefinitions }) {
|
|
494
|
+
export async function saveRecording({ step, cucumberStep, codePage, projectDir, stepsDefinitions, parametersMap }) {
|
|
495
|
+
if (step.commands && Array.isArray(step.commands)) {
|
|
496
|
+
step.commands = step.commands.map((cmd) => toRecordingStep(cmd, parametersMap));
|
|
497
|
+
}
|
|
74
498
|
let routesPath = path.join(tmpdir(), "blinq_temp_routes");
|
|
75
499
|
|
|
76
|
-
if (process.env.TEMP_RUN) {
|
|
500
|
+
if (process.env.TEMP_RUN === "true") {
|
|
77
501
|
if (existsSync(routesPath)) {
|
|
78
502
|
rmSync(routesPath, { recursive: true });
|
|
79
503
|
}
|
|
@@ -111,6 +535,7 @@ export async function saveRecording({ step, cucumberStep, codePage, projectDir,
|
|
|
111
535
|
}
|
|
112
536
|
}
|
|
113
537
|
|
|
538
|
+
routesPath = path.join(tmpdir(), "blinq_temp_routes");
|
|
114
539
|
if (process.env.TEMP_RUN === "true") {
|
|
115
540
|
console.log("Save routes in temp folder for running:", routesPath);
|
|
116
541
|
if (existsSync(routesPath)) {
|
|
@@ -141,6 +566,7 @@ export async function saveRecording({ step, cucumberStep, codePage, projectDir,
|
|
|
141
566
|
|
|
142
567
|
cucumberStep.text = step.text;
|
|
143
568
|
const recording = new Recording();
|
|
569
|
+
|
|
144
570
|
const steps = step.commands;
|
|
145
571
|
|
|
146
572
|
recording.loadFromObject({ steps, step: cucumberStep });
|
|
@@ -216,12 +642,18 @@ export async function saveRecording({ step, cucumberStep, codePage, projectDir,
|
|
|
216
642
|
if (step.commands && step.commands.length > 0 && step.commands[0]) {
|
|
217
643
|
path = step.commands[0].lastKnownUrlPath;
|
|
218
644
|
}
|
|
645
|
+
let protect = false;
|
|
646
|
+
if (step.commands && step.commands.length > 0 && step.commands[0].type) {
|
|
647
|
+
if (step.commands[0].type === "verify_element_property" || step.commands[0].type === "conditional_wait") {
|
|
648
|
+
protect = true;
|
|
649
|
+
}
|
|
650
|
+
}
|
|
219
651
|
const infraResult = codePage.addInfraCommand(
|
|
220
652
|
methodName,
|
|
221
653
|
description,
|
|
222
654
|
cucumberStep.getVariablesList(),
|
|
223
655
|
generateCodeResult.codeLines,
|
|
224
|
-
|
|
656
|
+
protect,
|
|
225
657
|
"recorder",
|
|
226
658
|
path
|
|
227
659
|
);
|
|
@@ -243,6 +675,7 @@ export async function saveRecording({ step, cucumberStep, codePage, projectDir,
|
|
|
243
675
|
}
|
|
244
676
|
|
|
245
677
|
codePage.removeUnusedElements();
|
|
678
|
+
codePage.mergeSimilarElements();
|
|
246
679
|
cucumberStep.methodName = methodName;
|
|
247
680
|
if (generateCodeResult.locatorsMetadata) {
|
|
248
681
|
codePage.addLocatorsMetadata(generateCodeResult.locatorsMetadata);
|
|
@@ -294,26 +727,35 @@ export const getCommandsForImplementedStep = (stepName, stepsDefinitions, stepPa
|
|
|
294
727
|
if (error) {
|
|
295
728
|
throw new Error(error);
|
|
296
729
|
}
|
|
730
|
+
isUtilStep = codePage.sourceFileName.endsWith("utils.mjs");
|
|
297
731
|
|
|
298
732
|
if (parametersNames.length !== stepParams.length) {
|
|
299
733
|
// console.log("Parameters mismatch", parametersNames, stepParams);
|
|
300
734
|
throw new Error("Parameters mismatch");
|
|
301
735
|
}
|
|
302
|
-
for (let i = 0; i < parametersNames.length; i++) {
|
|
303
|
-
stepParams[i].argumentName = parametersNames[i];
|
|
304
|
-
}
|
|
305
736
|
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
737
|
+
const pattern = step.name;
|
|
738
|
+
if (isUtilStep && pattern === "Verify the file {string} exists") {
|
|
739
|
+
commands.push({
|
|
740
|
+
type: "verify_file_exists",
|
|
741
|
+
parameters: [stepParams[0].text],
|
|
742
|
+
});
|
|
743
|
+
} else {
|
|
744
|
+
for (let i = 0; i < parametersNames.length; i++) {
|
|
745
|
+
stepParams[i].argumentName = parametersNames[i];
|
|
746
|
+
}
|
|
747
|
+
|
|
748
|
+
for (const { code } of codeCommands) {
|
|
749
|
+
const command = invertCodeToCommand(code, elements, stepParams, stepsDefinitions, codePage, stepName)[0];
|
|
750
|
+
if (command === undefined || command.type === null) continue;
|
|
751
|
+
if (command.element) {
|
|
752
|
+
const key = command.element.key;
|
|
753
|
+
if (key && locatorsJson[key]) {
|
|
754
|
+
command.allStrategyLocators = locatorsJson[key];
|
|
755
|
+
}
|
|
314
756
|
}
|
|
757
|
+
commands.push(command);
|
|
315
758
|
}
|
|
316
|
-
commands.push(command);
|
|
317
759
|
}
|
|
318
760
|
} catch (error) {
|
|
319
761
|
console.error(error);
|
|
@@ -372,6 +814,12 @@ export async function updateStepDefinitions({ scenario, featureName, projectDir
|
|
|
372
814
|
const utilsTemplateFilePath = path.join(__dirname, "../../assets", "templates", "utils_template.txt");
|
|
373
815
|
const utilsContent = readFileSync(utilsTemplateFilePath, "utf8");
|
|
374
816
|
writeFileSync(utilsFilePath, utilsContent, "utf8");
|
|
817
|
+
const hooksTemplateFilePath = path.join(__dirname, "../../assets", "templates", "_hooks_template.txt");
|
|
818
|
+
if (existsSync(hooksTemplateFilePath)) {
|
|
819
|
+
const hooksFilePath = path.join(stepDefinitionFolderPath, "_hooks.mjs");
|
|
820
|
+
const hooksContent = readFileSync(hooksTemplateFilePath, "utf8");
|
|
821
|
+
writeFileSync(hooksFilePath, hooksContent, "utf8");
|
|
822
|
+
}
|
|
375
823
|
const steps = scenario.steps;
|
|
376
824
|
|
|
377
825
|
const stepsDefinitions = new StepsDefinitions(projectDir);
|
|
@@ -392,6 +840,7 @@ export async function updateStepDefinitions({ scenario, featureName, projectDir
|
|
|
392
840
|
console.log("Save routes in temp folder for running:", routesPath);
|
|
393
841
|
if (existsSync(routesPath)) {
|
|
394
842
|
console.log("Removing existing temp_routes_folder:", routesPath);
|
|
843
|
+
routesPath = path.join(tmpdir(), `blinq_temp_routes`);
|
|
395
844
|
rmSync(routesPath, { recursive: true });
|
|
396
845
|
}
|
|
397
846
|
mkdirSync(routesPath, { recursive: true });
|
|
@@ -415,6 +864,9 @@ export async function updateStepDefinitions({ scenario, featureName, projectDir
|
|
|
415
864
|
}
|
|
416
865
|
saveRoutes({ step, folderPath: routesPath });
|
|
417
866
|
}
|
|
867
|
+
if (step.commands && Array.isArray(step.commands)) {
|
|
868
|
+
step.commands = step.commands.map((cmd) => toRecordingStep(cmd, scenario.parametersMap));
|
|
869
|
+
}
|
|
418
870
|
continue;
|
|
419
871
|
}
|
|
420
872
|
const cucumberStep = getCucumberStep({ step });
|
|
@@ -422,7 +874,14 @@ export async function updateStepDefinitions({ scenario, featureName, projectDir
|
|
|
422
874
|
const stepDefsFilePath = locateDefinitionPath(featureFolder, pageName);
|
|
423
875
|
// path.join(stepDefinitionFolderPath, pageName + "_page.mjs");
|
|
424
876
|
let codePage = getCodePage(stepDefsFilePath);
|
|
425
|
-
codePage = await saveRecording({
|
|
877
|
+
codePage = await saveRecording({
|
|
878
|
+
step,
|
|
879
|
+
cucumberStep,
|
|
880
|
+
codePage,
|
|
881
|
+
projectDir,
|
|
882
|
+
stepsDefinitions,
|
|
883
|
+
parametersMap: scenario.parametersMap,
|
|
884
|
+
});
|
|
426
885
|
if (!codePage) {
|
|
427
886
|
continue;
|
|
428
887
|
}
|
|
@@ -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
|
|