@dev-blinq/cucumber_client 1.0.1472-dev → 1.0.1472-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 (45) hide show
  1. package/bin/assets/bundled_scripts/recorder.js +73 -73
  2. package/bin/assets/scripts/recorder.js +87 -49
  3. package/bin/assets/scripts/snapshot_capturer.js +10 -17
  4. package/bin/assets/scripts/unique_locators.js +168 -40
  5. package/bin/assets/templates/_hooks_template.txt +6 -2
  6. package/bin/assets/templates/utils_template.txt +16 -16
  7. package/bin/client/code_cleanup/utils.js +16 -7
  8. package/bin/client/code_gen/code_inversion.js +125 -1
  9. package/bin/client/code_gen/duplication_analysis.js +2 -1
  10. package/bin/client/code_gen/function_signature.js +8 -0
  11. package/bin/client/code_gen/index.js +4 -0
  12. package/bin/client/code_gen/page_reflection.js +90 -9
  13. package/bin/client/code_gen/playwright_codeget.js +173 -77
  14. package/bin/client/codemod/find_harcoded_locators.js +173 -0
  15. package/bin/client/codemod/fix_hardcoded_locators.js +247 -0
  16. package/bin/client/codemod/index.js +8 -0
  17. package/bin/client/codemod/locators_array/find_misstructured_elements.js +148 -0
  18. package/bin/client/codemod/locators_array/fix_misstructured_elements.js +144 -0
  19. package/bin/client/codemod/locators_array/index.js +114 -0
  20. package/bin/client/codemod/types.js +1 -0
  21. package/bin/client/cucumber/feature.js +4 -17
  22. package/bin/client/cucumber/steps_definitions.js +17 -12
  23. package/bin/client/recorderv3/bvt_init.js +310 -0
  24. package/bin/client/recorderv3/bvt_recorder.js +1560 -1183
  25. package/bin/client/recorderv3/constants.js +45 -0
  26. package/bin/client/recorderv3/implemented_steps.js +2 -0
  27. package/bin/client/recorderv3/index.js +3 -293
  28. package/bin/client/recorderv3/mixpanel.js +41 -0
  29. package/bin/client/recorderv3/services.js +839 -142
  30. package/bin/client/recorderv3/step_runner.js +36 -7
  31. package/bin/client/recorderv3/step_utils.js +300 -98
  32. package/bin/client/recorderv3/update_feature.js +87 -39
  33. package/bin/client/recorderv3/utils.js +74 -0
  34. package/bin/client/recorderv3/wbr_entry.js +61 -0
  35. package/bin/client/recording.js +1 -0
  36. package/bin/client/types/locators.js +2 -0
  37. package/bin/client/upload-service.js +2 -0
  38. package/bin/client/utils/app_dir.js +21 -0
  39. package/bin/client/utils/socket_logger.js +100 -125
  40. package/bin/index.js +5 -0
  41. package/package.json +21 -6
  42. package/bin/client/recorderv3/app_dir.js +0 -23
  43. package/bin/client/recorderv3/network.js +0 -299
  44. package/bin/client/recorderv3/scriptTest.js +0 -5
  45. package/bin/client/recorderv3/ws_server.js +0 -72
@@ -12,7 +12,7 @@ import path from "path";
12
12
  * @param {string} text the text to verify exists in page
13
13
  * @protect
14
14
  */
