@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.
Files changed (48) hide show
  1. package/bin/assets/bundled_scripts/recorder.js +107 -107
  2. package/bin/assets/preload/css_gen.js +10 -10
  3. package/bin/assets/preload/toolbar.js +27 -29
  4. package/bin/assets/preload/unique_locators.js +1 -1
  5. package/bin/assets/preload/yaml.js +288 -275
  6. package/bin/assets/scripts/aria_snapshot.js +223 -220
  7. package/bin/assets/scripts/dom_attr.js +329 -329
  8. package/bin/assets/scripts/dom_parent.js +169 -174
  9. package/bin/assets/scripts/event_utils.js +94 -94
  10. package/bin/assets/scripts/pw.js +2050 -1949
  11. package/bin/assets/scripts/recorder.js +13 -23
  12. package/bin/assets/scripts/snapshot_capturer.js +147 -147
  13. package/bin/assets/scripts/unique_locators.js +163 -44
  14. package/bin/assets/scripts/yaml.js +796 -783
  15. package/bin/assets/templates/_hooks_template.txt +41 -0
  16. package/bin/assets/templates/utils_template.txt +2 -45
  17. package/bin/client/apiTest/apiTest.js +6 -0
  18. package/bin/client/code_cleanup/utils.js +5 -1
  19. package/bin/client/code_gen/api_codegen.js +2 -2
  20. package/bin/client/code_gen/code_inversion.js +107 -2
  21. package/bin/client/code_gen/function_signature.js +4 -0
  22. package/bin/client/code_gen/page_reflection.js +846 -906
  23. package/bin/client/code_gen/playwright_codeget.js +25 -11
  24. package/bin/client/cucumber/feature.js +4 -0
  25. package/bin/client/cucumber/feature_data.js +2 -2
  26. package/bin/client/cucumber/project_to_document.js +9 -3
  27. package/bin/client/cucumber/steps_definitions.js +6 -3
  28. package/bin/client/cucumber_selector.js +17 -1
  29. package/bin/client/local_agent.js +4 -3
  30. package/bin/client/parse_feature_file.js +23 -26
  31. package/bin/client/playground/projects/env.json +2 -2
  32. package/bin/client/project.js +186 -196
  33. package/bin/client/recorderv3/bvt_recorder.js +213 -90
  34. package/bin/client/recorderv3/implemented_steps.js +8 -0
  35. package/bin/client/recorderv3/index.js +59 -54
  36. package/bin/client/recorderv3/scriptTest.js +1 -1
  37. package/bin/client/recorderv3/services.js +4 -16
  38. package/bin/client/recorderv3/step_runner.js +315 -205
  39. package/bin/client/recorderv3/step_utils.js +475 -16
  40. package/bin/client/recorderv3/update_feature.js +9 -5
  41. package/bin/client/recording.js +1 -0
  42. package/bin/client/upload-service.js +3 -2
  43. package/bin/client/utils/socket_logger.js +132 -0
  44. package/bin/index.js +1 -0
  45. package/bin/logger.js +3 -2
  46. package/bin/min/consoleApi.min.cjs +2 -3
  47. package/bin/min/injectedScript.min.cjs +16 -16
  48. 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
- false,
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
- isUtilStep = codePage.sourceFileName.endsWith("utils.mjs");
307
- for (const { code } of codeCommands) {
308
- const command = invertCodeToCommand(code, elements, stepParams, stepsDefinitions, codePage, stepName)[0];
309
- if (command === undefined || command.type === null) continue;
310
- if (command.element) {
311
- const key = command.element.key;
312
- if (key && locatorsJson[key]) {
313
- command.allStrategyLocators = locatorsJson[key];
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({ step, cucumberStep, codePage, projectDir, stepsDefinitions });
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 (oldTags.includes(tag)) {
133
- oldTags = oldTags.filter((t) => t !== tag);
134
- } else {
135
- oldTags.push(tag);
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 -1;
238
+ return scenario;
235
239
  }
236
240
 
237
241
  while (
@@ -53,6 +53,7 @@ const Types = {
53
53
  SET_INPUT_FILES: "set_input_files",
54
54
  VERIFY_PAGE_SNAPSHOT: "verify_page_snapshot",
55
55
  CONDITIONAL_WAIT: "conditional_wait",
56
+ SLEEP: "sleep",
56
57
  };
57
58
  class Recording {
58
59
  steps = [];
@@ -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