automation_model 1.0.597-dev → 1.0.598-dev
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/lib/command_common.d.ts +1 -1
- package/lib/command_common.js +28 -26
- package/lib/command_common.js.map +1 -1
- package/lib/stable_browser.d.ts +4 -5
- package/lib/stable_browser.js +177 -175
- package/lib/stable_browser.js.map +1 -1
- package/package.json +1 -1
package/lib/stable_browser.js
CHANGED
|
@@ -7,6 +7,7 @@ import path from "path";
|
|
|
7
7
|
import reg_parser from "regex-parser";
|
|
8
8
|
import { findDateAlternatives, findNumberAlternatives } from "./analyze_helper.js";
|
|
9
9
|
import { getDateTimeValue } from "./date_time.js";
|
|
10
|
+
import drawRectangle from "./drawRect.js";
|
|
10
11
|
//import { closeUnexpectedPopups } from "./popups.js";
|
|
11
12
|
import { getTableCells, getTableData } from "./table_analyze.js";
|
|
12
13
|
import { _convertToRegexQuery, _copyContext, _fixLocatorUsingParams, _fixUsingParams, _getServerUrl, extractStepExampleParameters, KEYBOARD_EVENTS, maskValue, replaceWithLocalTestData, scrollPageToLoadLazyElements, unEscapeString, } from "./utils.js";
|
|
@@ -52,6 +53,9 @@ export const Types = {
|
|
|
52
53
|
VERIFY_TEXT_WITH_RELATION: "verify_text_with_relation",
|
|
53
54
|
};
|
|
54
55
|
export const apps = {};
|
|
56
|
+
const formatElementName = (elementName) => {
|
|
57
|
+
return elementName ? JSON.stringify(elementName) : "element";
|
|
58
|
+
};
|
|
55
59
|
class StableBrowser {
|
|
56
60
|
browser;
|
|
57
61
|
page;
|
|
@@ -252,7 +256,7 @@ class StableBrowser {
|
|
|
252
256
|
highlight: false,
|
|
253
257
|
};
|
|
254
258
|
try {
|
|
255
|
-
await _preCommand(state, this
|
|
259
|
+
await _preCommand(state, this);
|
|
256
260
|
await this.page.goto(url, {
|
|
257
261
|
timeout: 60000,
|
|
258
262
|
});
|
|
@@ -373,7 +377,7 @@ class StableBrowser {
|
|
|
373
377
|
}
|
|
374
378
|
return { elementCount: tagCount, randomToken };
|
|
375
379
|
}
|
|
376
|
-
async _collectLocatorInformation(selectorHierarchy, index = 0, scope, foundLocators, _params, info, visibleOnly = true, allowDisabled = false) {
|
|
380
|
+
async _collectLocatorInformation(selectorHierarchy, index = 0, scope, foundLocators, _params, info, visibleOnly = true, allowDisabled = false, element_name = null) {
|
|
377
381
|
if (!info) {
|
|
378
382
|
info = {};
|
|
379
383
|
}
|
|
@@ -400,7 +404,7 @@ class StableBrowser {
|
|
|
400
404
|
let locatorString = await this._locateElmentByTextClimbCss(scope, replacedText, locatorSearch.climb, locatorSearch.css, _params);
|
|
401
405
|
if (!locatorString) {
|
|
402
406
|
info.failCause.textNotFound = true;
|
|
403
|
-
info.failCause.lastError =
|
|
407
|
+
info.failCause.lastError = `failed to locate ${formatElementName(element_name)} by text: ${locatorSearch.text}`;
|
|
404
408
|
return;
|
|
405
409
|
}
|
|
406
410
|
locator = await this._getLocator({ css: locatorString }, scope, _params);
|
|
@@ -410,7 +414,7 @@ class StableBrowser {
|
|
|
410
414
|
let result = await this._locateElementByText(scope, text, locatorSearch.tag, false, locatorSearch.partial === true, true, _params);
|
|
411
415
|
if (result.elementCount === 0) {
|
|
412
416
|
info.failCause.textNotFound = true;
|
|
413
|
-
info.failCause.lastError =
|
|
417
|
+
info.failCause.lastError = `failed to locate ${formatElementName(element_name)} by text: ${text}`;
|
|
414
418
|
return;
|
|
415
419
|
}
|
|
416
420
|
locatorSearch.css = "[data-blinq-id-" + result.randomToken + "]";
|
|
@@ -462,11 +466,11 @@ class StableBrowser {
|
|
|
462
466
|
info.printMessages = {};
|
|
463
467
|
}
|
|
464
468
|
if (info.locatorLog && !visible) {
|
|
465
|
-
info.failCause.lastError =
|
|
469
|
+
info.failCause.lastError = `${formatElementName(element_name)} is not visible, searching for ${originalLocatorSearch}`;
|
|
466
470
|
info.locatorLog.setLocatorSearchStatus(originalLocatorSearch, "FOUND_NOT_VISIBLE");
|
|
467
471
|
}
|
|
468
472
|
if (info.locatorLog && !enabled) {
|
|
469
|
-
info.failCause.lastError =
|
|
473
|
+
info.failCause.lastError = `${formatElementName(element_name)} is disabled, searching for ${originalLocatorSearch}`;
|
|
470
474
|
info.locatorLog.setLocatorSearchStatus(originalLocatorSearch, "FOUND_NOT_ENABLED");
|
|
471
475
|
}
|
|
472
476
|
if (!info.printMessages[j.toString()]) {
|
|
@@ -619,7 +623,7 @@ class StableBrowser {
|
|
|
619
623
|
//info.log += "unable to locate iframe " + selectors.iframe_src + "\n";
|
|
620
624
|
if (Date.now() - startTime > timeout) {
|
|
621
625
|
info.failCause.iframeNotFound = true;
|
|
622
|
-
info.failCause.lastError =
|
|
626
|
+
info.failCause.lastError = `unable to locate iframe "${selectors.iframe_src}"`;
|
|
623
627
|
throw new Error("unable to locate iframe " + selectors.iframe_src);
|
|
624
628
|
}
|
|
625
629
|
await new Promise((resolve) => setTimeout(resolve, 1000));
|
|
@@ -693,17 +697,17 @@ class StableBrowser {
|
|
|
693
697
|
}
|
|
694
698
|
// info.log += "scanning locators in priority 1" + "\n";
|
|
695
699
|
let onlyPriority3 = selectorsLocators[0].priority === 3;
|
|
696
|
-
result = await this._scanLocatorsGroup(locatorsByPriority["1"], scope, _params, info, visibleOnly, allowDisabled);
|
|
700
|
+
result = await this._scanLocatorsGroup(locatorsByPriority["1"], scope, _params, info, visibleOnly, allowDisabled, selectors?.element_name);
|
|
697
701
|
if (result.foundElements.length === 0) {
|
|
698
702
|
// info.log += "scanning locators in priority 2" + "\n";
|
|
699
|
-
result = await this._scanLocatorsGroup(locatorsByPriority["2"], scope, _params, info, visibleOnly, allowDisabled);
|
|
703
|
+
result = await this._scanLocatorsGroup(locatorsByPriority["2"], scope, _params, info, visibleOnly, allowDisabled, selectors?.element_name);
|
|
700
704
|
}
|
|
701
705
|
if (result.foundElements.length === 0 && onlyPriority3) {
|
|
702
|
-
result = await this._scanLocatorsGroup(locatorsByPriority["3"], scope, _params, info, visibleOnly, allowDisabled);
|
|
706
|
+
result = await this._scanLocatorsGroup(locatorsByPriority["3"], scope, _params, info, visibleOnly, allowDisabled, selectors?.element_name);
|
|
703
707
|
}
|
|
704
708
|
else {
|
|
705
709
|
if (result.foundElements.length === 0 && !highPriorityOnly) {
|
|
706
|
-
result = await this._scanLocatorsGroup(locatorsByPriority["3"], scope, _params, info, visibleOnly, allowDisabled);
|
|
710
|
+
result = await this._scanLocatorsGroup(locatorsByPriority["3"], scope, _params, info, visibleOnly, allowDisabled, selectors?.element_name);
|
|
707
711
|
}
|
|
708
712
|
}
|
|
709
713
|
let foundElements = result.foundElements;
|
|
@@ -771,11 +775,11 @@ class StableBrowser {
|
|
|
771
775
|
//info.log += "failed to locate unique element, total elements found " + locatorsCount + "\n";
|
|
772
776
|
info.failCause.locatorNotFound = true;
|
|
773
777
|
if (!info?.failCause?.lastError) {
|
|
774
|
-
info.failCause.lastError =
|
|
778
|
+
info.failCause.lastError = `failed to locate ${formatElementName(selectors.element_name)}, ${locatorsCount > 0 ? `${locatorsCount} matching elements found` : "no matching elements found"}`;
|
|
775
779
|
}
|
|
776
780
|
throw new Error("failed to locate first element no elements found, " + info.log);
|
|
777
781
|
}
|
|
778
|
-
async _scanLocatorsGroup(locatorsGroup, scope, _params, info, visibleOnly, allowDisabled = false) {
|
|
782
|
+
async _scanLocatorsGroup(locatorsGroup, scope, _params, info, visibleOnly, allowDisabled = false, element_name) {
|
|
779
783
|
let foundElements = [];
|
|
780
784
|
const result = {
|
|
781
785
|
foundElements: foundElements,
|
|
@@ -783,7 +787,7 @@ class StableBrowser {
|
|
|
783
787
|
for (let i = 0; i < locatorsGroup.length; i++) {
|
|
784
788
|
let foundLocators = [];
|
|
785
789
|
try {
|
|
786
|
-
await this._collectLocatorInformation(locatorsGroup, i, scope, foundLocators, _params, info, visibleOnly, allowDisabled);
|
|
790
|
+
await this._collectLocatorInformation(locatorsGroup, i, scope, foundLocators, _params, info, visibleOnly, allowDisabled, element_name);
|
|
787
791
|
}
|
|
788
792
|
catch (e) {
|
|
789
793
|
// this call can fail it the browser is navigating
|
|
@@ -791,7 +795,7 @@ class StableBrowser {
|
|
|
791
795
|
// this.logger.debug(e);
|
|
792
796
|
foundLocators = [];
|
|
793
797
|
try {
|
|
794
|
-
await this._collectLocatorInformation(locatorsGroup, i, this.page, foundLocators, _params, info, visibleOnly, allowDisabled);
|
|
798
|
+
await this._collectLocatorInformation(locatorsGroup, i, this.page, foundLocators, _params, info, visibleOnly, allowDisabled, element_name);
|
|
795
799
|
}
|
|
796
800
|
catch (e) {
|
|
797
801
|
this.logger.info("unable to use locator (second try) " + JSON.stringify(locatorsGroup[i]));
|
|
@@ -827,7 +831,7 @@ class StableBrowser {
|
|
|
827
831
|
operation: "simpleClick",
|
|
828
832
|
log: "***** click on " + elementDescription + " *****\n",
|
|
829
833
|
};
|
|
830
|
-
_preCommand(state, this
|
|
834
|
+
_preCommand(state, this);
|
|
831
835
|
const startTime = Date.now();
|
|
832
836
|
let timeout = 30000;
|
|
833
837
|
if (options && options.timeout) {
|
|
@@ -876,7 +880,7 @@ class StableBrowser {
|
|
|
876
880
|
operation: "simpleClickType",
|
|
877
881
|
log: "***** click type on " + elementDescription + " *****\n",
|
|
878
882
|
};
|
|
879
|
-
_preCommand(state, this
|
|
883
|
+
_preCommand(state, this);
|
|
880
884
|
const startTime = Date.now();
|
|
881
885
|
let timeout = 30000;
|
|
882
886
|
if (options && options.timeout) {
|
|
@@ -924,7 +928,7 @@ class StableBrowser {
|
|
|
924
928
|
log: "***** click on " + selectors.element_name + " *****\n",
|
|
925
929
|
};
|
|
926
930
|
try {
|
|
927
|
-
await _preCommand(state, this
|
|
931
|
+
await _preCommand(state, this);
|
|
928
932
|
// if (state.options && state.options.context) {
|
|
929
933
|
// state.selectors.locators[0].text = state.options.context;
|
|
930
934
|
// }
|
|
@@ -960,18 +964,18 @@ class StableBrowser {
|
|
|
960
964
|
log: "***** check " + selectors.element_name + " *****\n",
|
|
961
965
|
};
|
|
962
966
|
try {
|
|
963
|
-
await _preCommand(state, this
|
|
967
|
+
await _preCommand(state, this);
|
|
964
968
|
state.info.checked = checked;
|
|
965
969
|
// let element = await this._locate(selectors, info, _params);
|
|
966
970
|
// ({ screenshotId, screenshotPath } = await this._screenShot(options, world, info));
|
|
967
971
|
try {
|
|
968
|
-
if (world && world.screenshot && !world.screenshotPath) {
|
|
969
|
-
|
|
970
|
-
|
|
971
|
-
await new Promise((resolve) => setTimeout(resolve, 100));
|
|
972
|
-
await this._unHighlightElements(element);
|
|
973
|
-
}
|
|
972
|
+
// if (world && world.screenshot && !world.screenshotPath) {
|
|
973
|
+
// console.log(`Highlighting while running from recorder`);
|
|
974
|
+
await this._highlightElements(element);
|
|
974
975
|
await state.element.setChecked(checked);
|
|
976
|
+
await new Promise((resolve) => setTimeout(resolve, 1000));
|
|
977
|
+
// await this._unHighlightElements(element);
|
|
978
|
+
// }
|
|
975
979
|
// await new Promise((resolve) => setTimeout(resolve, 1000));
|
|
976
980
|
// await this._unHighlightElements(element);
|
|
977
981
|
}
|
|
@@ -1009,10 +1013,10 @@ class StableBrowser {
|
|
|
1009
1013
|
log: "***** hover " + selectors.element_name + " *****\n",
|
|
1010
1014
|
};
|
|
1011
1015
|
try {
|
|
1012
|
-
await _preCommand(state, this
|
|
1016
|
+
await _preCommand(state, this);
|
|
1013
1017
|
try {
|
|
1014
1018
|
await state.element.hover();
|
|
1015
|
-
await _screenshot(state, this);
|
|
1019
|
+
// await _screenshot(state, this);
|
|
1016
1020
|
await new Promise((resolve) => setTimeout(resolve, 1000));
|
|
1017
1021
|
}
|
|
1018
1022
|
catch (e) {
|
|
@@ -1020,10 +1024,10 @@ class StableBrowser {
|
|
|
1020
1024
|
state.info.log += "hover failed, will try again" + "\n";
|
|
1021
1025
|
state.element = await this._locate(selectors, state.info, _params);
|
|
1022
1026
|
await state.element.hover({ timeout: 10000 });
|
|
1023
|
-
await _screenshot(state, this);
|
|
1027
|
+
// await _screenshot(state, this);
|
|
1024
1028
|
await new Promise((resolve) => setTimeout(resolve, 1000));
|
|
1025
1029
|
}
|
|
1026
|
-
|
|
1030
|
+
await _screenshot(state, this);
|
|
1027
1031
|
await this.waitForPageLoad();
|
|
1028
1032
|
return state.info;
|
|
1029
1033
|
}
|
|
@@ -1050,7 +1054,7 @@ class StableBrowser {
|
|
|
1050
1054
|
log: "***** select option " + selectors.element_name + " *****\n",
|
|
1051
1055
|
};
|
|
1052
1056
|
try {
|
|
1053
|
-
await _preCommand(state, this
|
|
1057
|
+
await _preCommand(state, this);
|
|
1054
1058
|
try {
|
|
1055
1059
|
await state.element.selectOption(values);
|
|
1056
1060
|
}
|
|
@@ -1084,7 +1088,7 @@ class StableBrowser {
|
|
|
1084
1088
|
log: "",
|
|
1085
1089
|
};
|
|
1086
1090
|
try {
|
|
1087
|
-
await _preCommand(state, this
|
|
1091
|
+
await _preCommand(state, this);
|
|
1088
1092
|
const valueSegment = state.value.split("&&");
|
|
1089
1093
|
for (let i = 0; i < valueSegment.length; i++) {
|
|
1090
1094
|
if (i > 0) {
|
|
@@ -1127,7 +1131,7 @@ class StableBrowser {
|
|
|
1127
1131
|
log: "***** set input value " + selectors.element_name + " *****\n",
|
|
1128
1132
|
};
|
|
1129
1133
|
try {
|
|
1130
|
-
await _preCommand(state, this
|
|
1134
|
+
await _preCommand(state, this);
|
|
1131
1135
|
let value = await this._replaceWithLocalData(state.value, this);
|
|
1132
1136
|
try {
|
|
1133
1137
|
await state.element.evaluateHandle((el, value) => {
|
|
@@ -1164,7 +1168,7 @@ class StableBrowser {
|
|
|
1164
1168
|
throwError: false,
|
|
1165
1169
|
};
|
|
1166
1170
|
try {
|
|
1167
|
-
await _preCommand(state, this
|
|
1171
|
+
await _preCommand(state, this);
|
|
1168
1172
|
try {
|
|
1169
1173
|
await state.element.click();
|
|
1170
1174
|
await new Promise((resolve) => setTimeout(resolve, 500));
|
|
@@ -1238,7 +1242,7 @@ class StableBrowser {
|
|
|
1238
1242
|
_value = newValue;
|
|
1239
1243
|
}
|
|
1240
1244
|
try {
|
|
1241
|
-
await _preCommand(state, this
|
|
1245
|
+
await _preCommand(state, this);
|
|
1242
1246
|
state.info.value = _value;
|
|
1243
1247
|
if (options === null || options === undefined || !options.press) {
|
|
1244
1248
|
try {
|
|
@@ -1331,7 +1335,7 @@ class StableBrowser {
|
|
|
1331
1335
|
log: "***** fill on " + selectors.element_name + " with value " + value + "*****\n",
|
|
1332
1336
|
};
|
|
1333
1337
|
try {
|
|
1334
|
-
await _preCommand(state, this
|
|
1338
|
+
await _preCommand(state, this);
|
|
1335
1339
|
await state.element.fill(value);
|
|
1336
1340
|
await state.element.dispatchEvent("change");
|
|
1337
1341
|
if (enter) {
|
|
@@ -1377,19 +1381,21 @@ class StableBrowser {
|
|
|
1377
1381
|
catch (e) {
|
|
1378
1382
|
//ignore
|
|
1379
1383
|
}
|
|
1380
|
-
({ screenshotId, screenshotPath } = await this._screenShot(options, world, info
|
|
1384
|
+
({ screenshotId, screenshotPath } = await this._screenShot(options, world, info));
|
|
1381
1385
|
try {
|
|
1382
|
-
|
|
1383
|
-
|
|
1384
|
-
|
|
1385
|
-
|
|
1386
|
-
|
|
1387
|
-
|
|
1388
|
-
|
|
1389
|
-
|
|
1390
|
-
|
|
1391
|
-
|
|
1392
|
-
}
|
|
1386
|
+
await this._highlightElements(element);
|
|
1387
|
+
// if (world && world.screenshot && !world.screenshotPath) {
|
|
1388
|
+
// // console.log(`Highlighting for get text while running from recorder`);
|
|
1389
|
+
// this._highlightElements(element)
|
|
1390
|
+
// .then(async () => {
|
|
1391
|
+
// await new Promise((resolve) => setTimeout(resolve, 1000));
|
|
1392
|
+
// this._unhighlightElements(element).then(
|
|
1393
|
+
// () => {}
|
|
1394
|
+
// // console.log(`Unhighlighting vrtr in recorder is successful`)
|
|
1395
|
+
// );
|
|
1396
|
+
// })
|
|
1397
|
+
// .catch(e);
|
|
1398
|
+
// }
|
|
1393
1399
|
const elementText = await element.innerText();
|
|
1394
1400
|
return {
|
|
1395
1401
|
text: elementText,
|
|
@@ -1436,13 +1442,13 @@ class StableBrowser {
|
|
|
1436
1442
|
}
|
|
1437
1443
|
let foundObj = null;
|
|
1438
1444
|
try {
|
|
1439
|
-
await _preCommand(state, this
|
|
1445
|
+
await _preCommand(state, this);
|
|
1440
1446
|
state.info.pattern = pattern;
|
|
1441
1447
|
foundObj = await this._getText(selectors, 0, _params, options, state.info, world);
|
|
1442
1448
|
if (foundObj && foundObj.element) {
|
|
1443
1449
|
await this.scrollIfNeeded(foundObj.element, state.info);
|
|
1444
1450
|
}
|
|
1445
|
-
await _screenshot(state, this
|
|
1451
|
+
await _screenshot(state, this);
|
|
1446
1452
|
let escapedText = text.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, "\\$&");
|
|
1447
1453
|
pattern = pattern.replace("{text}", escapedText);
|
|
1448
1454
|
let regex = new RegExp(pattern, "im");
|
|
@@ -1487,12 +1493,12 @@ class StableBrowser {
|
|
|
1487
1493
|
}
|
|
1488
1494
|
let foundObj = null;
|
|
1489
1495
|
try {
|
|
1490
|
-
await _preCommand(state, this
|
|
1496
|
+
await _preCommand(state, this);
|
|
1491
1497
|
foundObj = await this._getText(selectors, climb, _params, options, state.info, world);
|
|
1492
1498
|
if (foundObj && foundObj.element) {
|
|
1493
1499
|
await this.scrollIfNeeded(foundObj.element, state.info);
|
|
1494
1500
|
}
|
|
1495
|
-
await _screenshot(state, this
|
|
1501
|
+
await _screenshot(state, this);
|
|
1496
1502
|
const dateAlternatives = findDateAlternatives(text);
|
|
1497
1503
|
const numberAlternatives = findNumberAlternatives(text);
|
|
1498
1504
|
if (dateAlternatives.date) {
|
|
@@ -1681,7 +1687,7 @@ class StableBrowser {
|
|
|
1681
1687
|
}
|
|
1682
1688
|
return data;
|
|
1683
1689
|
}
|
|
1684
|
-
async _screenShot(options = {}, world = null, info = null
|
|
1690
|
+
async _screenShot(options = {}, world = null, info = null) {
|
|
1685
1691
|
// collect url/path/title
|
|
1686
1692
|
if (info) {
|
|
1687
1693
|
if (!info.title) {
|
|
@@ -1710,7 +1716,7 @@ class StableBrowser {
|
|
|
1710
1716
|
const uuidStr = "id_" + randomUUID();
|
|
1711
1717
|
const screenshotPath = path.join(world.screenshotPath, uuidStr + ".png");
|
|
1712
1718
|
try {
|
|
1713
|
-
await this.takeScreenshot(screenshotPath
|
|
1719
|
+
await this.takeScreenshot(screenshotPath);
|
|
1714
1720
|
// let buffer = await this.page.screenshot({ timeout: 4000 });
|
|
1715
1721
|
// // save the buffer to the screenshot path asynchrously
|
|
1716
1722
|
// fs.writeFile(screenshotPath, buffer, (err) => {
|
|
@@ -1721,7 +1727,7 @@ class StableBrowser {
|
|
|
1721
1727
|
result.screenshotId = uuidStr;
|
|
1722
1728
|
result.screenshotPath = screenshotPath;
|
|
1723
1729
|
if (info && info.box) {
|
|
1724
|
-
|
|
1730
|
+
await drawRectangle(screenshotPath, info.box.x, info.box.y, info.box.width, info.box.height);
|
|
1725
1731
|
}
|
|
1726
1732
|
}
|
|
1727
1733
|
catch (e) {
|
|
@@ -1731,7 +1737,7 @@ class StableBrowser {
|
|
|
1731
1737
|
else if (options && options.screenshot) {
|
|
1732
1738
|
result.screenshotPath = options.screenshotPath;
|
|
1733
1739
|
try {
|
|
1734
|
-
await this.takeScreenshot(options.screenshotPath
|
|
1740
|
+
await this.takeScreenshot(options.screenshotPath);
|
|
1735
1741
|
// let buffer = await this.page.screenshot({ timeout: 4000 });
|
|
1736
1742
|
// // save the buffer to the screenshot path asynchrously
|
|
1737
1743
|
// fs.writeFile(options.screenshotPath, buffer, (err) => {
|
|
@@ -1744,12 +1750,12 @@ class StableBrowser {
|
|
|
1744
1750
|
this.logger.info("unable to take screenshot, ignored");
|
|
1745
1751
|
}
|
|
1746
1752
|
if (info && info.box) {
|
|
1747
|
-
|
|
1753
|
+
await drawRectangle(options.screenshotPath, info.box.x, info.box.y, info.box.width, info.box.height);
|
|
1748
1754
|
}
|
|
1749
1755
|
}
|
|
1750
1756
|
return result;
|
|
1751
1757
|
}
|
|
1752
|
-
async takeScreenshot(screenshotPath
|
|
1758
|
+
async takeScreenshot(screenshotPath) {
|
|
1753
1759
|
const playContext = this.context.playContext;
|
|
1754
1760
|
// Using CDP to capture the screenshot
|
|
1755
1761
|
const viewportWidth = Math.max(...(await this.page.evaluate(() => [
|
|
@@ -1767,9 +1773,9 @@ class StableBrowser {
|
|
|
1767
1773
|
// await new Promise((resolve) => setTimeout(resolve, 100));
|
|
1768
1774
|
// console.log(`Unhighlighted previous element`);
|
|
1769
1775
|
// }
|
|
1770
|
-
if (focusedElement) {
|
|
1771
|
-
|
|
1772
|
-
}
|
|
1776
|
+
// if (focusedElement) {
|
|
1777
|
+
// await this._highlightElements(focusedElement);
|
|
1778
|
+
// }
|
|
1773
1779
|
if (this.context.browserName === "chromium") {
|
|
1774
1780
|
const client = await playContext.newCDPSession(this.page);
|
|
1775
1781
|
const { data } = await client.send("Page.captureScreenshot", {
|
|
@@ -1791,10 +1797,10 @@ class StableBrowser {
|
|
|
1791
1797
|
else {
|
|
1792
1798
|
screenshotBuffer = await this.page.screenshot();
|
|
1793
1799
|
}
|
|
1794
|
-
if (focusedElement) {
|
|
1795
|
-
|
|
1796
|
-
|
|
1797
|
-
}
|
|
1800
|
+
// if (focusedElement) {
|
|
1801
|
+
// // console.log(`Focused element ${JSON.stringify(focusedElement._selector)}`)
|
|
1802
|
+
// await this._unhighlightElements(focusedElement);
|
|
1803
|
+
// }
|
|
1798
1804
|
let image = await Jimp.read(screenshotBuffer);
|
|
1799
1805
|
// Get the image dimensions
|
|
1800
1806
|
const { width, height } = image.bitmap;
|
|
@@ -1821,7 +1827,7 @@ class StableBrowser {
|
|
|
1821
1827
|
};
|
|
1822
1828
|
await new Promise((resolve) => setTimeout(resolve, 2000));
|
|
1823
1829
|
try {
|
|
1824
|
-
await _preCommand(state, this
|
|
1830
|
+
await _preCommand(state, this);
|
|
1825
1831
|
await expect(state.element).toHaveCount(1, { timeout: 10000 });
|
|
1826
1832
|
return state.info;
|
|
1827
1833
|
}
|
|
@@ -1844,10 +1850,11 @@ class StableBrowser {
|
|
|
1844
1850
|
text: `Extract attribute from element`,
|
|
1845
1851
|
operation: "extractAttribute",
|
|
1846
1852
|
log: "***** extract attribute " + attribute + " from " + selectors.element_name + " *****\n",
|
|
1853
|
+
allowDisabled: true,
|
|
1847
1854
|
};
|
|
1848
1855
|
await new Promise((resolve) => setTimeout(resolve, 2000));
|
|
1849
1856
|
try {
|
|
1850
|
-
await _preCommand(state, this
|
|
1857
|
+
await _preCommand(state, this);
|
|
1851
1858
|
switch (attribute) {
|
|
1852
1859
|
case "inner_text":
|
|
1853
1860
|
state.value = await state.element.innerText();
|
|
@@ -1865,7 +1872,7 @@ class StableBrowser {
|
|
|
1865
1872
|
state.info.value = state.value;
|
|
1866
1873
|
this.setTestData({ [variable]: state.value }, world);
|
|
1867
1874
|
this.logger.info("set test data: " + variable + "=" + state.value);
|
|
1868
|
-
await new Promise((resolve) => setTimeout(resolve, 500));
|
|
1875
|
+
// await new Promise((resolve) => setTimeout(resolve, 500));
|
|
1869
1876
|
return state.info;
|
|
1870
1877
|
}
|
|
1871
1878
|
catch (e) {
|
|
@@ -1894,7 +1901,7 @@ class StableBrowser {
|
|
|
1894
1901
|
await new Promise((resolve) => setTimeout(resolve, 2000));
|
|
1895
1902
|
let val;
|
|
1896
1903
|
try {
|
|
1897
|
-
await _preCommand(state, this
|
|
1904
|
+
await _preCommand(state, this);
|
|
1898
1905
|
switch (attribute) {
|
|
1899
1906
|
case "innerText":
|
|
1900
1907
|
val = String(await state.element.innerText());
|
|
@@ -2036,17 +2043,17 @@ class StableBrowser {
|
|
|
2036
2043
|
if (node && node.style) {
|
|
2037
2044
|
let originalOutline = node.style.outline;
|
|
2038
2045
|
// console.log(`Original outline was: ${originalOutline}`);
|
|
2039
|
-
node.__previousOutline = originalOutline;
|
|
2046
|
+
// node.__previousOutline = originalOutline;
|
|
2040
2047
|
node.style.outline = "2px solid red";
|
|
2041
2048
|
// console.log(`New outline is: ${node.style.outline}`);
|
|
2042
|
-
|
|
2043
|
-
|
|
2044
|
-
|
|
2045
|
-
|
|
2046
|
-
|
|
2047
|
-
|
|
2048
|
-
|
|
2049
|
-
|
|
2049
|
+
if (window) {
|
|
2050
|
+
window.addEventListener("beforeunload", function (e) {
|
|
2051
|
+
node.style.outline = originalBorder;
|
|
2052
|
+
});
|
|
2053
|
+
}
|
|
2054
|
+
setTimeout(function () {
|
|
2055
|
+
node.style.outline = originalOutline;
|
|
2056
|
+
}, 2000);
|
|
2050
2057
|
}
|
|
2051
2058
|
})
|
|
2052
2059
|
.then(() => { })
|
|
@@ -2072,15 +2079,15 @@ class StableBrowser {
|
|
|
2072
2079
|
element.__previousOutline = originalOutline;
|
|
2073
2080
|
// Set the new border to be red and 2px solid
|
|
2074
2081
|
element.style.outline = "2px solid red";
|
|
2075
|
-
|
|
2076
|
-
|
|
2077
|
-
|
|
2078
|
-
|
|
2079
|
-
|
|
2082
|
+
if (window) {
|
|
2083
|
+
window.addEventListener("beforeunload", function (e) {
|
|
2084
|
+
element.style.outline = originalBorder;
|
|
2085
|
+
});
|
|
2086
|
+
}
|
|
2080
2087
|
// Set a timeout to revert to the original border after 2 seconds
|
|
2081
|
-
|
|
2082
|
-
|
|
2083
|
-
|
|
2088
|
+
setTimeout(function () {
|
|
2089
|
+
element.style.outline = originalBorder;
|
|
2090
|
+
}, 2000);
|
|
2084
2091
|
}
|
|
2085
2092
|
return;
|
|
2086
2093
|
}, [css])
|
|
@@ -2095,58 +2102,54 @@ class StableBrowser {
|
|
|
2095
2102
|
console.debug(error);
|
|
2096
2103
|
}
|
|
2097
2104
|
}
|
|
2098
|
-
async _unhighlightElements(scope, css) {
|
|
2099
|
-
|
|
2100
|
-
|
|
2101
|
-
|
|
2102
|
-
|
|
2103
|
-
|
|
2104
|
-
|
|
2105
|
-
|
|
2106
|
-
|
|
2107
|
-
|
|
2108
|
-
|
|
2109
|
-
|
|
2110
|
-
|
|
2111
|
-
|
|
2112
|
-
|
|
2113
|
-
|
|
2114
|
-
|
|
2115
|
-
|
|
2116
|
-
|
|
2117
|
-
|
|
2118
|
-
|
|
2119
|
-
|
|
2120
|
-
|
|
2121
|
-
|
|
2122
|
-
|
|
2123
|
-
|
|
2124
|
-
|
|
2125
|
-
|
|
2126
|
-
|
|
2127
|
-
|
|
2128
|
-
|
|
2129
|
-
|
|
2130
|
-
|
|
2131
|
-
|
|
2132
|
-
|
|
2133
|
-
|
|
2134
|
-
|
|
2135
|
-
|
|
2136
|
-
|
|
2137
|
-
|
|
2138
|
-
|
|
2139
|
-
|
|
2140
|
-
|
|
2141
|
-
|
|
2142
|
-
|
|
2143
|
-
|
|
2144
|
-
|
|
2145
|
-
|
|
2146
|
-
catch (error) {
|
|
2147
|
-
// console.debug(error);
|
|
2148
|
-
}
|
|
2149
|
-
}
|
|
2105
|
+
// async _unhighlightElements(scope, css) {
|
|
2106
|
+
// try {
|
|
2107
|
+
// if (!scope) {
|
|
2108
|
+
// return;
|
|
2109
|
+
// }
|
|
2110
|
+
// if (!css) {
|
|
2111
|
+
// scope
|
|
2112
|
+
// .evaluate((node) => {
|
|
2113
|
+
// if (node && node.style) {
|
|
2114
|
+
// if (!node.__previousOutline) {
|
|
2115
|
+
// node.style.outline = "";
|
|
2116
|
+
// } else {
|
|
2117
|
+
// node.style.outline = node.__previousOutline;
|
|
2118
|
+
// }
|
|
2119
|
+
// }
|
|
2120
|
+
// })
|
|
2121
|
+
// .then(() => {})
|
|
2122
|
+
// .catch((e) => {
|
|
2123
|
+
// // console.log(`Error while unhighlighting node ${JSON.stringify(scope)}: ${e}`);
|
|
2124
|
+
// });
|
|
2125
|
+
// } else {
|
|
2126
|
+
// scope
|
|
2127
|
+
// .evaluate(([css]) => {
|
|
2128
|
+
// if (!css) {
|
|
2129
|
+
// return;
|
|
2130
|
+
// }
|
|
2131
|
+
// let elements = Array.from(document.querySelectorAll(css));
|
|
2132
|
+
// for (i = 0; i < elements.length; i++) {
|
|
2133
|
+
// let element = elements[i];
|
|
2134
|
+
// if (!element.style) {
|
|
2135
|
+
// return;
|
|
2136
|
+
// }
|
|
2137
|
+
// if (!element.__previousOutline) {
|
|
2138
|
+
// element.style.outline = "";
|
|
2139
|
+
// } else {
|
|
2140
|
+
// element.style.outline = element.__previousOutline;
|
|
2141
|
+
// }
|
|
2142
|
+
// }
|
|
2143
|
+
// })
|
|
2144
|
+
// .then(() => {})
|
|
2145
|
+
// .catch((e) => {
|
|
2146
|
+
// // console.error(`Error while unhighlighting element in css: ${e}`);
|
|
2147
|
+
// });
|
|
2148
|
+
// }
|
|
2149
|
+
// } catch (error) {
|
|
2150
|
+
// // console.debug(error);
|
|
2151
|
+
// }
|
|
2152
|
+
// }
|
|
2150
2153
|
async verifyPagePath(pathPart, options = {}, world = null) {
|
|
2151
2154
|
const startTime = Date.now();
|
|
2152
2155
|
let error = null;
|
|
@@ -2261,7 +2264,7 @@ class StableBrowser {
|
|
|
2261
2264
|
let dateAlternatives = findDateAlternatives(text);
|
|
2262
2265
|
let numberAlternatives = findNumberAlternatives(text);
|
|
2263
2266
|
try {
|
|
2264
|
-
await _preCommand(state, this
|
|
2267
|
+
await _preCommand(state, this);
|
|
2265
2268
|
state.info.text = text;
|
|
2266
2269
|
while (true) {
|
|
2267
2270
|
const resultWithElementsFound = await this.findTextInAllFrames(dateAlternatives, numberAlternatives, text, state);
|
|
@@ -2275,31 +2278,31 @@ class StableBrowser {
|
|
|
2275
2278
|
if (resultWithElementsFound[0].randomToken) {
|
|
2276
2279
|
const frame = resultWithElementsFound[0].frame;
|
|
2277
2280
|
const dataAttribute = `[data-blinq-id-${resultWithElementsFound[0].randomToken}]`;
|
|
2278
|
-
|
|
2279
|
-
|
|
2280
|
-
|
|
2281
|
-
|
|
2282
|
-
|
|
2283
|
-
|
|
2284
|
-
|
|
2285
|
-
|
|
2286
|
-
|
|
2287
|
-
|
|
2288
|
-
|
|
2289
|
-
|
|
2290
|
-
|
|
2281
|
+
await this._highlightElements(frame, dataAttribute);
|
|
2282
|
+
// if (world && world.screenshot && !world.screenshotPath) {
|
|
2283
|
+
// console.log(`Highlighting for verify text is found while running from recorder`);
|
|
2284
|
+
// this._highlightElements(frame, dataAttribute).then(async () => {
|
|
2285
|
+
// await new Promise((resolve) => setTimeout(resolve, 1000));
|
|
2286
|
+
// this._unhighlightElements(frame, dataAttribute)
|
|
2287
|
+
// .then(async () => {
|
|
2288
|
+
// console.log(`Unhighlighted frame dataAttribute successfully`);
|
|
2289
|
+
// })
|
|
2290
|
+
// .catch(
|
|
2291
|
+
// (e) => {}
|
|
2292
|
+
// console.error(e)
|
|
2293
|
+
// );
|
|
2294
|
+
// });
|
|
2295
|
+
// }
|
|
2291
2296
|
const element = await frame.locator(dataAttribute).first();
|
|
2292
2297
|
// await new Promise((resolve) => setTimeout(resolve, 100));
|
|
2293
2298
|
// await this._unhighlightElements(frame, dataAttribute);
|
|
2294
2299
|
if (element) {
|
|
2295
2300
|
await this.scrollIfNeeded(element, state.info);
|
|
2296
2301
|
await element.dispatchEvent("bvt_verify_page_contains_text");
|
|
2297
|
-
await _screenshot(state, this, element);
|
|
2302
|
+
// await _screenshot(state, this, element);
|
|
2298
2303
|
}
|
|
2299
2304
|
}
|
|
2300
|
-
|
|
2301
|
-
await _screenshot(state, this);
|
|
2302
|
-
}
|
|
2305
|
+
await _screenshot(state, this);
|
|
2303
2306
|
return state.info;
|
|
2304
2307
|
}
|
|
2305
2308
|
// await expect(element).toHaveCount(1, { timeout: 10000 });
|
|
@@ -2335,7 +2338,7 @@ class StableBrowser {
|
|
|
2335
2338
|
let dateAlternatives = findDateAlternatives(text);
|
|
2336
2339
|
let numberAlternatives = findNumberAlternatives(text);
|
|
2337
2340
|
try {
|
|
2338
|
-
await _preCommand(state, this
|
|
2341
|
+
await _preCommand(state, this);
|
|
2339
2342
|
state.info.text = text;
|
|
2340
2343
|
while (true) {
|
|
2341
2344
|
const resultWithElementsFound = await this.findTextInAllFrames(dateAlternatives, numberAlternatives, text, state);
|
|
@@ -2387,7 +2390,7 @@ class StableBrowser {
|
|
|
2387
2390
|
let numberAlternatives = findNumberAlternatives(textToVerify);
|
|
2388
2391
|
let foundAncore = false;
|
|
2389
2392
|
try {
|
|
2390
|
-
await _preCommand(state, this
|
|
2393
|
+
await _preCommand(state, this);
|
|
2391
2394
|
state.info.text = textToVerify;
|
|
2392
2395
|
while (true) {
|
|
2393
2396
|
const resultWithElementsFound = await this.findTextInAllFrames(dateAlternatives, numberAlternatives, textAnchor, state);
|
|
@@ -2416,18 +2419,20 @@ class StableBrowser {
|
|
|
2416
2419
|
const result = await this._locateElementByText(continer, textToVerify, "*", false, true, true, {});
|
|
2417
2420
|
if (result.elementCount > 0) {
|
|
2418
2421
|
const dataAttribute = "[data-blinq-id-" + result.randomToken + "]";
|
|
2422
|
+
await this._highlightElements(frame, dataAttribute);
|
|
2419
2423
|
//const cssAnchor = `[data-blinq-id="blinq-id-${token}-anchor"]`;
|
|
2420
|
-
if (world && world.screenshot && !world.screenshotPath) {
|
|
2421
|
-
|
|
2422
|
-
|
|
2423
|
-
|
|
2424
|
-
|
|
2425
|
-
|
|
2426
|
-
|
|
2427
|
-
|
|
2428
|
-
|
|
2429
|
-
|
|
2430
|
-
|
|
2424
|
+
// if (world && world.screenshot && !world.screenshotPath) {
|
|
2425
|
+
// console.log(`Highlighting for vtrt while running from recorder`);
|
|
2426
|
+
// this._highlightElements(frame, dataAttribute)
|
|
2427
|
+
// .then(async () => {
|
|
2428
|
+
// await new Promise((resolve) => setTimeout(resolve, 1000));
|
|
2429
|
+
// this._unhighlightElements(frame, dataAttribute).then(
|
|
2430
|
+
// () => {}
|
|
2431
|
+
// console.log(`Unhighlighting vrtr in recorder is successful`)
|
|
2432
|
+
// );
|
|
2433
|
+
// })
|
|
2434
|
+
// .catch(e);
|
|
2435
|
+
// }
|
|
2431
2436
|
//await this._highlightElements(frame, cssAnchor);
|
|
2432
2437
|
const element = await frame.locator(dataAttribute).first();
|
|
2433
2438
|
// await new Promise((resolve) => setTimeout(resolve, 100));
|
|
@@ -2435,11 +2440,8 @@ class StableBrowser {
|
|
|
2435
2440
|
if (element) {
|
|
2436
2441
|
await this.scrollIfNeeded(element, state.info);
|
|
2437
2442
|
await element.dispatchEvent("bvt_verify_page_contains_text");
|
|
2438
|
-
await _screenshot(state, this, element);
|
|
2439
|
-
}
|
|
2440
|
-
else {
|
|
2441
|
-
await _screenshot(state, this);
|
|
2442
2443
|
}
|
|
2444
|
+
await _screenshot(state, this);
|
|
2443
2445
|
return state.info;
|
|
2444
2446
|
}
|
|
2445
2447
|
}
|
|
@@ -2562,14 +2564,14 @@ class StableBrowser {
|
|
|
2562
2564
|
info.selectors = selectors;
|
|
2563
2565
|
try {
|
|
2564
2566
|
let table = await this._locate(selectors, info, _params);
|
|
2565
|
-
({ screenshotId, screenshotPath } = await this._screenShot(options, world, info
|
|
2567
|
+
({ screenshotId, screenshotPath } = await this._screenShot(options, world, info));
|
|
2566
2568
|
const tableData = await getTableData(this.page, table);
|
|
2567
2569
|
return tableData;
|
|
2568
2570
|
}
|
|
2569
2571
|
catch (e) {
|
|
2570
2572
|
this.logger.error("getTableData failed " + info.log);
|
|
2571
2573
|
this.logger.error(e);
|
|
2572
|
-
({ screenshotId, screenshotPath } = await this._screenShot(options, world, info
|
|
2574
|
+
({ screenshotId, screenshotPath } = await this._screenShot(options, world, info));
|
|
2573
2575
|
info.screenshotPath = screenshotPath;
|
|
2574
2576
|
Object.assign(e, { info: info });
|
|
2575
2577
|
error = e;
|
|
@@ -2850,7 +2852,7 @@ class StableBrowser {
|
|
|
2850
2852
|
throwError: false,
|
|
2851
2853
|
};
|
|
2852
2854
|
try {
|
|
2853
|
-
await _preCommand(state, this
|
|
2855
|
+
await _preCommand(state, this);
|
|
2854
2856
|
await this.page.close();
|
|
2855
2857
|
}
|
|
2856
2858
|
catch (e) {
|