15
- async function verifyTextExistsInPage(text) {
15
+ export async function verifyTextExistsInPage(text) {
16
16
  await context.web.verifyTextExistInPage(text, null, this);
17
17
  }
18
18
  Then("Verify the text {string} can be found in the page", verifyTextExistsInPage);
@@ -22,7 +22,7 @@ Then("Verify the text {string} can be found in the page", verifyTextExistsInPage
22
22
  * @param {string} elementDescription element description
23
23
  * @protect
24
24
  */
25
- async function clickOnElement(elementDescription) {
25
+ export async function clickOnElement(elementDescription) {
26
26
  await context.web.simpleClick(elementDescription, null, null, this);
27
27
  }
28
28
  When("click on {string}", clickOnElement);
@@ -36,7 +36,7 @@ When("Click {string}", clickOnElement);
36
36
  * @param {string} value value to fill the element with
37
37
  * @protect
38
38
  */
39
- async function fillElement(elementDescription, value) {
39
+ export async function fillElement(elementDescription, value) {
40
40
  await context.web.simpleClickType(elementDescription, value, null, null, this);
41
41
  }
42
42
  When("fill {string} with {string}", fillElement);
@@ -47,7 +47,7 @@ When("Fill {string} with {string}", fillElement);
47
47
  * @param {string} text the text to verify does not exist in page
48
48
  * @protect
49
49
  */
50
- async function verifyTextNotExistsInPage(text) {
50
+ export async function verifyTextNotExistsInPage(text) {
51
51
  await context.web.waitForTextToDisappear(text, null, this);
52
52
  }
53
53
  Then("Verify the text {string} cannot be found in the page", verifyTextNotExistsInPage);
@@ -57,7 +57,7 @@ Then("Verify the text {string} cannot be found in the page", verifyTextNotExists
57
57
  * @param {string} url URL to navigate
58
58
  * @protect
59
59
  */
60
- async function navigateTo(url) {
60
+ export async function navigateTo(url) {
61
61
  await context.web.goto(url, this);
62
62
  }
63
63
  When("Navigate to {string}", navigateTo);
@@ -66,7 +66,7 @@ When("Navigate to {string}", navigateTo);
66
66
  * Navigate to the current page
67
67
  * @protect
68
68
  */
69
- async function browserNavigateBack() {
69
+ export async function browserNavigateBack() {
70
70
  await context.web.goBack({}, this);
71
71
  }
72
72
  Then("Browser navigate back", browserNavigateBack);
@@ -75,7 +75,7 @@ Then("Browser navigate back", browserNavigateBack);
75
75
  * Navigate forward in browser history
76
76
  * @protect
77
77
  */
78
- async function browserNavigateForward() {
78
+ export async function browserNavigateForward() {
79
79
  await context.web.goForward({}, this);
80
80
  }
81
81
  Then("Browser navigate forward", browserNavigateForward);
@@ -85,7 +85,7 @@ Then("Browser navigate forward", browserNavigateForward);
85
85
  * @param {string} filePath the file path or empty to store in the test data file
86
86
  * @protect
87
87
  */
88
- async function storeBrowserSession(filePath) {
88
+ export async function storeBrowserSession(filePath) {
89
89
  await context.web.saveStoreState(filePath, this);
90
90
  }
91
91
  When("Store browser session {string}", storeBrowserSession);
@@ -95,7 +95,7 @@ When("Store browser session {string}", storeBrowserSession);
95
95
  * @param {string} filePath the file path or empty
96
96
  * @protect
97
97
  */
98
- async function resetBrowserSession(filePath) {
98
+ export async function resetBrowserSession(filePath) {
99
99
  await context.web.restoreSaveState(filePath, this);
100
100
  }
101
101
  When("Reset browser session {string}", resetBrowserSession);
@@ -107,7 +107,7 @@ When("Reset browser session {string}", resetBrowserSession);
107
107
  * @param {string} textToVerify the target text to verify
108
108
  * @protect
109
109
  */
110
- async function verifyTextRelatedToText(textAnchor, climb, textToVerify) {
110
+ export async function verifyTextRelatedToText(textAnchor, climb, textToVerify) {
111
111
  await context.web.verifyTextRelatedToText(textAnchor, climb, textToVerify, null, this);
112
112
  }
113
113
  Then(
@@ -120,7 +120,7 @@ Then(
120
120
  * @requestName the name of the bruno request file
121
121
  * @protect
122
122
  */
123
- async function runBrunoRequest(requestName) {
123
+ export async function runBrunoRequest(requestName) {
124
124
  await executeBrunoRequest(requestName, {}, context, this);
125
125
  }
126
126
  When("Bruno - {string}", runBrunoRequest);
@@ -131,7 +131,7 @@ When("bruno - {string}", runBrunoRequest);
131
131
  * @param {string} fileName the downloaded file to verify
132
132
  * @protect
133
133
  */
134
- async function verify_the_downloaded_file_exists(fileName) {
134
+ export async function verify_the_downloaded_file_exists(fileName) {
135
135
  const downloadFolder = path.join(context.reportFolder, "downloads");
136
136
  const downloadFile = path.join(downloadFolder, fileName);
137
137
  await verifyFileExists(downloadFile, {}, context, this);
@@ -148,7 +148,7 @@ When("Noop", async function () {});
148
148
  * @param {string} url URL to be verified against current URL
149
149
  * @protect
150
150
  */
151
- async function verify_page_url(url) {
151
+ export async function verify_page_url(url) {
152
152
  await context.web.verifyPagePath(url, {}, this);
153
153
  }
154
154
  Then("Verify the page url is {string}", verify_page_url);
@@ -158,7 +158,7 @@ Then("Verify the page url is {string}", verify_page_url);
158
158
  * @param {string} title Title to be verified against current Title
159
159
  * @protect
160
160
  */
161
- async function verify_page_title(title) {
161
+ export async function verify_page_title(title) {
162
162
  await context.web.verifyPageTitle(title, {}, this);
163
163
  }
164
164
  Then("Verify the page title is {string}", verify_page_title);
@@ -170,7 +170,7 @@ Then("Verify the page title is {string}", verify_page_title);
170
170
  * @param {world} - Optional world context
171
171
  * @returns Promise that resolves after the specified duration
172
172
  */
173
- async function sleep(duration) {
174
- await context.web.sleep(duration, {}, null);
173
+ export async function sleep(duration) {
174
+ await context.web.sleep(duration, {}, this);
175
175
  }
176
176
  Then("Sleep for {string} ms", { timeout: -1 }, sleep);
@@ -10,7 +10,7 @@ import * as t from "@babel/types";
10
10
  import { CucumberExpression, ParameterTypeRegistry } from "@cucumber/cucumber-expressions";
11
11
  import { existsSync, readFileSync, writeFileSync } from "fs";
12
12
  import { getAiConfig } from "../code_gen/page_reflection.js";
13
- import socketLogger from "../utils/socket_logger.js";
13
+ import socketLogger, { getErrorMessage } from "../utils/socket_logger.js";
14
14
 
15
15
  const STEP_KEYWORDS = new Set(["Given", "When", "Then"]);
16
16
 
@@ -308,18 +308,27 @@ export function getDefaultPrettierConfig() {
308
308
  const configContent = readFileSync(prettierConfigPath, "utf-8");
309
309
  prettierConfig = JSON.parse(configContent);
310
310
  } catch (error) {
311
- socketLogger.error("Error parsing Prettier config file", error);
312
- console.error(`Error parsing Prettier config file: ${error}`);
311
+ socketLogger.error(
312
+ `Error parsing Prettier config file: ${getErrorMessage(error)}`,
313
+ undefined,
314
+ "getDefaultPrettierConfig"
315
+ );
313
316
  }
314
317
  } else {
315
318
  // save the default config to .prettierrc
316
319
  try {
317
320
  writeFileSync(prettierConfigPath, JSON.stringify(prettierConfig, null, 2), "utf-8");
318
- socketLogger.info(`Created default Prettier config at ${prettierConfigPath}`);
319
- console.log(`Created default Prettier config at ${prettierConfigPath}`);
321
+ socketLogger.info(
322
+ `Created default Prettier config at ${prettierConfigPath}`,
323
+ undefined,
324
+ "getDefaultPrettierConfig"
325
+ );
320
326
  } catch (error) {
321
- socketLogger.error(`Error writing Prettier config file: ${error}`);
322
- console.error(`Error writing Prettier config file: ${error}`);
327
+ socketLogger.error(
328
+ `Error writing Prettier config file: ${getErrorMessage(error)}`,
329
+ undefined,
330
+ "getDefaultPrettierConfig"
331
+ );
323
332
  }
324
333
  }
325
334
  return prettierConfig;
@@ -1,5 +1,9 @@
1
1
  import { Types } from "../recording.js";
2
2
  import Walker from "node-source-walk";
3
+ /**
4
+ * @typedef {import("../types/locators").Locator} Locator
5
+ * @typedef {import("../types/locators").LocatorBundle} LocatorBundle
6
+ */
3
7
 
4
8
  const extractElementIdentifier = (node) => {
5
9
  // Check for elements["someIdentifier"] pattern
@@ -86,6 +90,34 @@ const parseDataSource = (paramNode, stepParams) => {
86
90
  // }
87
91
  throw new Error("Unknown parameter type");
88
92
  };
93
+
94
+ const parseOptions = (optionsNode) => {
95
+ const properties = optionsNode.properties;
96
+ const options = {};
97
+ for (const prop of properties) {
98
+ let key = "";
99
+ if (prop.key.type === "Identifier") {
100
+ key = prop.key.name;
101
+ } else if (prop.key.type === "StringLiteral") {
102
+ key = prop.key.value;
103
+ }
104
+ if (key === "context") continue;
105
+ options[key] = prop.value.value;
106
+ }
107
+ return options;
108
+ };
109
+
110
+ const parseOptionsFromCallNode = (call, index) => {
111
+ if (call.arguments[index] && call.arguments[index].type === "ObjectExpression") {
112
+ return parseOptions(call.arguments[index]);
113
+ }
114
+ return null;
115
+ };
116
+ /**
117
+ * @param {any} call
118
+ * @param {Record<string, { locators?: Locator[] | LocatorBundle }>} elements
119
+ * @param {any[]} stepParams
120
+ */
89
121
  const invertStableCommand = (call, elements, stepParams) => {
90
122
  const methodName = call.callee.property.name;
91
123
  const step = { type: null, parameters: [], element: null, locators: null };
@@ -104,6 +136,7 @@ const invertStableCommand = (call, elements, stepParams) => {
104
136
  step.dataSource = inputParam.dataSource;
105
137
  step.dataKey = inputParam.dataKey;
106
138
  }
139
+ step.options = parseOptionsFromCallNode(call, 3);
107
140
  break;
108
141
  }
109
142
 
@@ -130,6 +163,8 @@ const invertStableCommand = (call, elements, stepParams) => {
130
163
  step.count = clickCountProp.value.value;
131
164
  }
132
165
  }
166
+
167
+ step.options = parseOptionsFromCallNode(call, 2);
133
168
  break;
134
169
 
135
170
  case "setDateTime": {
@@ -147,6 +182,7 @@ const invertStableCommand = (call, elements, stepParams) => {
147
182
  step.dataKey = dateParam.dataKey;
148
183
  step.parameters = [toVariableName(dateParam.dataKey), format, enterParam];
149
184
  }
185
+ step.options = parseOptionsFromCallNode(call, 5);
150
186
  break;
151
187
  }
152
188
 
@@ -163,6 +199,7 @@ const invertStableCommand = (call, elements, stepParams) => {
163
199
  step.dataKey = selectParam.dataKey;
164
200
  step.parameters = [toVariableName(selectParam.dataKey)];
165
201
  }
202
+ step.options = parseOptionsFromCallNode(call, 3);
166
203
  break;
167
204
  }
168
205
 
@@ -176,6 +213,7 @@ const invertStableCommand = (call, elements, stepParams) => {
176
213
  step.dataKey = text.dataKey;
177
214
  step.parameters = [toVariableName(text.dataKey)];
178
215
  }
216
+ step.options = parseOptionsFromCallNode(call, 2);
179
217
  break;
180
218
  }
181
219
  case "waitForTextToDisappear": {
@@ -188,6 +226,7 @@ const invertStableCommand = (call, elements, stepParams) => {
188
226
  step.dataKey = text.dataKey;
189
227
  step.parameters = [toVariableName(text.dataKey)];
190
228
  }
229
+ step.options = parseOptionsFromCallNode(call, 2);
191
230
  break;
192
231
  }
193
232
 
@@ -203,6 +242,7 @@ const invertStableCommand = (call, elements, stepParams) => {
203
242
  step.dataKey = text.dataKey;
204
243
  step.parameters = [toVariableName(text.dataKey), climb ?? null];
205
244
  }
245
+ step.options = parseOptionsFromCallNode(call, 4);
206
246
  break;
207
247
  }
208
248
  case "extractAttribute": {
@@ -233,6 +273,7 @@ const invertStableCommand = (call, elements, stepParams) => {
233
273
  step.regex = "";
234
274
  step.trimSpaces = false;
235
275
  }
276
+ step.options = parseOptionsFromCallNode(call, 4);
236
277
  break;
237
278
  }
238
279
  case "verifyAttribute": {
@@ -249,6 +290,7 @@ const invertStableCommand = (call, elements, stepParams) => {
249
290
  step.dataKey = value.dataKey;
250
291
  step.parameters = [attribute, toVariableName(value.dataKey)];
251
292
  }
293
+ step.options = parseOptionsFromCallNode(call, 4);
252
294
  break;
253
295
  }
254
296
 
@@ -277,6 +319,7 @@ const invertStableCommand = (call, elements, stepParams) => {
277
319
  step.parameters = [toVariableName(fillParam.dataKey), enterValue];
278
320
  }
279
321
  }
322
+ step.options = parseOptionsFromCallNode(call, 4);
280
323
  break;
281
324
 
282
325
  case "loadTestDataAsync": {
@@ -307,23 +350,28 @@ const invertStableCommand = (call, elements, stepParams) => {
307
350
  step.dataKey = url.dataKey;
308
351
  step.parameters = [toVariableName(url.dataKey)];
309
352
  }
353
+ step.options = parseOptionsFromCallNode(call, 2);
310
354
  break;
311
355
  }
312
356
 
313
357
  case "goBack":
314
358
  step.type = Types.GO_BACK;
359
+ step.options = parseOptionsFromCallNode(call, 0);
315
360
  break;
316
361
 
317
362
  case "goForward":
318
363
  step.type = Types.GO_FORWARD;
364
+ step.options = parseOptionsFromCallNode(call, 0);
319
365
  break;
320
366
 
321
367
  case "reloadPage":
322
368
  step.type = Types.RELOAD;
369
+ step.options = parseOptionsFromCallNode(call, 0);
323
370
  break;
324
371
 
325
372
  case "closePage":
326
373
  step.type = Types.CLOSE_PAGE;
374
+ step.options = parseOptionsFromCallNode(call, 0);
327
375
  break;
328
376
 
329
377
  case "simpleClick":
@@ -341,12 +389,15 @@ const invertStableCommand = (call, elements, stepParams) => {
341
389
  case "hover":
342
390
  step.type = Types.HOVER;
343
391
  step.element = extractElement(call.arguments[0]);
392
+ step.options = parseOptionsFromCallNode(call, 2);
344
393
  break;
345
394
 
346
395
  case "setCheck":
347
396
  step.type = Types.CHECK;
348
397
  step.element = extractElement(call.arguments[0]);
349
398
  step.check = call.arguments[1].value;
399
+ ///
400
+ step.options = parseOptionsFromCallNode(call, 3);
350
401
  break;
351
402
 
352
403
  case "setViewportSize": {
@@ -354,12 +405,14 @@ const invertStableCommand = (call, elements, stepParams) => {
354
405
  const width = call.arguments[0].value;
355
406
  const height = call.arguments[1].value;
356
407
  step.parameters = [width, height];
408
+ step.options = parseOptionsFromCallNode(call, 2);
357
409
  break;
358
410
  }
359
411
 
360
412
  case "visualVerification": {
361
413
  step.type = Types.VISUAL_VERIFICATION;
362
414
  step.parameters = [call.arguments[0].value];
415
+ step.options = parseOptionsFromCallNode(call, 1);
363
416
  break;
364
417
  }
365
418
  case "waitForUserInput": {
@@ -370,6 +423,7 @@ const invertStableCommand = (call, elements, stepParams) => {
370
423
  case "extractEmailData": {
371
424
  step.type = Types.MAIL_GET_CODE_OR_URL;
372
425
  step.parameters = [call.arguments[0].value];
426
+ step.options = parseOptionsFromCallNode(call, 1);
373
427
  break;
374
428
  }
375
429
  case "verifyTextRelatedToText": {
@@ -383,6 +437,7 @@ const invertStableCommand = (call, elements, stepParams) => {
383
437
  const textToVerify =
384
438
  textToVerifyParse.type === "literal" ? textToVerifyParse.value : toVariableName(textToVerifyParse.dataKey);
385
439
  step.parameters = [textAnchor, climb, textToVerify];
440
+ step.options = parseOptionsFromCallNode(call, 3);
386
441
  break;
387
442
  }
388
443
  case "setInputFiles": {
@@ -396,6 +451,7 @@ const invertStableCommand = (call, elements, stepParams) => {
396
451
  step.dataKey = fileParam.dataKey;
397
452
  step.parameters = [toVariableName(fileParam.dataKey)];
398
453
  }
454
+ step.options = parseOptionsFromCallNode(call, 3);
399
455
  break;
400
456
  }
401
457
  case "snapshotValidation": {
@@ -405,6 +461,7 @@ const invertStableCommand = (call, elements, stepParams) => {
405
461
  step.parameters = [inputParam.value];
406
462
  }
407
463
  step.selectors = call.arguments[0].value;
464
+ step.options = parseOptionsFromCallNode(call, 3);
408
465
  break;
409
466
  }
410
467
  case "verifyPageTitle": {
@@ -417,6 +474,7 @@ const invertStableCommand = (call, elements, stepParams) => {
417
474
  step.dataKey = text.dataKey;
418
475
  step.parameters = [toVariableName(text.dataKey)];
419
476
  }
477
+ step.options = parseOptionsFromCallNode(call, 1);
420
478
  break;
421
479
  }
422
480
  case "verifyPagePath": {
@@ -429,6 +487,7 @@ const invertStableCommand = (call, elements, stepParams) => {
429
487
  step.dataKey = path.dataKey;
430
488
  step.parameters = [toVariableName(path.dataKey)];
431
489
  }
490
+ step.options = parseOptionsFromCallNode(call, 1);
432
491
  break;
433
492
  }
434
493
  case "verifyProperty": {
@@ -443,6 +502,7 @@ const invertStableCommand = (call, elements, stepParams) => {
443
502
  step.dataKey = value.dataKey;
444
503
  step.parameters = [property, toVariableName(value.dataKey)];
445
504
  }
505
+ step.options = parseOptionsFromCallNode(call, 4);
446
506
  break;
447
507
  }
448
508
  case "extractProperty": {
@@ -473,15 +533,79 @@ const invertStableCommand = (call, elements, stepParams) => {
473
533
  step.regex = "";
474
534
  step.trimSpaces = false;
475
535
  }
536
+ step.options = parseOptionsFromCallNode(call, 4);
537
+ break;
538
+ }
539
+
540
+ case "conditionalWait": {
541
+ step.type = Types.CONDITIONAL_WAIT;
542
+ step.element = extractElement(call.arguments[0]);
543
+ const condition = call.arguments[1].value;
544
+
545
+ const _timeout = parseDataSource(call.arguments[2], stepParams);
546
+ let timeout = 30;
547
+ if (_timeout.type === "literal") {
548
+ if (isNaN(_timeout.value)) {
549
+ throw new Error(`Timeout value must be a number, got ${_timeout.value}`);
550
+ }
551
+ timeout = Number(_timeout.value) * 1000;
552
+ } else {
553
+ step.dataSource = _timeout.dataSource;
554
+ step.dataKey = _timeout.dataKey;
555
+ timeout = toVariableName(_timeout.dataKey);
556
+ }
557
+ // step.timeout = timeout;
558
+ // step.value = "true";
559
+ step.parameters = [timeout, condition, step.value];
560
+ // step.condition = condition;
561
+ step.options = parseOptionsFromCallNode(call, 4);
562
+ break;
563
+ }
564
+
565
+ case "sleep": {
566
+ step.type = Types.SLEEP;
567
+ const duration = parseDataSource(call.arguments[0], stepParams);
568
+ if (duration.type === "literal") {
569
+ if (isNaN(duration.value)) {
570
+ throw new Error(`Sleep duration must be a number, got ${duration.value}`);
571
+ }
572
+ step.parameters = [Number(duration.value)];
573
+ } else {
574
+ step.dataSource = duration.dataSource;
575
+ step.dataKey = duration.dataKey;
576
+ step.parameters = [toVariableName(duration.dataKey)];
577
+ }
578
+ step.options = parseOptionsFromCallNode(call, 1);
476
579
  break;
477
580
  }
581
+ case "verify_file_exists": {
582
+ step.type = Types.VERIFY_FILE_EXISTS;
583
+ const filePath = parseDataSource(call.arguments[0], stepParams);
584
+ if (filePath.type === "literal") {
585
+ step.parameters = [filePath.value];
586
+ } else {
587
+ step.dataSource = filePath.dataSource;
588
+ step.dataKey = filePath.dataKey;
589
+ step.parameters = [toVariableName(filePath.dataKey)];
590
+ }
591
+ step.options = parseOptionsFromCallNode(call, 1);
592
+ break;
593
+ }
594
+
595
+ // case "verifyPagePath":
596
+ // {
597
+ // step.type = Types.VERIFY_PAGE_PATH;
598
+ // step.parameters = [call.arguments[0].value];
599
+ // break;
600
+ // }
478
601
  default:
479
602
  return; // Skip if no matching method
480
603
  }
481
604
 
482
605
  // Set locators if element exists
483
606
  if (step.element && elements[step.element.key]) {
484
- step.locators = elements[step.element.key];
607
+ const locBundle = elements[step.element.key];
608
+ step.locators = locBundle;
485
609
  }
486
610
 
487
611
  if (step.type === Types.CLICK) {
@@ -4,6 +4,7 @@ import path from "path";
4
4
  import { CodePage } from "./page_reflection.js";
5
5
  import { compareElements, generateSignature } from "./function_signature.js";
6
6
  import { updateStepDefinitions } from "../recorderv3/step_utils.js";
7
+ import socketLoggerInstance from "../utils/socket_logger.js";
7
8
  /**
8
9
  * DuplicationAnalizer class
9
10
  * How to use:
@@ -101,7 +102,7 @@ async function compareWithScenario(projectDir, scenario) {
101
102
  analyzerExisting.load();
102
103
  // generate a temporary folder
103
104
  const folder = fs.mkdtempSync(path.join(os.tmpdir(), "blinq-"));
104
- await updateStepDefinitions({ scenario, featureName: "temp", projectDir: folder });
105
+ await updateStepDefinitions({ scenario, featureName: "temp", projectDir: folder, logger: socketLoggerInstance });
105
106
  const analyzerScenario = new DuplicationAnalizer(folder);
106
107
  analyzerScenario.load();
107
108
  const compareResults = [];
@@ -11,6 +11,12 @@ async function verify_the_opportunity_name_was_created(_name) {
11
11
  }
12
12
  */
13
13
 
14
+ import strip from "strip-comments";
15
+ /**
16
+ * @typedef {import("../types/locators").Locator} Locator
17
+ * @typedef {import("../types/locators").LocatorBundle} LocatorBundle
18
+ */
19
+
14
20
  function generateSignature(page, functionName) {
15
21
  let functionCode = null;
16
22
  let method = null;
@@ -28,6 +34,8 @@ function generateSignature(page, functionName) {
28
34
  method.node.body.parent.params.forEach((param) => {
29
35
  parameters.push(param.name);
30
36
  });
37
+ const strippedFunctionCode = strip(functionCode);
38
+ functionCode = strippedFunctionCode !== "" ? strippedFunctionCode : functionCode;
31
39
  let lines = functionCode.split("\n");
32
40
  // trim all lines
33
41
  lines = lines.map((line) => line.trim());
@@ -1,4 +1,8 @@
1
1
  import fs from "fs";
2
+ /**
3
+ * @typedef {import("../types/locators").Locator} Locator
4
+ * @typedef {import("../types/locators").LocatorBundle} LocatorBundle
5
+ */
2
6
 
3
7
  import { Project } from "../project.js";
4
8
  import { generateCode } from "./playwright_codeget.js";