@dev-blinq/cucumber_client 1.0.1475-dev → 1.0.1475-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 +49 -49
- package/bin/assets/scripts/recorder.js +87 -34
- package/bin/assets/scripts/snapshot_capturer.js +10 -17
- package/bin/assets/scripts/unique_locators.js +78 -28
- package/bin/assets/templates/_hooks_template.txt +6 -2
- package/bin/assets/templates/utils_template.txt +16 -16
- package/bin/client/code_cleanup/codemod/find_harcoded_locators.js +173 -0
- package/bin/client/code_cleanup/codemod/fix_hardcoded_locators.js +247 -0
- package/bin/client/code_cleanup/utils.js +16 -7
- package/bin/client/code_gen/code_inversion.js +125 -1
- package/bin/client/code_gen/duplication_analysis.js +2 -1
- package/bin/client/code_gen/function_signature.js +8 -0
- package/bin/client/code_gen/index.js +4 -0
- package/bin/client/code_gen/page_reflection.js +90 -9
- package/bin/client/code_gen/playwright_codeget.js +173 -77
- package/bin/client/codemod/find_harcoded_locators.js +173 -0
- package/bin/client/codemod/fix_hardcoded_locators.js +247 -0
- package/bin/client/codemod/index.js +8 -0
- package/bin/client/codemod/locators_array/find_misstructured_elements.js +148 -0
- package/bin/client/codemod/locators_array/fix_misstructured_elements.js +144 -0
- package/bin/client/codemod/locators_array/index.js +114 -0
- package/bin/client/codemod/types.js +1 -0
- package/bin/client/cucumber/feature.js +4 -17
- package/bin/client/cucumber/steps_definitions.js +17 -12
- package/bin/client/recorderv3/bvt_init.js +310 -0
- package/bin/client/recorderv3/bvt_recorder.js +1560 -1183
- package/bin/client/recorderv3/constants.js +45 -0
- package/bin/client/recorderv3/implemented_steps.js +2 -0
- package/bin/client/recorderv3/index.js +3 -293
- package/bin/client/recorderv3/mixpanel.js +39 -0
- package/bin/client/recorderv3/services.js +839 -142
- package/bin/client/recorderv3/step_runner.js +36 -7
- package/bin/client/recorderv3/step_utils.js +316 -98
- package/bin/client/recorderv3/update_feature.js +85 -37
- package/bin/client/recorderv3/utils.js +80 -0
- package/bin/client/recorderv3/wbr_entry.js +61 -0
- package/bin/client/recording.js +1 -0
- package/bin/client/types/locators.js +2 -0
- package/bin/client/upload-service.js +2 -0
- package/bin/client/utils/app_dir.js +21 -0
- package/bin/client/utils/socket_logger.js +100 -125
- package/bin/index.js +5 -0
- package/package.json +21 -6
- package/bin/client/recorderv3/app_dir.js +0 -23
- package/bin/client/recorderv3/network.js +0 -299
- package/bin/client/recorderv3/scriptTest.js +0 -5
- package/bin/client/recorderv3/ws_server.js +0 -72
|
@@ -5,6 +5,8 @@ import path from "path";
|
|
|
5
5
|
import { CodePage } from "./page_reflection.js";
|
|
6
6
|
import { convertToIdentifier, escapeNonPrintables } from "./utils.js";
|
|
7
7
|
import socketLogger from "../utils/socket_logger.js";
|
|
8
|
+
import fs from "fs";
|
|
9
|
+
|
|
8
10
|
const findElementIdentifier = (node, step, userData, elements) => {
|
|
9
11
|
if (node.key) {
|
|
10
12
|
// incase of rerunning implemented steps
|
|
@@ -47,6 +49,7 @@ const findElementIdentifier = (node, step, userData, elements) => {
|
|
|
47
49
|
return elementIdentifier;
|
|
48
50
|
};
|
|
49
51
|
const _isCodeGenerationStep = (step) => {
|
|
52
|
+
return true;
|
|
50
53
|
if (
|
|
51
54
|
step.type === Types.CLICK ||
|
|
52
55
|
step.type === Types.FILL ||
|
|
@@ -67,18 +70,54 @@ const _isCodeGenerationStep = (step) => {
|
|
|
67
70
|
step.type === Types.VERIFY_PROPERTY ||
|
|
68
71
|
step.type === Types.SET_INPUT_FILES ||
|
|
69
72
|
step.type === Types.VERIFY_PAGE_SNAPSHOT ||
|
|
70
|
-
step.type === Types.CONDITIONAL_WAIT
|
|
73
|
+
step.type === Types.CONDITIONAL_WAIT ||
|
|
74
|
+
step.type === Types.CLOSE_PAGE
|
|
71
75
|
) {
|
|
72
76
|
return true;
|
|
73
77
|
}
|
|
74
78
|
return false;
|
|
75
79
|
};
|
|
80
|
+
|
|
81
|
+
const _isLocatorStrategyStep = (step) => {
|
|
82
|
+
switch (step.type) {
|
|
83
|
+
case Types.VERIFY_PAGE_SNAPSHOT:
|
|
84
|
+
case Types.CLOSE_PAGE:
|
|
85
|
+
case Types.VERIFY_FILE_EXISTS:
|
|
86
|
+
case Types.VERIFY_PAGE_CONTAINS_NO_TEXT:
|
|
87
|
+
case Types.VERIFY_PAGE_CONTAINS_TEXT:
|
|
88
|
+
case Types.VERIFY_PAGE_PATH:
|
|
89
|
+
case Types.VERIFY_PAGE_TITLE:
|
|
90
|
+
case Types.VERIFY_TEXT_RELATED_TO_TEXT:
|
|
91
|
+
case Types.NAVIGATE:
|
|
92
|
+
case Types.RELOAD:
|
|
93
|
+
case Types.GO_BACK:
|
|
94
|
+
case Types.GO_FORWARD:
|
|
95
|
+
case Types.SLEEP:
|
|
96
|
+
case Types.SET_VIEWPORT:
|
|
97
|
+
case Types.VISUAL_VERIFICATION:
|
|
98
|
+
case Types.LOAD_DATA:
|
|
99
|
+
case Types.MAIL_GET_CODE_OR_URL:
|
|
100
|
+
case Types.ASK:
|
|
101
|
+
case Types.WAIT_FOR_USER_INPUT:
|
|
102
|
+
case Types.COMPLETE:
|
|
103
|
+
case Types.CLICK_SIMPLE:
|
|
104
|
+
case Types.FILL_SIMPLE:
|
|
105
|
+
case Types.API:
|
|
106
|
+
return false;
|
|
107
|
+
default:
|
|
108
|
+
return true;
|
|
109
|
+
}
|
|
110
|
+
};
|
|
76
111
|
// Note: this function is used to exclude a key from an object
|
|
77
112
|
// Please move it to utils and use it as a reusable function ...
|
|
78
113
|
function excludeKey(obj, keyToRemove) {
|
|
79
114
|
const { [keyToRemove]: _, ...rest } = obj;
|
|
80
115
|
return rest;
|
|
81
116
|
}
|
|
117
|
+
/**
|
|
118
|
+
* Split locators by strategy
|
|
119
|
+
* @param {import("../types/locators").LocatorBundle} locators
|
|
120
|
+
*/
|
|
82
121
|
const splitToLocatorsGroups = (locators) => {
|
|
83
122
|
const no_text = locators.locators.filter((locator) => locator.mode === "NO_TEXT");
|
|
84
123
|
const ignore_digit = locators.locators.filter((locator) => locator.mode === "IGNORE_DIGIT");
|
|
@@ -97,6 +136,20 @@ const splitToLocatorsGroups = (locators) => {
|
|
|
97
136
|
});
|
|
98
137
|
return { basic, no_text, ignore_digit, context };
|
|
99
138
|
};
|
|
139
|
+
|
|
140
|
+
const serializeOptions = (options, context) => {
|
|
141
|
+
if (!options) return "null";
|
|
142
|
+
if (typeof options !== "object") return "null";
|
|
143
|
+
if (Array.isArray(options)) return "null";
|
|
144
|
+
let result = "{ ";
|
|
145
|
+
if (context) result += `"context": ${context}, `;
|
|
146
|
+
for (const key in options) {
|
|
147
|
+
result += `"${key}": ${JSON.stringify(options[key])}, `;
|
|
148
|
+
}
|
|
149
|
+
result += " }";
|
|
150
|
+
return result;
|
|
151
|
+
};
|
|
152
|
+
|
|
100
153
|
const _generateCodeFromCommand = (step, elements, userData) => {
|
|
101
154
|
let elementsChanged = false;
|
|
102
155
|
|
|
@@ -105,7 +158,12 @@ const _generateCodeFromCommand = (step, elements, userData) => {
|
|
|
105
158
|
// handle element
|
|
106
159
|
let element_name = null;
|
|
107
160
|
let allStrategyLocators = null;
|
|
108
|
-
|
|
161
|
+
const codeLines = [];
|
|
162
|
+
|
|
163
|
+
if (_isCodeGenerationStep(step) === false)
|
|
164
|
+
return { codeLines, elements: elementsChanged ? elements : null, elementIdentifier, allStrategyLocators };
|
|
165
|
+
|
|
166
|
+
if (_isCodeGenerationStep(step) && _isLocatorStrategyStep(step)) {
|
|
109
167
|
allStrategyLocators = step.allStrategyLocators ?? splitToLocatorsGroups(step.locators);
|
|
110
168
|
let node = null;
|
|
111
169
|
|
|
@@ -167,8 +225,6 @@ const _generateCodeFromCommand = (step, elements, userData) => {
|
|
|
167
225
|
}
|
|
168
226
|
}
|
|
169
227
|
|
|
170
|
-
const codeLines = [];
|
|
171
|
-
|
|
172
228
|
let line = null;
|
|
173
229
|
let comment = null;
|
|
174
230
|
let input = null;
|
|
@@ -176,7 +232,7 @@ const _generateCodeFromCommand = (step, elements, userData) => {
|
|
|
176
232
|
let attribute = null;
|
|
177
233
|
let variable = null;
|
|
178
234
|
let format = null;
|
|
179
|
-
let options = null;
|
|
235
|
+
let options = step.options ?? null;
|
|
180
236
|
let property = null;
|
|
181
237
|
switch (step.type) {
|
|
182
238
|
case Types.SET_INPUT:
|
|
@@ -186,7 +242,7 @@ const _generateCodeFromCommand = (step, elements, userData) => {
|
|
|
186
242
|
//parameters.push(step.dataKey);
|
|
187
243
|
input = "_" + step.dataKey;
|
|
188
244
|
}
|
|
189
|
-
line += `${input}, _params,
|
|
245
|
+
line += `${input}, _params, ${serializeOptions(options)}, this);`;
|
|
190
246
|
if (element_name) {
|
|
191
247
|
comment = `// Set ${element_name} to ${input}`;
|
|
192
248
|
codeLines.push(escapeNonPrintables(comment));
|
|
@@ -199,7 +255,7 @@ const _generateCodeFromCommand = (step, elements, userData) => {
|
|
|
199
255
|
comment = `// Check ${element_name}`;
|
|
200
256
|
codeLines.push(escapeNonPrintables(comment));
|
|
201
257
|
}
|
|
202
|
-
line = `await context.web.setCheck(elements["${elementIdentifier}"], ${step.check}, _params,
|
|
258
|
+
line = `await context.web.setCheck(elements["${elementIdentifier}"], ${step.check}, _params, ${serializeOptions(options)}, this);`;
|
|
203
259
|
codeLines.push(line);
|
|
204
260
|
} else {
|
|
205
261
|
switch (step.count) {
|
|
@@ -208,7 +264,7 @@ const _generateCodeFromCommand = (step, elements, userData) => {
|
|
|
208
264
|
comment = `// Click on ${element_name}`;
|
|
209
265
|
codeLines.push(escapeNonPrintables(comment));
|
|
210
266
|
}
|
|
211
|
-
line = `await context.web.click(elements["${elementIdentifier}"], _params,
|
|
267
|
+
line = `await context.web.click(elements["${elementIdentifier}"], _params, ${serializeOptions(options)}, this);`;
|
|
212
268
|
codeLines.push(line);
|
|
213
269
|
break;
|
|
214
270
|
case 2:
|
|
@@ -216,7 +272,9 @@ const _generateCodeFromCommand = (step, elements, userData) => {
|
|
|
216
272
|
comment = `// Double click on ${element_name}`;
|
|
217
273
|
codeLines.push(escapeNonPrintables(comment));
|
|
218
274
|
}
|
|
219
|
-
|
|
275
|
+
options = options ?? {};
|
|
276
|
+
options.clickCount = 2;
|
|
277
|
+
line = `await context.web.click(elements["${elementIdentifier}"], _params, ${serializeOptions(options)}, this);`;
|
|
220
278
|
codeLines.push(line);
|
|
221
279
|
break;
|
|
222
280
|
default:
|
|
@@ -224,7 +282,7 @@ const _generateCodeFromCommand = (step, elements, userData) => {
|
|
|
224
282
|
comment = `// Click on ${element_name}`;
|
|
225
283
|
codeLines.push(escapeNonPrintables(comment));
|
|
226
284
|
}
|
|
227
|
-
line = `await context.web.click(elements["${elementIdentifier}"], _params,
|
|
285
|
+
line = `await context.web.click(elements["${elementIdentifier}"], _params, ${serializeOptions(options)}, this);`;
|
|
228
286
|
codeLines.push(line);
|
|
229
287
|
break;
|
|
230
288
|
}
|
|
@@ -235,17 +293,19 @@ const _generateCodeFromCommand = (step, elements, userData) => {
|
|
|
235
293
|
case 1:
|
|
236
294
|
comment = `// Parameterized click on ${step.value}`;
|
|
237
295
|
codeLines.push(escapeNonPrintables(comment));
|
|
238
|
-
line = `await context.web.click(elements["${elementIdentifier}"], _params,
|
|
296
|
+
line = `await context.web.click(elements["${elementIdentifier}"], _params, ${serializeOptions(options)}, this);`;
|
|
239
297
|
break;
|
|
240
298
|
case 2:
|
|
241
299
|
comment = `// Parameterized double click on ${step.value}`;
|
|
242
300
|
codeLines.push(escapeNonPrintables(comment));
|
|
243
|
-
|
|
301
|
+
options = options ?? {};
|
|
302
|
+
options.clickCount = 2;
|
|
303
|
+
line = `await context.web.click(elements["${elementIdentifier}"], _params, ${serializeOptions(options)}, this);`;
|
|
244
304
|
break;
|
|
245
305
|
default:
|
|
246
306
|
comment = `// Parameterized click on ${step.value}`;
|
|
247
307
|
codeLines.push(escapeNonPrintables(comment));
|
|
248
|
-
line = `await context.web.click(elements["${elementIdentifier}"], _params,
|
|
308
|
+
line = `await context.web.click(elements["${elementIdentifier}"], _params, ${serializeOptions(options)}, this);`;
|
|
249
309
|
}
|
|
250
310
|
codeLines.push(line);
|
|
251
311
|
break;
|
|
@@ -264,7 +324,7 @@ const _generateCodeFromCommand = (step, elements, userData) => {
|
|
|
264
324
|
} else {
|
|
265
325
|
enter = '"' + step.parameters[2] + '"';
|
|
266
326
|
}
|
|
267
|
-
line += `${input}, "${format}", ${enter}, _params,
|
|
327
|
+
line += `${input}, "${format}", ${enter}, _params, ${serializeOptions(options)}, this);`;
|
|
268
328
|
if (element_name) {
|
|
269
329
|
comment = `// Set date time ${element_name} to "${input}" with format "${format}"`;
|
|
270
330
|
codeLines.push(escapeNonPrintables(comment));
|
|
@@ -286,7 +346,7 @@ const _generateCodeFromCommand = (step, elements, userData) => {
|
|
|
286
346
|
} else {
|
|
287
347
|
enter = '"' + step.parameters[1] + '"';
|
|
288
348
|
}
|
|
289
|
-
line += `${input}, ${enter}, _params,
|
|
349
|
+
line += `${input}, ${enter}, _params, ${serializeOptions(options)}, this);`;
|
|
290
350
|
if (element_name) {
|
|
291
351
|
comment = `// Fill ${element_name} with "${input}"`;
|
|
292
352
|
codeLines.push(escapeNonPrintables(comment));
|
|
@@ -308,7 +368,7 @@ const _generateCodeFromCommand = (step, elements, userData) => {
|
|
|
308
368
|
} else {
|
|
309
369
|
enter = '"' + step.parameters[1] + '"';
|
|
310
370
|
}
|
|
311
|
-
line += `${input}, ${enter}, _params,
|
|
371
|
+
line += `${input}, ${enter}, _params, ${serializeOptions(options)}, this);`;
|
|
312
372
|
if (element_name) {
|
|
313
373
|
comment = `// Fill ${element_name} with "${input}"`;
|
|
314
374
|
codeLines.push(escapeNonPrintables(comment));
|
|
@@ -322,15 +382,25 @@ const _generateCodeFromCommand = (step, elements, userData) => {
|
|
|
322
382
|
if (step.dataSource === "userData" || step.dataSource === "parameters") {
|
|
323
383
|
input = "_" + step.dataKey;
|
|
324
384
|
}
|
|
325
|
-
let options = "null";
|
|
385
|
+
// let options = "null";
|
|
326
386
|
if (step.regex !== "") {
|
|
327
|
-
options =
|
|
387
|
+
options = options ?? {};
|
|
388
|
+
options = {
|
|
389
|
+
...options,
|
|
390
|
+
regex: step.regex,
|
|
391
|
+
trimSpaces: step.trimSpaces,
|
|
392
|
+
}; // `{regex: ${JSON.stringify(step.regex)},trimSpaces: ${step.trimSpaces}}`;
|
|
328
393
|
} else if (step.trimSpaces) {
|
|
329
|
-
options =
|
|
394
|
+
options = options ?? {};
|
|
395
|
+
options = {
|
|
396
|
+
...options,
|
|
397
|
+
trimSpaces: step.trimSpaces,
|
|
398
|
+
};
|
|
399
|
+
// options = `{trimSpaces: ${step.trimSpaces}}`;
|
|
330
400
|
} else {
|
|
331
|
-
options = "null";
|
|
401
|
+
options = null; //"null";
|
|
332
402
|
}
|
|
333
|
-
line = `await context.web.extractAttribute(elements["${elementIdentifier}"], "${attribute}", ${input}, _params
|
|
403
|
+
line = `await context.web.extractAttribute(elements["${elementIdentifier}"], "${attribute}", ${input}, _params, ${serializeOptions(options)}, this);`;
|
|
334
404
|
|
|
335
405
|
if (element_name) {
|
|
336
406
|
comment = `// Extract attribute ${attribute} from ${element_name} to ${variable}`;
|
|
@@ -346,15 +416,24 @@ const _generateCodeFromCommand = (step, elements, userData) => {
|
|
|
346
416
|
if (step.dataSource === "userData" || step.dataSource === "parameters") {
|
|
347
417
|
input = "_" + step.dataKey;
|
|
348
418
|
}
|
|
349
|
-
let options = "null";
|
|
350
419
|
if (step.regex !== "") {
|
|
351
|
-
options =
|
|
420
|
+
options = options ?? {};
|
|
421
|
+
options = {
|
|
422
|
+
...options,
|
|
423
|
+
regex: step.regex,
|
|
424
|
+
trimSpaces: step.trimSpaces,
|
|
425
|
+
}; // `{regex: ${JSON.stringify(step.regex)},trimSpaces: ${step.trimSpaces}}`;
|
|
352
426
|
} else if (step.trimSpaces) {
|
|
353
|
-
options =
|
|
427
|
+
options = options ?? {};
|
|
428
|
+
options = {
|
|
429
|
+
...options,
|
|
430
|
+
trimSpaces: step.trimSpaces,
|
|
431
|
+
};
|
|
432
|
+
// options = `{trimSpaces: ${step.trimSpaces}}`;
|
|
354
433
|
} else {
|
|
355
|
-
options = "null";
|
|
434
|
+
options = null; //"null";
|
|
356
435
|
}
|
|
357
|
-
line = `await context.web.extractProperty(elements["${elementIdentifier}"], "${property}", ${input}, _params
|
|
436
|
+
line = `await context.web.extractProperty(elements["${elementIdentifier}"], "${property}", ${input}, _params, ${serializeOptions(options)}, this);`;
|
|
358
437
|
|
|
359
438
|
if (element_name) {
|
|
360
439
|
comment = `// Extract property ${property} from ${element_name} to ${variable}`;
|
|
@@ -363,23 +442,40 @@ const _generateCodeFromCommand = (step, elements, userData) => {
|
|
|
363
442
|
codeLines.push(line);
|
|
364
443
|
break;
|
|
365
444
|
}
|
|
366
|
-
case Types.VERIFY_PAGE_SNAPSHOT:
|
|
445
|
+
case Types.VERIFY_PAGE_SNAPSHOT: {
|
|
367
446
|
comment = step.nestFrmLoc
|
|
368
447
|
? `// Verify page snapshot ${step.parameters[0]} in the frame ${step.selectors.iframe_src}`
|
|
369
448
|
: `// Verify page snapshot ${step.parameters[0]}`;
|
|
370
449
|
codeLines.push(escapeNonPrintables(comment));
|
|
371
450
|
line = `const frameLocator = ${JSON.stringify(step.selectors ?? null)}`;
|
|
372
451
|
codeLines.push(line);
|
|
373
|
-
line = `await context.web.snapshotValidation(frameLocator
|
|
452
|
+
line = `await context.web.snapshotValidation(frameLocator,${step.valueInStepText ? "_param_0" : `"${step.parameters[0]}"`}, _params, ${serializeOptions(options)}, this);`;
|
|
374
453
|
codeLines.push(line);
|
|
454
|
+
|
|
455
|
+
const data = step.data;
|
|
456
|
+
if (data) {
|
|
457
|
+
try {
|
|
458
|
+
const { snapshot, fileName, filePath } = data;
|
|
459
|
+
const folderPath = process.env.BVT_TEMP_SNAPSHOTS_FOLDER ?? filePath;
|
|
460
|
+
const filePathWithName = path.join(folderPath, fileName);
|
|
461
|
+
if (!fs.existsSync(folderPath)) {
|
|
462
|
+
fs.mkdirSync(folderPath, { recursive: true });
|
|
463
|
+
}
|
|
464
|
+
fs.writeFileSync(filePathWithName, snapshot, "utf-8");
|
|
465
|
+
} catch (e) {
|
|
466
|
+
console.log(`Error saving snapshot file: ${e}`);
|
|
467
|
+
throw e;
|
|
468
|
+
}
|
|
469
|
+
}
|
|
375
470
|
break;
|
|
471
|
+
}
|
|
376
472
|
case Types.VERIFY_PAGE_CONTAINS_TEXT:
|
|
377
473
|
line = "await context.web.verifyTextExistInPage( ";
|
|
378
474
|
input = `${escapeNonPrintables(JSON.stringify(step.parameters[0]))}`;
|
|
379
475
|
if (step.dataSource === "userData" || step.dataSource === "parameters") {
|
|
380
476
|
input = "_" + step.dataKey;
|
|
381
477
|
}
|
|
382
|
-
line += `${input},
|
|
478
|
+
line += `${input}, ${serializeOptions(options)}, this);`;
|
|
383
479
|
comment = `// Verify page contains text "${input}"`;
|
|
384
480
|
codeLines.push(escapeNonPrintables(comment));
|
|
385
481
|
codeLines.push(line);
|
|
@@ -393,7 +489,7 @@ const _generateCodeFromCommand = (step, elements, userData) => {
|
|
|
393
489
|
if (step.dataSource === "userData" || step.dataSource === "parameters") {
|
|
394
490
|
input = "_" + step.dataKey;
|
|
395
491
|
}
|
|
396
|
-
line += `${input}, ${step.parameters[1]} ,_params,
|
|
492
|
+
line += `${input}, ${step.parameters[1]} , _params, ${serializeOptions(options)}, this);`;
|
|
397
493
|
if (element_name) {
|
|
398
494
|
comment = `// Verify ${element_name} contains text "${input}"`;
|
|
399
495
|
codeLines.push(escapeNonPrintables(comment));
|
|
@@ -408,7 +504,7 @@ const _generateCodeFromCommand = (step, elements, userData) => {
|
|
|
408
504
|
}
|
|
409
505
|
line = `await context.web.analyzeTable(elements["${elementIdentifier}"], ${JSON.stringify(
|
|
410
506
|
step.parameters[0]
|
|
411
|
-
)}, "${step.parameters[1]}", ${input}, _params,
|
|
507
|
+
)}, "${step.parameters[1]}", ${input}, _params, ${serializeOptions(options)}, this);`;
|
|
412
508
|
if (element_name) {
|
|
413
509
|
comment = `// Analyze table ${element_name} query ${JSON.stringify(
|
|
414
510
|
step.parameters[0]
|
|
@@ -428,27 +524,27 @@ const _generateCodeFromCommand = (step, elements, userData) => {
|
|
|
428
524
|
} else if (step.dataSource === "environment") {
|
|
429
525
|
input = `context.environment["_${step.dataKey}"]`;
|
|
430
526
|
}
|
|
431
|
-
line += `${input}, _params,
|
|
527
|
+
line += `${input}, _params, ${serializeOptions(options)}, this);`;
|
|
432
528
|
if (element_name) {
|
|
433
529
|
comment = `// Select "${input}" from ${element_name}`;
|
|
434
530
|
codeLines.push(escapeNonPrintables(comment));
|
|
435
531
|
}
|
|
436
532
|
codeLines.push(line);
|
|
437
533
|
} else if (step.selectMode === "click_combo") {
|
|
438
|
-
line = `await context.web.click(elements["${elementIdentifier}"], _params,
|
|
534
|
+
line = `await context.web.click(elements["${elementIdentifier}"], _params, ${serializeOptions(options)}, this);`;
|
|
439
535
|
if (element_name) {
|
|
440
536
|
comment = `// Open combobox ${element_name}`;
|
|
441
537
|
codeLines.push(escapeNonPrintables(comment));
|
|
442
538
|
}
|
|
443
539
|
codeLines.push(line);
|
|
444
|
-
line = `await context.web.click(elements["${optionIdentifier}"], _params,
|
|
540
|
+
line = `await context.web.click(elements["${optionIdentifier}"], _params, ${serializeOptions(options)}, this);`;
|
|
445
541
|
if (element_name) {
|
|
446
542
|
comment = `// Select "${optionIdentifier}" from ${element_name}`;
|
|
447
543
|
codeLines.push(escapeNonPrintables(comment));
|
|
448
544
|
}
|
|
449
545
|
codeLines.push(line);
|
|
450
546
|
} else if (step.selectMode === "click") {
|
|
451
|
-
line = `await context.web.click(elements["${optionIdentifier}"], _params,
|
|
547
|
+
line = `await context.web.click(elements["${optionIdentifier}"], _params, ${serializeOptions(options)}, this);`;
|
|
452
548
|
if (element_name) {
|
|
453
549
|
comment = `// Select ${optionIdentifier} from ${element_name}`;
|
|
454
550
|
codeLines.push(escapeNonPrintables(comment));
|
|
@@ -461,13 +557,13 @@ const _generateCodeFromCommand = (step, elements, userData) => {
|
|
|
461
557
|
if (step.dataSource === "userData" || step.dataSource === "parameters") {
|
|
462
558
|
input = "_" + step.dataKey;
|
|
463
559
|
}
|
|
464
|
-
line += `${input}, false, _params,
|
|
560
|
+
line += `${input}, false, _params, ${serializeOptions(options)}, this);`;
|
|
465
561
|
if (element_name) {
|
|
466
562
|
comment = `// Fill ${element_name} with "${input}"`;
|
|
467
563
|
codeLines.push(escapeNonPrintables(comment));
|
|
468
564
|
}
|
|
469
565
|
codeLines.push(line);
|
|
470
|
-
line = `await context.web.click(elements["${optionIdentifier}"], _params,
|
|
566
|
+
line = `await context.web.click(elements["${optionIdentifier}"], _params, ${serializeOptions(options)}, this);`;
|
|
471
567
|
codeLines.push(line);
|
|
472
568
|
} else {
|
|
473
569
|
throw new Error(`Unknown select mode ${step.selectMode}`);
|
|
@@ -479,13 +575,13 @@ const _generateCodeFromCommand = (step, elements, userData) => {
|
|
|
479
575
|
case Types.RELOAD:
|
|
480
576
|
comment = `// Reload page`;
|
|
481
577
|
codeLines.push(escapeNonPrintables(comment));
|
|
482
|
-
line =
|
|
578
|
+
line = `await context.web.reloadPage(${serializeOptions(options)}, this);`;
|
|
483
579
|
codeLines.push(line);
|
|
484
580
|
break;
|
|
485
581
|
case Types.CLOSE_PAGE:
|
|
486
582
|
comment = `// Close page`;
|
|
487
583
|
codeLines.push(escapeNonPrintables(comment));
|
|
488
|
-
line =
|
|
584
|
+
line = `await context.web.closePage(${serializeOptions(options)}, this);`;
|
|
489
585
|
codeLines.push(line);
|
|
490
586
|
break;
|
|
491
587
|
case Types.NAVIGATE:
|
|
@@ -498,7 +594,7 @@ const _generateCodeFromCommand = (step, elements, userData) => {
|
|
|
498
594
|
} else if (step.dataSource === "environment") {
|
|
499
595
|
input = `context.environment["_${step.dataKey}"]`;
|
|
500
596
|
}
|
|
501
|
-
line = `await context.web.goto(${input}, this);`;
|
|
597
|
+
line = `await context.web.goto(${input}, this, ${serializeOptions(options)});`;
|
|
502
598
|
codeLines.push(line);
|
|
503
599
|
break;
|
|
504
600
|
case Types.VERIFY_PAGE_PATH:
|
|
@@ -507,7 +603,7 @@ const _generateCodeFromCommand = (step, elements, userData) => {
|
|
|
507
603
|
if (step.dataSource === "userData" || step.dataSource === "parameters") {
|
|
508
604
|
input = "_" + step.dataKey;
|
|
509
605
|
}
|
|
510
|
-
line += `${input},
|
|
606
|
+
line += `${input}, ${serializeOptions(options)}, this);`;
|
|
511
607
|
comment = `// Verify page path "${input}"`;
|
|
512
608
|
codeLines.push(escapeNonPrintables(comment));
|
|
513
609
|
codeLines.push(line);
|
|
@@ -518,7 +614,7 @@ const _generateCodeFromCommand = (step, elements, userData) => {
|
|
|
518
614
|
if (step.dataSource === "userData" || step.dataSource === "parameters") {
|
|
519
615
|
input = "_" + step.dataKey;
|
|
520
616
|
}
|
|
521
|
-
line += `${input},
|
|
617
|
+
line += `${input}, ${serializeOptions(options)}, this);`;
|
|
522
618
|
comment = `// Verify page title "${input}"`;
|
|
523
619
|
codeLines.push(escapeNonPrintables(comment));
|
|
524
620
|
codeLines.push(line);
|
|
@@ -528,13 +624,13 @@ const _generateCodeFromCommand = (step, elements, userData) => {
|
|
|
528
624
|
if (step.dataSource === "userData" || step.dataSource === "parameters") {
|
|
529
625
|
input = "_" + step.dataKey;
|
|
530
626
|
}
|
|
531
|
-
line = `await context.web.type(${input}, _params,
|
|
627
|
+
line = `await context.web.type(${input}, _params, ${serializeOptions(options)}, this);`;
|
|
532
628
|
comment = `// Type "${input}"`;
|
|
533
629
|
codeLines.push(escapeNonPrintables(comment));
|
|
534
630
|
codeLines.push(line);
|
|
535
631
|
break;
|
|
536
632
|
case Types.HOVER:
|
|
537
|
-
line = `await context.web.hover(elements["${elementIdentifier}"], _params,
|
|
633
|
+
line = `await context.web.hover(elements["${elementIdentifier}"], _params, ${serializeOptions(options)}, this);`;
|
|
538
634
|
if (element_name) {
|
|
539
635
|
comment = `// Hover ${element_name}`;
|
|
540
636
|
codeLines.push(escapeNonPrintables(comment));
|
|
@@ -575,13 +671,15 @@ const _generateCodeFromCommand = (step, elements, userData) => {
|
|
|
575
671
|
case Types.CHECK:
|
|
576
672
|
comment = `// Check ${element_name}`;
|
|
577
673
|
codeLines.push(escapeNonPrintables(comment));
|
|
578
|
-
line = `await context.web.setCheck(elements["${elementIdentifier}"], ${step.check}, _params,
|
|
674
|
+
line = `await context.web.setCheck(elements["${elementIdentifier}"], ${step.check}, _params, ${serializeOptions(options)}, this);`;
|
|
579
675
|
codeLines.push(line);
|
|
580
676
|
break;
|
|
581
677
|
case Types.PRESS:
|
|
582
678
|
comment = `// Press ${step.key}`;
|
|
583
679
|
codeLines.push(escapeNonPrintables(comment));
|
|
584
|
-
|
|
680
|
+
options = options ?? {};
|
|
681
|
+
options.press = true;
|
|
682
|
+
line = `await context.web.clickType( elements["${elementIdentifier}"] ,"${step.key}",null, _params, ${serializeOptions(options)}, this);`;
|
|
585
683
|
codeLines.push(line);
|
|
586
684
|
break;
|
|
587
685
|
case Types.CONTEXT_CLICK:
|
|
@@ -593,7 +691,9 @@ const _generateCodeFromCommand = (step, elements, userData) => {
|
|
|
593
691
|
if (step.dataSource === "userData" || step.dataSource === "parameters") {
|
|
594
692
|
input = "_" + step.dataKey;
|
|
595
693
|
}
|
|
596
|
-
|
|
694
|
+
options = options ?? {};
|
|
695
|
+
// options.context = input;
|
|
696
|
+
line = `await context.web.click(elements["${elementIdentifier}"], _params, ${serializeOptions(options, input)}, this);`;
|
|
597
697
|
codeLines.push(line);
|
|
598
698
|
break;
|
|
599
699
|
case 2:
|
|
@@ -603,7 +703,10 @@ const _generateCodeFromCommand = (step, elements, userData) => {
|
|
|
603
703
|
if (step.dataSource === "userData" || step.dataSource === "parameters") {
|
|
604
704
|
input = "_" + step.dataKey;
|
|
605
705
|
}
|
|
606
|
-
|
|
706
|
+
options = options ?? {};
|
|
707
|
+
// options.context = input;
|
|
708
|
+
options.clickCount = 2;
|
|
709
|
+
line = `await context.web.click(elements["${elementIdentifier}"], _params, ${serializeOptions(options, input)}, this);`;
|
|
607
710
|
codeLines.push(line);
|
|
608
711
|
break;
|
|
609
712
|
default:
|
|
@@ -613,7 +716,9 @@ const _generateCodeFromCommand = (step, elements, userData) => {
|
|
|
613
716
|
if (step.dataSource === "userData" || step.dataSource === "parameters") {
|
|
614
717
|
input = "_" + step.dataKey;
|
|
615
718
|
}
|
|
616
|
-
|
|
719
|
+
options = options ?? {};
|
|
720
|
+
// options.context = input;
|
|
721
|
+
line = `await context.web.click(elements["${elementIdentifier}"], _params, ${serializeOptions(options, input)}, this);`;
|
|
617
722
|
codeLines.push(line);
|
|
618
723
|
break;
|
|
619
724
|
}
|
|
@@ -638,24 +743,25 @@ const _generateCodeFromCommand = (step, elements, userData) => {
|
|
|
638
743
|
if (step.dataSource === "userData" || step.dataSource === "parameters") {
|
|
639
744
|
input = "_" + step.dataKey;
|
|
640
745
|
}
|
|
641
|
-
line += `"${step.parameters[0]}", ${input}, _params,
|
|
746
|
+
line += `"${step.parameters[0]}", ${input}, _params, ${serializeOptions(options)}, this);`;
|
|
642
747
|
codeLines.push(line);
|
|
643
748
|
break;
|
|
644
749
|
}
|
|
645
750
|
case Types.VERIFY_PROPERTY: {
|
|
646
751
|
line = `await context.web.verifyProperty(elements["${elementIdentifier}"], `;
|
|
647
|
-
input = "_param_0"
|
|
752
|
+
input = step.valueInStepText ? "_param_0" : `"${escapeNonPrintables(step.parameters[1].replaceAll('"', '\\"'))}"`;
|
|
648
753
|
if (step.dataSource === "userData" || step.dataSource === "parameters") {
|
|
649
754
|
input = "_" + step.dataKey;
|
|
650
755
|
}
|
|
651
|
-
line += `"${step.parameters[0]}", ${input}, _params,
|
|
756
|
+
line += `"${step.parameters[0]}", ${input}, _params, ${serializeOptions(options)}, this);`;
|
|
652
757
|
codeLines.push(line);
|
|
653
758
|
break;
|
|
654
759
|
}
|
|
655
760
|
case Types.CONDITIONAL_WAIT: {
|
|
656
761
|
line = `await context.web.conditionalWait(elements["${elementIdentifier}"], `;
|
|
657
|
-
|
|
658
|
-
|
|
762
|
+
const timeout = Number(step.parameters[0]) / 1000;
|
|
763
|
+
input = step.valueInStepText ? "_param_0" : `"${escapeNonPrintables(String(timeout))}"`;
|
|
764
|
+
line += `"${step.parameters[1]}", ${input}, _params, ${serializeOptions(options)}, this);`;
|
|
659
765
|
codeLines.push(line);
|
|
660
766
|
break;
|
|
661
767
|
}
|
|
@@ -666,7 +772,7 @@ const _generateCodeFromCommand = (step, elements, userData) => {
|
|
|
666
772
|
if (step.dataSource === "userData" || step.dataSource === "parameters") {
|
|
667
773
|
input = "_" + step.dataKey;
|
|
668
774
|
}
|
|
669
|
-
line += `${input}, _params,
|
|
775
|
+
line += `${input}, _params, ${serializeOptions(options)}, this);`;
|
|
670
776
|
if (element_name) {
|
|
671
777
|
comment = `// Set ${element_name} to ${input}`;
|
|
672
778
|
codeLines.push(escapeNonPrintables(comment));
|
|
@@ -674,6 +780,7 @@ const _generateCodeFromCommand = (step, elements, userData) => {
|
|
|
674
780
|
codeLines.push(line);
|
|
675
781
|
break;
|
|
676
782
|
}
|
|
783
|
+
|
|
677
784
|
case Types.CLICK_SIMPLE:
|
|
678
785
|
case Types.FILL_SIMPLE:
|
|
679
786
|
// no code need to be added
|
|
@@ -684,22 +791,6 @@ const _generateCodeFromCommand = (step, elements, userData) => {
|
|
|
684
791
|
return { codeLines, elements: elementsChanged ? elements : null, elementIdentifier, allStrategyLocators };
|
|
685
792
|
};
|
|
686
793
|
|
|
687
|
-
/**
|
|
688
|
-
* Generates a report command based on the given position.
|
|
689
|
-
* @param {"start"|"end"} position
|
|
690
|
-
*/
|
|
691
|
-
const generateReportCommand = (position, cmdId) => {
|
|
692
|
-
const codeLines = [];
|
|
693
|
-
if (position === "start") {
|
|
694
|
-
const line = `await context.web.addCommandToReport("${cmdId}", "PASSED", '{"status":"start","cmdId":"${cmdId}"}', {type:"cmdReport"},this);`;
|
|
695
|
-
codeLines.push(line);
|
|
696
|
-
} else if (position === "end") {
|
|
697
|
-
const line = `await context.web.addCommandToReport("${cmdId}", "PASSED", '{"status":"end","cmdId":"${cmdId}"}', {type:"cmdReport"},this);`;
|
|
698
|
-
codeLines.push(line);
|
|
699
|
-
}
|
|
700
|
-
return codeLines;
|
|
701
|
-
};
|
|
702
|
-
|
|
703
794
|
const generateCode = (recording, codePage, userData, projectDir, methodName) => {
|
|
704
795
|
const stepsDefinitions = new StepsDefinitions(projectDir);
|
|
705
796
|
stepsDefinitions.load(false);
|
|
@@ -722,12 +813,10 @@ const generateCode = (recording, codePage, userData, projectDir, methodName) =>
|
|
|
722
813
|
codePage = new CodePage(mjsFullPath);
|
|
723
814
|
codePage.generateModel();
|
|
724
815
|
}
|
|
725
|
-
//console.log("step found");
|
|
726
816
|
}
|
|
727
817
|
let elements = {};
|
|
728
818
|
if (!codePage) {
|
|
729
|
-
socketLogger.info("CodePage is null");
|
|
730
|
-
console.log("codePage is null");
|
|
819
|
+
socketLogger.info("CodePage is null", undefined, "generateCode");
|
|
731
820
|
} else {
|
|
732
821
|
elements = codePage.getVariableDeclarationAsObject("elements");
|
|
733
822
|
}
|
|
@@ -741,6 +830,7 @@ const generateCode = (recording, codePage, userData, projectDir, methodName) =>
|
|
|
741
830
|
if (recordingStep.type === Types.COMPLETE) {
|
|
742
831
|
return;
|
|
743
832
|
}
|
|
833
|
+
socketLogger.info(`Generating code for step: ${recordingStep.type}`, undefined, "generateCode");
|
|
744
834
|
|
|
745
835
|
// if (process.env.TEMP_RUN === "true") {
|
|
746
836
|
// codeLines.push(...generateReportCommand("start", recordingStep.cmdId));
|
|
@@ -752,9 +842,11 @@ const generateCode = (recording, codePage, userData, projectDir, methodName) =>
|
|
|
752
842
|
// codeLines.push(...generateReportCommand("end", recordingStep.cmdId));
|
|
753
843
|
// }
|
|
754
844
|
if (result.elements) {
|
|
845
|
+
socketLogger.info(`Updating elements with ${Object.keys(result.elements)}`, undefined, "generateCode");
|
|
755
846
|
elements = result.elements;
|
|
756
847
|
}
|
|
757
848
|
if (result.elementIdentifier) {
|
|
849
|
+
socketLogger.info(`Adding locator metadata for ${result.elementIdentifier}`, undefined, "generateCode");
|
|
758
850
|
locatorsMetadata[result.elementIdentifier] = result.allStrategyLocators;
|
|
759
851
|
}
|
|
760
852
|
});
|
|
@@ -768,7 +860,11 @@ const generateCode = (recording, codePage, userData, projectDir, methodName) =>
|
|
|
768
860
|
locatorsMetadata,
|
|
769
861
|
};
|
|
770
862
|
};
|
|
771
|
-
const generatePageName = (url) => {
|
|
863
|
+
const generatePageName = (url, isUtilStep) => {
|
|
864
|
+
if (isUtilStep) {
|
|
865
|
+
return "renamed_util";
|
|
866
|
+
}
|
|
867
|
+
|
|
772
868
|
try {
|
|
773
869
|
let pathname = url;
|
|
774
870
|
try {
|
|
@@ -791,8 +887,8 @@ const generatePageName = (url) => {
|
|
|
791
887
|
}
|
|
792
888
|
// join by _
|
|
793
889
|
return lowerCaseParts.join("_");
|
|
794
|
-
} catch
|
|
890
|
+
} catch {
|
|
795
891
|
return "default";
|
|
796
892
|
}
|
|
797
893
|
};
|
|
798
|
-
export { generateCode, generatePageName };
|
|
894
|
+
export { generateCode, generatePageName, _generateCodeFromCommand };
|