automation_model 1.0.558-dev → 1.0.558-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.
@@ -0,0 +1 @@
1
+ {"version":3,"file":"table_helper.js","sourceRoot":"","sources":["../../src/table_helper.ts"],"names":[],"mappings":"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"}
@@ -2,8 +2,10 @@ import { BrowserContext, Page, Browser as PlaywrightBrowser } from "playwright";
2
2
  import { Environment } from "./environment.js";
3
3
  import { StableBrowser } from "./stable_browser.js";
4
4
  import { Api } from "./api.js";
5
+ import { InitScripts } from "./generation_scripts.js";
5
6
  declare class TestContext {
6
7
  stable: StableBrowser | null;
8
+ web: StableBrowser | null;
7
9
  browser: PlaywrightBrowser | null;
8
10
  playContext: BrowserContext | null;
9
11
  page: Page | null;
@@ -14,6 +16,7 @@ declare class TestContext {
14
16
  headless: boolean;
15
17
  browserName: string | null;
16
18
  browserObject: any;
19
+ initScripts: InitScripts | null;
17
20
  constructor();
18
21
  }
19
22
  export { TestContext };
@@ -1,5 +1,6 @@
1
1
  class TestContext {
2
2
  stable = null;
3
+ web = null;
3
4
  browser = null;
4
5
  playContext = null;
5
6
  page = null;
@@ -10,6 +11,7 @@ class TestContext {
10
11
  headless = false;
11
12
  browserName = null;
12
13
  browserObject = null;
14
+ initScripts = null;
13
15
  constructor() { }
14
16
  }
15
17
  export { TestContext };
@@ -1 +1 @@
1
- {"version":3,"file":"test_context.js","sourceRoot":"","sources":["../../src/test_context.ts"],"names":[],"mappings":"AAKA,MAAM,WAAW;IACf,MAAM,GAAyB,IAAI,CAAC;IACpC,OAAO,GAA6B,IAAI,CAAC;IACzC,WAAW,GAA0B,IAAI,CAAC;IAC1C,IAAI,GAAgB,IAAI,CAAC;IACzB,WAAW,GAAuB,IAAI,CAAC;IACvC,YAAY,GAAkB,IAAI,CAAC;IACnC,GAAG,GAAe,IAAI,CAAC;IACvB,QAAQ,GAAG,KAAK,CAAC;IACjB,QAAQ,GAAG,KAAK,CAAC;IACjB,WAAW,GAAkB,IAAI,CAAC;IAClC,aAAa,GAAQ,IAAI,CAAC;IAC1B,gBAAe,CAAC;CACjB;AACD,OAAO,EAAE,WAAW,EAAE,CAAC"}
1
+ {"version":3,"file":"test_context.js","sourceRoot":"","sources":["../../src/test_context.ts"],"names":[],"mappings":"AAMA,MAAM,WAAW;IACf,MAAM,GAAyB,IAAI,CAAC;IACpC,GAAG,GAAyB,IAAI,CAAC;IACjC,OAAO,GAA6B,IAAI,CAAC;IACzC,WAAW,GAA0B,IAAI,CAAC;IAC1C,IAAI,GAAgB,IAAI,CAAC;IACzB,WAAW,GAAuB,IAAI,CAAC;IACvC,YAAY,GAAkB,IAAI,CAAC;IACnC,GAAG,GAAe,IAAI,CAAC;IACvB,QAAQ,GAAG,KAAK,CAAC;IACjB,QAAQ,GAAG,KAAK,CAAC;IACjB,WAAW,GAAkB,IAAI,CAAC;IAClC,aAAa,GAAQ,IAAI,CAAC;IAC1B,WAAW,GAAuB,IAAI,CAAC;IACvC,gBAAe,CAAC;CACjB;AACD,OAAO,EAAE,WAAW,EAAE,CAAC"}
package/lib/utils.d.ts CHANGED
@@ -1,5 +1,21 @@
1
1
  declare function encrypt(text: string, key?: string | null): string;
2
2
  declare function decrypt(encryptedText: string, key?: string | null, totpWait?: boolean): Promise<string>;
3
- declare function replaceWithLocalTestData(value: string, world: any, _decrypt?: boolean, totpWait?: boolean, context?: any, stable?: any): Promise<string>;
3
+ export declare function testForRegex(text: string): boolean;
4
+ declare function _convertToRegexQuery(text: string, isRegex: boolean, fullMatch: boolean, ignoreCase: boolean): string;
5
+ declare function _getDataFile(world?: any, context?: any, web?: any): string;
6
+ declare function replaceWithLocalTestData(value: string, world: any, _decrypt?: boolean, totpWait?: boolean, context?: any, web?: any): Promise<string>;
4
7
  declare function maskValue(value: string): string;
5
- export { encrypt, decrypt, replaceWithLocalTestData, maskValue };
8
+ declare function _copyContext(from: any, to: any): void;
9
+ declare function scrollPageToLoadLazyElements(page: any): Promise<void>;
10
+ type Params = Record<string, string>;
11
+ declare function _fixUsingParams(text: string, _params: Params): string;
12
+ declare function getWebLogFile(logFolder: string): string;
13
+ declare function _fixLocatorUsingParams(locator: any, _params: Params): any;
14
+ declare function _isObject(value: any): any;
15
+ declare function scanAndManipulate(currentObj: any, _params: Params): void;
16
+ declare function extractStepExampleParameters(step: any): any;
17
+ export declare function performAction(action: string, element: any, options: any, web: any, state: any, _params: Params): Promise<void>;
18
+ declare const KEYBOARD_EVENTS: string[];
19
+ declare function unEscapeString(str: string): string;
20
+ declare function _getServerUrl(): string;
21
+ export { encrypt, decrypt, replaceWithLocalTestData, maskValue, _copyContext, scrollPageToLoadLazyElements, _fixUsingParams, getWebLogFile, _fixLocatorUsingParams, _isObject, scanAndManipulate, KEYBOARD_EVENTS, unEscapeString, Params, _getServerUrl, _convertToRegexQuery, _getDataFile, extractStepExampleParameters };
package/lib/utils.js CHANGED
@@ -1,8 +1,8 @@
1
1
  import CryptoJS from "crypto-js";
2
- import objectPath from "object-path";
3
2
  import path from "path";
4
3
  import { TOTP } from "totp-generator";
5
4
  import fs from "fs";
5
+ import axios from "axios";
6
6
  // Function to encrypt a string
7
7
  function encrypt(text, key = null) {
8
8
  if (!key) {
@@ -38,6 +38,86 @@ async function decrypt(encryptedText, key = null, totpWait = true) {
38
38
  const bytes = CryptoJS.AES.decrypt(encryptedText, key);
39
39
  return bytes.toString(CryptoJS.enc.Utf8);
40
40
  }
41
+ export function testForRegex(text) {
42
+ const regexEndPattern = /\/([gimuy]*)$/;
43
+ if (text.startsWith("/")) {
44
+ const match = regexEndPattern.test(text);
45
+ if (match) {
46
+ try {
47
+ const regex = new RegExp(text.substring(1, text.lastIndexOf("/")), text.match(regexEndPattern)[1]);
48
+ return true;
49
+ }
50
+ catch {
51
+ // not regex
52
+ }
53
+ }
54
+ }
55
+ return false;
56
+ }
57
+ function _convertToRegexQuery(text, isRegex, fullMatch, ignoreCase) {
58
+ let query = "internal:text=/";
59
+ let queryEnd = "/";
60
+ let pattern = "";
61
+ const regexEndPattern = /\/([gimuy]*)$/;
62
+ if (text.startsWith("/")) {
63
+ const match = regexEndPattern.test(text);
64
+ if (match) {
65
+ try {
66
+ const regex = new RegExp(text.substring(1, text.lastIndexOf("/")), text.match(regexEndPattern)[1]);
67
+ text = text.replace(/"/g, '\\"');
68
+ return "internal:text=" + text;
69
+ }
70
+ catch {
71
+ // not regex
72
+ }
73
+ }
74
+ }
75
+ if (isRegex) {
76
+ pattern = text;
77
+ }
78
+ else {
79
+ // first remove \n then split the text by any white space,
80
+ let parts = text.replace(/\\n/g, "").split(/\s+/);
81
+ // escape regex split part
82
+ parts = parts.map((part) => escapeRegex(part));
83
+ pattern = parts.join("\\s*");
84
+ }
85
+ if (fullMatch) {
86
+ pattern = "^\\s*" + pattern + "\\s*$";
87
+ }
88
+ if (ignoreCase) {
89
+ queryEnd += "i";
90
+ }
91
+ return query + pattern + queryEnd;
92
+ }
93
+ function escapeRegex(str) {
94
+ // Special regex characters that need to be escaped
95
+ const specialChars = [
96
+ "/",
97
+ ".",
98
+ "*",
99
+ "+",
100
+ "?",
101
+ "^",
102
+ "$",
103
+ "(",
104
+ ")",
105
+ "[",
106
+ "]",
107
+ "{",
108
+ "}",
109
+ "|",
110
+ "\\",
111
+ "-",
112
+ "'",
113
+ '"',
114
+ ">", // added to avoid confusion with pw selectorsxw
115
+ ];
116
+ // Create a regex that will match all special characters
117
+ const escapedRegex = new RegExp(specialChars.map((char) => `\\${char}`).join("|"), "g");
118
+ // Escape special characters by prefixing them with a backslash
119
+ return str.replace(escapedRegex, "\\$&");
120
+ }
41
121
  function _findKey() {
42
122
  if (process.env.PROJECT_ID) {
43
123
  return process.env.PROJECT_ID;
@@ -50,53 +130,156 @@ function _findKey() {
50
130
  // extract the base folder name
51
131
  return path.basename(folder);
52
132
  }
53
- function _getDataFile(world = null, context = null, stable = null) {
133
+ function _getDataFile(world = null, context = null, web = null) {
134
+ let dataFile = null;
135
+ if (world && world.reportFolder) {
136
+ dataFile = path.join(world.reportFolder, "data.json");
137
+ }
138
+ else if (web && web.reportFolder) {
139
+ dataFile = path.join(web.reportFolder, "data.json");
140
+ }
141
+ else if (context && context.reportFolder) {
142
+ dataFile = path.join(context.reportFolder, "data.json");
143
+ }
144
+ else {
145
+ dataFile = "data.json";
146
+ }
147
+ return dataFile;
148
+ }
149
+ function _getTestDataFile(world = null, context = null, web = null) {
54
150
  let dataFile = null;
55
151
  if (world && world.reportFolder) {
56
152
  dataFile = path.join(world.reportFolder, "data.json");
57
153
  }
58
- else if (stable && stable.reportFolder) {
59
- dataFile = path.join(stable.reportFolder, "data.json");
154
+ else if (web && web.reportFolder) {
155
+ dataFile = path.join(web.reportFolder, "data.json");
60
156
  }
61
157
  else if (context && context.reportFolder) {
62
158
  dataFile = path.join(context.reportFolder, "data.json");
63
159
  }
160
+ else if (fs.existsSync(path.join("data", "data.json"))) {
161
+ dataFile = path.join("data", "data.json");
162
+ }
64
163
  else {
65
164
  dataFile = "data.json";
66
165
  }
67
166
  return dataFile;
68
167
  }
69
- function _getTestData(world = null, context = null, stable = null) {
70
- const dataFile = _getDataFile(world, context, stable);
168
+ function _getTestData(world = null, context = null, web = null) {
169
+ const dataFile = _getTestDataFile(world, context, web);
71
170
  let data = {};
72
171
  if (fs.existsSync(dataFile)) {
73
172
  data = JSON.parse(fs.readFileSync(dataFile, "utf8"));
74
173
  }
75
174
  return data;
76
175
  }
77
- async function replaceWithLocalTestData(value, world, _decrypt = true, totpWait = true, context = null, stable = null) {
176
+ async function replaceWithLocalTestData(value, world, _decrypt = true, totpWait = true, context = null, web = null) {
78
177
  if (!value) {
79
178
  return value;
80
179
  }
180
+ let env = "";
181
+ if (context && context.environment) {
182
+ env = context.environment.name;
183
+ }
81
184
  // find all the accurance of {{(.*?)}} and replace with the value
82
185
  let regex = /{{(.*?)}}/g;
83
186
  let matches = value.match(regex);
84
187
  if (matches) {
85
- const testData = _getTestData(world, context, stable);
188
+ const testData = _getTestData(world, context, web);
86
189
  for (let i = 0; i < matches.length; i++) {
87
190
  let match = matches[i];
88
191
  let key = match.substring(2, match.length - 2);
89
- let newValue = objectPath.get(testData, key, null);
90
- if (newValue !== null) {
91
- value = value.replace(match, newValue);
192
+ if (key && key.trim().startsWith("date:")) {
193
+ const dateQuery = key.substring(5);
194
+ const parts = dateQuery.split(">>");
195
+ const returnTemplate = parts[1] || null;
196
+ let serviceUrl = _getServerUrl();
197
+ const config = {
198
+ method: "post",
199
+ url: `${serviceUrl}/api/runs/find-date/find`,
200
+ headers: {
201
+ "x-source": "true",
202
+ "Content-Type": "application/json",
203
+ Authorization: `Bearer ${process.env.TOKEN}`,
204
+ },
205
+ data: JSON.stringify({
206
+ value: parts[0],
207
+ }),
208
+ };
209
+ let result = await axios.request(config);
210
+ //console.log(JSON.stringify(frameDump[0]));
211
+ if (result.status !== 200 || !result.data || result.data.status !== true || !result.data.result) {
212
+ console.error("Failed to find date");
213
+ throw new Error("Failed to find date");
214
+ }
215
+ value = formatDate(result.data.result, returnTemplate);
216
+ }
217
+ else {
218
+ let newValue = await replaceTestDataValue(env, key, testData);
219
+ if (newValue !== null) {
220
+ value = value.replace(match, newValue);
221
+ }
222
+ else {
223
+ newValue = await replaceTestDataValue("*", key, testData);
224
+ if (newValue !== null) {
225
+ value = value.replace(match, newValue);
226
+ }
227
+ }
92
228
  }
93
229
  }
94
230
  }
95
231
  if ((value.startsWith("secret:") || value.startsWith("totp:") || value.startsWith("mask:")) && _decrypt) {
96
232
  return await decrypt(value, null, totpWait);
97
233
  }
234
+ // check if the value is ${}
235
+ if (value.startsWith("${") && value.endsWith("}")) {
236
+ value = evaluateString(value, context.examplesRow);
237
+ }
98
238
  return value;
99
239
  }
240
+ async function replaceTestDataValue(env, key, testData) {
241
+ const dataArray = testData[env];
242
+ if (!dataArray) {
243
+ return null;
244
+ }
245
+ for (const obj of dataArray) {
246
+ if (obj.key !== key) {
247
+ continue;
248
+ }
249
+ if (obj.DataType === "secret") {
250
+ return await decrypt(`secret:${obj.value}`, null);
251
+ }
252
+ return obj.value;
253
+ }
254
+ return null;
255
+ }
256
+ function evaluateString(template, parameters) {
257
+ if (!parameters) {
258
+ parameters = {};
259
+ }
260
+ try {
261
+ return new Function(...Object.keys(parameters), `return \`${template}\`;`)(...Object.values(parameters));
262
+ }
263
+ catch (e) {
264
+ console.error(e);
265
+ return template;
266
+ }
267
+ }
268
+ function formatDate(dateStr, format) {
269
+ if (!format) {
270
+ return dateStr;
271
+ }
272
+ // Split the input date string
273
+ const [dd, mm, yyyy] = dateStr.split("-");
274
+ // Define replacements
275
+ const replacements = {
276
+ dd: dd,
277
+ mm: mm,
278
+ yyyy: yyyy,
279
+ };
280
+ // Replace format placeholders with actual values
281
+ return format.replace(/dd|mm|yyyy/g, (match) => replacements[match]);
282
+ }
100
283
  function maskValue(value) {
101
284
  if (!value) {
102
285
  return value;
@@ -112,7 +295,351 @@ function maskValue(value) {
112
295
  }
113
296
  return value;
114
297
  }
115
- // console.log(encrypt("Hello, World!", null));
116
- // console.log(decrypt("U2FsdGVkX1+6mavadgkMgJPIhR3IO1pDkx36TjTyoyE=", null));
117
- export { encrypt, decrypt, replaceWithLocalTestData, maskValue };
298
+ function _copyContext(from, to) {
299
+ to.browser = from.browser;
300
+ to.page = from.page;
301
+ to.context = from.context;
302
+ }
303
+ async function scrollPageToLoadLazyElements(page) {
304
+ let lastHeight = await page.evaluate(() => document.body.scrollHeight);
305
+ let retry = 0;
306
+ while (true) {
307
+ await page.evaluate(() => window.scrollBy(0, window.innerHeight));
308
+ await new Promise((resolve) => setTimeout(resolve, 1000));
309
+ let newHeight = await page.evaluate(() => document.body.scrollHeight);
310
+ if (newHeight === lastHeight) {
311
+ break;
312
+ }
313
+ lastHeight = newHeight;
314
+ retry++;
315
+ if (retry > 10) {
316
+ break;
317
+ }
318
+ }
319
+ await page.evaluate(() => window.scrollTo(0, 0));
320
+ }
321
+ function _fixUsingParams(text, _params) {
322
+ if (!_params || typeof text !== "string") {
323
+ return text;
324
+ }
325
+ for (let key in _params) {
326
+ let regValue = key;
327
+ if (key.startsWith("_")) {
328
+ // remove the _ prefix
329
+ regValue = key.substring(1);
330
+ }
331
+ text = text.replaceAll(new RegExp("{" + regValue + "}", "g"), _params[key]);
332
+ }
333
+ return text;
334
+ }
335
+ function getWebLogFile(logFolder) {
336
+ if (!fs.existsSync(logFolder)) {
337
+ fs.mkdirSync(logFolder, { recursive: true });
338
+ }
339
+ let nextIndex = 1;
340
+ while (fs.existsSync(path.join(logFolder, nextIndex.toString() + ".json"))) {
341
+ nextIndex++;
342
+ }
343
+ const fileName = nextIndex + ".json";
344
+ return path.join(logFolder, fileName);
345
+ }
346
+ function _fixLocatorUsingParams(locator, _params) {
347
+ // check if not null
348
+ if (!locator) {
349
+ return locator;
350
+ }
351
+ // clone the locator
352
+ locator = JSON.parse(JSON.stringify(locator));
353
+ scanAndManipulate(locator, _params);
354
+ return locator;
355
+ }
356
+ function _isObject(value) {
357
+ return value && typeof value === "object" && value.constructor === Object;
358
+ }
359
+ function scanAndManipulate(currentObj, _params) {
360
+ for (const key in currentObj) {
361
+ if (typeof currentObj[key] === "string") {
362
+ // Perform string manipulation
363
+ currentObj[key] = _fixUsingParams(currentObj[key], _params);
364
+ }
365
+ else if (_isObject(currentObj[key])) {
366
+ // Recursively scan nested objects
367
+ scanAndManipulate(currentObj[key], _params);
368
+ }
369
+ }
370
+ }
371
+ function extractStepExampleParameters(step) {
372
+ if (!step ||
373
+ !step.gherkinDocument ||
374
+ !step.pickle ||
375
+ !step.pickle.astNodeIds ||
376
+ !(step.pickle.astNodeIds.length > 1) ||
377
+ !step.gherkinDocument.feature ||
378
+ !step.gherkinDocument.feature.children) {
379
+ return {};
380
+ }
381
+ try {
382
+ const scenarioId = step.pickle.astNodeIds[0];
383
+ const exampleId = step.pickle.astNodeIds[1];
384
+ // find the scenario in the gherkin document
385
+ const scenario = step.gherkinDocument.feature.children.find((child) => child.scenario.id === scenarioId).scenario;
386
+ if (!scenario || !scenario.examples || !scenario.examples[0].tableBody) {
387
+ return {};
388
+ }
389
+ // find the table body in the examples
390
+ const row = scenario.examples[0].tableBody.find((r) => r.id === exampleId);
391
+ if (!row) {
392
+ return {};
393
+ }
394
+ // extract the cells values (row.cells.value) into an array
395
+ const values = row.cells.map((cell) => cell.value);
396
+ // extract the table headers keys (scenario.examples.tableHeader.cells.value) into an array
397
+ const keys = scenario.examples[0].tableHeader.cells.map((cell) => cell.value);
398
+ // create a dictionary of the keys and values
399
+ const params = {};
400
+ for (let i = 0; i < keys.length; i++) {
401
+ params[keys[i]] = values[i];
402
+ }
403
+ return params;
404
+ }
405
+ catch (e) {
406
+ console.error(e);
407
+ return {};
408
+ }
409
+ }
410
+ export async function performAction(action, element, options, web, state, _params) {
411
+ let usedOptions;
412
+ if (!options) {
413
+ options = {};
414
+ }
415
+ if (!element) {
416
+ throw new Error("Element not found");
417
+ }
418
+ switch (action) {
419
+ case "click":
420
+ // copy any of the following options to usedOptions: button, clickCount, delay, modifiers, force, position, trial
421
+ usedOptions = ["button", "clickCount", "delay", "modifiers", "force", "position", "trial", "timeout"].reduce((acc, key) => {
422
+ if (options[key]) {
423
+ acc[key] = options[key];
424
+ }
425
+ return acc;
426
+ }, {});
427
+ if (!usedOptions.timeout) {
428
+ usedOptions.timeout = 10000;
429
+ if (usedOptions.position) {
430
+ usedOptions.timeout = 1000;
431
+ }
432
+ }
433
+ try {
434
+ await element.click(usedOptions);
435
+ }
436
+ catch (e) {
437
+ if (usedOptions.position) {
438
+ // find the element bounding box
439
+ const rect = await element.boundingBox();
440
+ // calculate the x and y position
441
+ const x = rect.x + rect.width / 2 + (usedOptions.position.x || 0);
442
+ const y = rect.y + rect.height / 2 + (usedOptions.position.y || 0);
443
+ // click on the x and y position
444
+ await web.page.mouse.click(x, y);
445
+ }
446
+ else {
447
+ if (state && state.selectors) {
448
+ state.element = await web._locate(state.selectors, state.info, _params);
449
+ element = state.element;
450
+ }
451
+ await element.dispatchEvent("click");
452
+ }
453
+ }
454
+ break;
455
+ case "hover":
456
+ usedOptions = ["position", "trial", "timeout"].reduce((acc, key) => {
457
+ acc[key] = options[key];
458
+ return acc;
459
+ }, {});
460
+ try {
461
+ await element.hover(usedOptions);
462
+ await new Promise((resolve) => setTimeout(resolve, 1000));
463
+ }
464
+ catch (e) {
465
+ if (state && state.selectors) {
466
+ state.info.log += "hover failed, will try again" + "\n";
467
+ state.element = await web._locate(state.selectors, state.info, _params);
468
+ element = state.element;
469
+ }
470
+ usedOptions.timeout = 10000;
471
+ await element.hover(usedOptions);
472
+ await new Promise((resolve) => setTimeout(resolve, 1000));
473
+ }
474
+ break;
475
+ case "hover+click":
476
+ await performAction("hover", element, options, web, state, _params);
477
+ await performAction("click", element, options, web, state, _params);
478
+ break;
479
+ default:
480
+ throw new Error(`Action ${action} not supported`);
481
+ }
482
+ }
483
+ const KEYBOARD_EVENTS = [
484
+ "ALT",
485
+ "AltGraph",
486
+ "CapsLock",
487
+ "Control",
488
+ "Fn",
489
+ "FnLock",
490
+ "Hyper",
491
+ "Meta",
492
+ "NumLock",
493
+ "ScrollLock",
494
+ "Shift",
495
+ "Super",
496
+ "Symbol",
497
+ "SymbolLock",
498
+ "Enter",
499
+ "Tab",
500
+ "ArrowDown",
501
+ "ArrowLeft",
502
+ "ArrowRight",
503
+ "ArrowUp",
504
+ "End",
505
+ "Home",
506
+ "PageDown",
507
+ "PageUp",
508
+ "Backspace",
509
+ "Clear",
510
+ "Copy",
511
+ "CrSel",
512
+ "Cut",
513
+ "Delete",
514
+ "EraseEof",
515
+ "ExSel",
516
+ "Insert",
517
+ "Paste",
518
+ "Redo",
519
+ "Undo",
520
+ "Accept",
521
+ "Again",
522
+ "Attn",
523
+ "Cancel",
524
+ "ContextMenu",
525
+ "Escape",
526
+ "Execute",
527
+ "Find",
528
+ "Finish",
529
+ "Help",
530
+ "Pause",
531
+ "Play",
532
+ "Props",
533
+ "Select",
534
+ "ZoomIn",
535
+ "ZoomOut",
536
+ "BrightnessDown",
537
+ "BrightnessUp",
538
+ "Eject",
539
+ "LogOff",
540
+ "Power",
541
+ "PowerOff",
542
+ "PrintScreen",
543
+ "Hibernate",
544
+ "Standby",
545
+ "WakeUp",
546
+ "AllCandidates",
547
+ "Alphanumeric",
548
+ "CodeInput",
549
+ "Compose",
550
+ "Convert",
551
+ "Dead",
552
+ "FinalMode",
553
+ "GroupFirst",
554
+ "GroupLast",
555
+ "GroupNext",
556
+ "GroupPrevious",
557
+ "ModeChange",
558
+ "NextCandidate",
559
+ "NonConvert",
560
+ "PreviousCandidate",
561
+ "Process",
562
+ "SingleCandidate",
563
+ "HangulMode",
564
+ "HanjaMode",
565
+ "JunjaMode",
566
+ "Eisu",
567
+ "Hankaku",
568
+ "Hiragana",
569
+ "HiraganaKatakana",
570
+ "KanaMode",
571
+ "KanjiMode",
572
+ "Katakana",
573
+ "Romaji",
574
+ "Zenkaku",
575
+ "ZenkakuHanaku",
576
+ "F1",
577
+ "F2",
578
+ "F3",
579
+ "F4",
580
+ "F5",
581
+ "F6",
582
+ "F7",
583
+ "F8",
584
+ "F9",
585
+ "F10",
586
+ "F11",
587
+ "F12",
588
+ "Soft1",
589
+ "Soft2",
590
+ "Soft3",
591
+ "Soft4",
592
+ "ChannelDown",
593
+ "ChannelUp",
594
+ "Close",
595
+ "MailForward",
596
+ "MailReply",
597
+ "MailSend",
598
+ "MediaFastForward",
599
+ "MediaPause",
600
+ "MediaPlay",
601
+ "MediaPlayPause",
602
+ "MediaRecord",
603
+ "MediaRewind",
604
+ "MediaStop",
605
+ "MediaTrackNext",
606
+ "MediaTrackPrevious",
607
+ "AudioBalanceLeft",
608
+ "AudioBalanceRight",
609
+ "AudioBassBoostDown",
610
+ "AudioBassBoostToggle",
611
+ "AudioBassBoostUp",
612
+ "AudioFaderFront",
613
+ "AudioFaderRear",
614
+ "AudioSurroundModeNext",
615
+ "AudioTrebleDown",
616
+ "AudioTrebleUp",
617
+ "AudioVolumeDown",
618
+ "AudioVolumeMute",
619
+ "AudioVolumeUp",
620
+ "MicrophoneToggle",
621
+ "MicrophoneVolumeDown",
622
+ "MicrophoneVolumeMute",
623
+ "MicrophoneVolumeUp",
624
+ "TV",
625
+ "TV3DMode",
626
+ "TVAntennaCable",
627
+ "TVAudioDescription",
628
+ ];
629
+ function unEscapeString(str) {
630
+ const placeholder = "__NEWLINE__";
631
+ str = str.replace(new RegExp(placeholder, "g"), "\n");
632
+ return str;
633
+ }
634
+ function _getServerUrl() {
635
+ let serviceUrl = "https://api.blinq.io";
636
+ if (process.env.NODE_ENV_BLINQ === "dev") {
637
+ serviceUrl = "https://dev.api.blinq.io";
638
+ }
639
+ else if (process.env.NODE_ENV_BLINQ === "stage") {
640
+ serviceUrl = "https://stage.api.blinq.io";
641
+ }
642
+ return serviceUrl;
643
+ }
644
+ export { encrypt, decrypt, replaceWithLocalTestData, maskValue, _copyContext, scrollPageToLoadLazyElements, _fixUsingParams, getWebLogFile, _fixLocatorUsingParams, _isObject, scanAndManipulate, KEYBOARD_EVENTS, unEscapeString, _getServerUrl, _convertToRegexQuery, _getDataFile, extractStepExampleParameters };
118
645
  //# sourceMappingURL=utils.js.map