automation_model 1.0.422-dev → 1.0.422-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.
@@ -2,9 +2,9 @@
2
2
  import { expect } from "@playwright/test";
3
3
  import dayjs from "dayjs";
4
4
  import fs from "fs";
5
+ import { Jimp } from "jimp";
5
6
  import path from "path";
6
7
  import reg_parser from "regex-parser";
7
- import sharp from "sharp";
8
8
  import { findDateAlternatives, findNumberAlternatives } from "./analyze_helper.js";
9
9
  import { getDateTimeValue } from "./date_time.js";
10
10
  import drawRectangle from "./drawRect.js";
@@ -14,6 +14,9 @@ import objectPath from "object-path";
14
14
  import { decrypt } from "./utils.js";
15
15
  import csv from "csv-parser";
16
16
  import { Readable } from "node:stream";
17
+ import readline from "readline";
18
+ import { getContext } from "./init_browser.js";
19
+ import { locate_element } from "./locate_element.js";
17
20
  const Types = {
18
21
  CLICK: "click_element",
19
22
  NAVIGATE: "navigate",
@@ -41,15 +44,19 @@ const Types = {
41
44
  LOAD_DATA: "load_data",
42
45
  SET_INPUT: "set_input",
43
46
  };
47
+ export const apps = {};
44
48
  class StableBrowser {
45
- constructor(browser, page, logger = null, context = null) {
49
+ constructor(browser, page, logger = null, context = null, world = null) {
46
50
  this.browser = browser;
47
51
  this.page = page;
48
52
  this.logger = logger;
49
53
  this.context = context;
54
+ this.world = world;
50
55
  this.project_path = null;
51
56
  this.webLogFile = null;
57
+ this.networkLogger = null;
52
58
  this.configuration = null;
59
+ this.appName = "main";
53
60
  if (!this.logger) {
54
61
  this.logger = console;
55
62
  }
@@ -75,11 +82,17 @@ class StableBrowser {
75
82
  this.logger.error("unable to read ai_config.json");
76
83
  }
77
84
  const logFolder = path.join(this.project_path, "logs", "web");
78
- this.webLogFile = this.getWebLogFile(logFolder);
79
- this.registerConsoleLogListener(page, context, this.webLogFile);
80
- this.registerRequestListener();
85
+ this.world = world;
81
86
  context.pages = [this.page];
82
87
  context.pageLoading = { status: false };
88
+ this.registerEventListeners(this.context);
89
+ }
90
+ registerEventListeners(context) {
91
+ this.registerConsoleLogListener(this.page, context);
92
+ this.registerRequestListener(this.page, context, this.webLogFile);
93
+ if (!context.pageLoading) {
94
+ context.pageLoading = { status: false };
95
+ }
83
96
  context.playContext.on("page", async function (page) {
84
97
  context.pageLoading.status = true;
85
98
  this.page = page;
@@ -109,6 +122,36 @@ class StableBrowser {
109
122
  context.pageLoading.status = false;
110
123
  }.bind(this));
111
124
  }
125
+ async switchApp(appName) {
126
+ // check if the current app (this.appName) is the same as the new app
127
+ if (this.appName === appName) {
128
+ return;
129
+ }
130
+ let navigate = false;
131
+ if (!apps[appName]) {
132
+ let newContext = await getContext(null, false, this.logger, appName, false, this);
133
+ navigate = true;
134
+ apps[appName] = {
135
+ context: newContext,
136
+ browser: newContext.browser,
137
+ page: newContext.page,
138
+ };
139
+ }
140
+ const tempContext = {};
141
+ this._copyContext(this, tempContext);
142
+ this._copyContext(apps[appName], this);
143
+ apps[this.appName] = tempContext;
144
+ this.appName = appName;
145
+ if (navigate) {
146
+ await this.goto(this.context.environment.baseUrl);
147
+ await this.waitForPageLoad();
148
+ }
149
+ }
150
+ _copyContext(from, to) {
151
+ to.browser = from.browser;
152
+ to.page = from.page;
153
+ to.context = from.context;
154
+ }
112
155
  getWebLogFile(logFolder) {
113
156
  if (!fs.existsSync(logFolder)) {
114
157
  fs.mkdirSync(logFolder, { recursive: true });
@@ -120,37 +163,65 @@ class StableBrowser {
120
163
  const fileName = nextIndex + ".json";
121
164
  return path.join(logFolder, fileName);
122
165
  }
123
- registerConsoleLogListener(page, context, logFile) {
166
+ registerConsoleLogListener(page, context) {
124
167
  if (!this.context.webLogger) {
125
168
  this.context.webLogger = [];
126
169
  }
127
170
  page.on("console", async (msg) => {
128
- this.context.webLogger.push({
171
+ var _a;
172
+ const obj = {
129
173
  type: msg.type(),
130
174
  text: msg.text(),
131
175
  location: msg.location(),
132
176
  time: new Date().toISOString(),
133
- });
134
- await fs.promises.writeFile(logFile, JSON.stringify(this.context.webLogger, null, 2));
177
+ };
178
+ this.context.webLogger.push(obj);
179
+ if (msg.type() === "error") {
180
+ (_a = this.world) === null || _a === void 0 ? void 0 : _a.attach(JSON.stringify(obj), { mediaType: "application/json+log" });
181
+ }
135
182
  });
136
183
  }
137
- registerRequestListener() {
138
- this.page.on("request", async (data) => {
184
+ registerRequestListener(page, context, logFile) {
185
+ if (!this.context.networkLogger) {
186
+ this.context.networkLogger = [];
187
+ }
188
+ page.on("request", async (data) => {
189
+ var _a;
190
+ const startTime = new Date().getTime();
139
191
  try {
140
- const pageUrl = new URL(this.page.url());
192
+ const pageUrl = new URL(page.url());
141
193
  const requestUrl = new URL(data.url());
142
194
  if (pageUrl.hostname === requestUrl.hostname) {
143
195
  const method = data.method();
144
- if (method === "POST" || method === "GET" || method === "PUT" || method === "DELETE" || method === "PATCH") {
196
+ if (["POST", "GET", "PUT", "DELETE", "PATCH"].includes(method)) {
145
197
  const token = await data.headerValue("Authorization");
146
198
  if (token) {
147
- this.context.authtoken = token;
199
+ context.authtoken = token;
148
200
  }
149
201
  }
150
202
  }
203
+ const response = await data.response();
204
+ const endTime = new Date().getTime();
205
+ const obj = {
206
+ url: data.url(),
207
+ method: data.method(),
208
+ postData: data.postData(),
209
+ error: data.failure() ? data.failure().errorText : null,
210
+ duration: endTime - startTime,
211
+ startTime,
212
+ };
213
+ context.networkLogger.push(obj);
214
+ (_a = this.world) === null || _a === void 0 ? void 0 : _a.attach(JSON.stringify(obj), { mediaType: "application/json+network" });
151
215
  }
152
216
  catch (error) {
153
217
  console.error("Error in request listener", error);
218
+ context.networkLogger.push({
219
+ error: "not able to listen",
220
+ message: error.message,
221
+ stack: error.stack,
222
+ time: new Date().toISOString(),
223
+ });
224
+ // await fs.promises.writeFile(logFile, JSON.stringify(context.networkLogger, null, 2));
154
225
  }
155
226
  });
156
227
  }
@@ -267,7 +338,10 @@ class StableBrowser {
267
338
  return locatorReturn;
268
339
  }
269
340
  async _locateElmentByTextClimbCss(scope, text, climb, css, _params) {
270
- let result = await this._locateElementByText(scope, this._fixUsingParams(text, _params), "*", false, true, _params);
341
+ if (css && css.locator) {
342
+ css = css.locator;
343
+ }
344
+ let result = await this._locateElementByText(scope, this._fixUsingParams(text, _params), "*", false, false, _params);
271
345
  if (result.elementCount === 0) {
272
346
  return;
273
347
  }
@@ -294,6 +368,15 @@ class StableBrowser {
294
368
  return false;
295
369
  }
296
370
  document.isParent = isParent;
371
+ function getRegex(str) {
372
+ const match = str.match(/^\/(.*?)\/([gimuy]*)$/);
373
+ if (!match) {
374
+ return null;
375
+ }
376
+ let [_, pattern, flags] = match;
377
+ return new RegExp(pattern, flags);
378
+ }
379
+ document.getRegex = getRegex;
297
380
  function collectAllShadowDomElements(element, result = []) {
298
381
  // Check and add the element if it has a shadow root
299
382
  if (element.shadowRoot) {
@@ -312,6 +395,10 @@ class StableBrowser {
312
395
  if (!tag) {
313
396
  tag = "*";
314
397
  }
398
+ let regexpSearch = document.getRegex(text);
399
+ if (regexpSearch) {
400
+ regex = true;
401
+ }
315
402
  let elements = Array.from(document.querySelectorAll(tag));
316
403
  let shadowHosts = [];
317
404
  document.collectAllShadowDomElements(document, shadowHosts);
@@ -327,7 +414,9 @@ class StableBrowser {
327
414
  let randomToken = null;
328
415
  const foundElements = [];
329
416
  if (regex) {
330
- let regexpSearch = new RegExp(text, "im");
417
+ if (!regexpSearch) {
418
+ regexpSearch = new RegExp(text, "im");
419
+ }
331
420
  for (let i = 0; i < elements.length; i++) {
332
421
  const element = elements[i];
333
422
  if ((element.innerText && regexpSearch.test(element.innerText)) ||
@@ -341,8 +430,8 @@ class StableBrowser {
341
430
  for (let i = 0; i < elements.length; i++) {
342
431
  const element = elements[i];
343
432
  if (partial) {
344
- if ((element.innerText && element.innerText.trim().includes(text)) ||
345
- (element.value && element.value.includes(text))) {
433
+ if ((element.innerText && element.innerText.toLowerCase().trim().includes(text.toLowerCase())) ||
434
+ (element.value && element.value.toLowerCase().includes(text.toLowerCase()))) {
346
435
  foundElements.push(element);
347
436
  }
348
437
  }
@@ -387,6 +476,12 @@ class StableBrowser {
387
476
  }
388
477
  async _collectLocatorInformation(selectorHierarchy, index = 0, scope, foundLocators, _params, info, visibleOnly = true) {
389
478
  let locatorSearch = selectorHierarchy[index];
479
+ try {
480
+ locatorSearch = JSON.parse(this._fixUsingParams(JSON.stringify(locatorSearch), _params));
481
+ }
482
+ catch (e) {
483
+ console.error(e);
484
+ }
390
485
  //info.log += "searching for locator " + JSON.stringify(locatorSearch) + "\n";
391
486
  let locator = null;
392
487
  if (locatorSearch.climb && locatorSearch.climb >= 0) {
@@ -475,6 +570,8 @@ class StableBrowser {
475
570
  if (result.foundElements.length > 0) {
476
571
  let dialogCloseLocator = result.foundElements[0].locator;
477
572
  await dialogCloseLocator.click();
573
+ // wait for the dialog to close
574
+ await dialogCloseLocator.waitFor({ state: "hidden" });
478
575
  return { rerun: true };
479
576
  }
480
577
  }
@@ -483,7 +580,7 @@ class StableBrowser {
483
580
  }
484
581
  async _locate(selectors, info, _params, timeout = 30000) {
485
582
  for (let i = 0; i < 3; i++) {
486
- info.log += "attempt " + i + ": totoal locators " + selectors.locators.length + "\n";
583
+ info.log += "attempt " + i + ": total locators " + selectors.locators.length + "\n";
487
584
  for (let j = 0; j < selectors.locators.length; j++) {
488
585
  let selector = selectors.locators[j];
489
586
  info.log += "searching for locator " + j + ":" + JSON.stringify(selector) + "\n";
@@ -502,10 +599,44 @@ class StableBrowser {
502
599
  let locatorsCount = 0;
503
600
  //let arrayMode = Array.isArray(selectors);
504
601
  let scope = this.page;
602
+ // for the simple click usecase
603
+ if (selectors.frame) {
604
+ scope = selectors.frame;
605
+ }
505
606
  if (selectors.iframe_src || selectors.frameLocators) {
607
+ const findFrame = async (frame, framescope) => {
608
+ for (let i = 0; i < frame.selectors.length; i++) {
609
+ let frameLocator = frame.selectors[i];
610
+ if (frameLocator.css) {
611
+ let testframescope = framescope.frameLocator(frameLocator.css);
612
+ if (frameLocator.index) {
613
+ testframescope = framescope.nth(frameLocator.index);
614
+ }
615
+ try {
616
+ await testframescope.owner().evaluateHandle(() => true, null, {
617
+ timeout: 5000,
618
+ });
619
+ framescope = testframescope;
620
+ break;
621
+ }
622
+ catch (error) {
623
+ console.error("frame not found " + frameLocator.css);
624
+ }
625
+ }
626
+ }
627
+ if (frame.children) {
628
+ return await findFrame(frame.children, framescope);
629
+ }
630
+ return framescope;
631
+ };
506
632
  info.log += "searching for iframe " + selectors.iframe_src + "/" + selectors.frameLocators + "\n";
507
633
  while (true) {
508
634
  let frameFound = false;
635
+ if (selectors.nestFrmLoc) {
636
+ scope = await findFrame(selectors.nestFrmLoc, scope);
637
+ frameFound = true;
638
+ break;
639
+ }
509
640
  if (selectors.frameLocators) {
510
641
  for (let i = 0; i < selectors.frameLocators.length; i++) {
511
642
  let frameLocator = selectors.frameLocators[i];
@@ -666,6 +797,66 @@ class StableBrowser {
666
797
  }
667
798
  return result;
668
799
  }
800
+ async simpleClick(elementDescription, _params, options = {}, world = null) {
801
+ const startTime = Date.now();
802
+ let timeout = 30000;
803
+ if (options && options.timeout) {
804
+ timeout = options.timeout;
805
+ }
806
+ while (true) {
807
+ try {
808
+ const result = await locate_element(this.context, elementDescription, "click");
809
+ if ((result === null || result === void 0 ? void 0 : result.elementNumber) >= 0) {
810
+ const selectors = {
811
+ frame: result === null || result === void 0 ? void 0 : result.frame,
812
+ locators: [
813
+ {
814
+ css: result === null || result === void 0 ? void 0 : result.css,
815
+ },
816
+ ],
817
+ };
818
+ await this.click(selectors, _params, options, world);
819
+ return;
820
+ }
821
+ }
822
+ catch (e) {
823
+ if (performance.now() - startTime > timeout) {
824
+ throw e;
825
+ }
826
+ }
827
+ await new Promise((resolve) => setTimeout(resolve, 3000));
828
+ }
829
+ }
830
+ async simpleClickType(elementDescription, value, _params, options = {}, world = null) {
831
+ const startTime = Date.now();
832
+ let timeout = 30000;
833
+ if (options && options.timeout) {
834
+ timeout = options.timeout;
835
+ }
836
+ while (true) {
837
+ try {
838
+ const result = await locate_element(this.context, elementDescription, "fill", value);
839
+ if ((result === null || result === void 0 ? void 0 : result.elementNumber) >= 0) {
840
+ const selectors = {
841
+ frame: result === null || result === void 0 ? void 0 : result.frame,
842
+ locators: [
843
+ {
844
+ css: result === null || result === void 0 ? void 0 : result.css,
845
+ },
846
+ ],
847
+ };
848
+ await this.clickType(selectors, value, false, _params, options, world);
849
+ return;
850
+ }
851
+ }
852
+ catch (e) {
853
+ if (performance.now() - startTime > timeout) {
854
+ throw e;
855
+ }
856
+ }
857
+ await new Promise((resolve) => setTimeout(resolve, 3000));
858
+ }
859
+ }
669
860
  async click(selectors, _params, options = {}, world = null) {
670
861
  this._validateSelectors(selectors);
671
862
  const startTime = Date.now();
@@ -685,14 +876,14 @@ class StableBrowser {
685
876
  ({ screenshotId, screenshotPath } = await this._screenShot(options, world, info));
686
877
  try {
687
878
  await this._highlightElements(element);
688
- await element.click({ timeout: 5000 });
879
+ await element.click();
689
880
  await new Promise((resolve) => setTimeout(resolve, 1000));
690
881
  }
691
882
  catch (e) {
692
883
  // await this.closeUnexpectedPopups();
693
884
  info.log += "click failed, will try again" + "\n";
694
885
  element = await this._locate(selectors, info, _params);
695
- await element.click({ timeout: 10000, force: true });
886
+ await element.dispatchEvent("click");
696
887
  await new Promise((resolve) => setTimeout(resolve, 1000));
697
888
  }
698
889
  await this.waitForPageLoad();
@@ -745,7 +936,7 @@ class StableBrowser {
745
936
  ({ screenshotId, screenshotPath } = await this._screenShot(options, world, info));
746
937
  try {
747
938
  await this._highlightElements(element);
748
- await element.setChecked(checked, { timeout: 5000 });
939
+ await element.setChecked(checked);
749
940
  await new Promise((resolve) => setTimeout(resolve, 1000));
750
941
  }
751
942
  catch (e) {
@@ -809,7 +1000,7 @@ class StableBrowser {
809
1000
  ({ screenshotId, screenshotPath } = await this._screenShot(options, world, info));
810
1001
  try {
811
1002
  await this._highlightElements(element);
812
- await element.hover({ timeout: 10000 });
1003
+ await element.hover();
813
1004
  await new Promise((resolve) => setTimeout(resolve, 1000));
814
1005
  }
815
1006
  catch (e) {
@@ -871,7 +1062,7 @@ class StableBrowser {
871
1062
  ({ screenshotId, screenshotPath } = await this._screenShot(options, world, info));
872
1063
  try {
873
1064
  await this._highlightElements(element);
874
- await element.selectOption(values, { timeout: 5000 });
1065
+ await element.selectOption(values);
875
1066
  }
876
1067
  catch (e) {
877
1068
  //await this.closeUnexpectedPopups();
@@ -1159,7 +1350,6 @@ class StableBrowser {
1159
1350
  let element = await this._locate(selectors, info, _params);
1160
1351
  //insert red border around the element
1161
1352
  await this.scrollIfNeeded(element, info);
1162
- ({ screenshotId, screenshotPath } = await this._screenShot(options, world, info));
1163
1353
  await this._highlightElements(element);
1164
1354
  if (options === null || options === undefined || !options.press) {
1165
1355
  try {
@@ -1209,6 +1399,7 @@ class StableBrowser {
1209
1399
  await new Promise((resolve) => setTimeout(resolve, 500));
1210
1400
  }
1211
1401
  }
1402
+ ({ screenshotId, screenshotPath } = await this._screenShot(options, world, info));
1212
1403
  if (enter === true) {
1213
1404
  await new Promise((resolve) => setTimeout(resolve, 2000));
1214
1405
  await this.page.keyboard.press("Enter");
@@ -1274,7 +1465,7 @@ class StableBrowser {
1274
1465
  let element = await this._locate(selectors, info, _params);
1275
1466
  ({ screenshotId, screenshotPath } = await this._screenShot(options, world, info));
1276
1467
  await this._highlightElements(element);
1277
- await element.fill(value, { timeout: 10000 });
1468
+ await element.fill(value);
1278
1469
  await element.dispatchEvent("change");
1279
1470
  if (enter) {
1280
1471
  await new Promise((resolve) => setTimeout(resolve, 2000));
@@ -1493,7 +1684,7 @@ class StableBrowser {
1493
1684
  return info;
1494
1685
  }
1495
1686
  catch (e) {
1496
- //await this.closeUnexpectedPopups();
1687
+ await this.closeUnexpectedPopups();
1497
1688
  this.logger.error("verify element contains text failed " + info.log);
1498
1689
  ({ screenshotId, screenshotPath } = await this._screenShot(options, world, info));
1499
1690
  info.screenshotPath = screenshotPath;
@@ -1541,6 +1732,29 @@ class StableBrowser {
1541
1732
  }
1542
1733
  return dataFile;
1543
1734
  }
1735
+ async waitForUserInput(message, world = null) {
1736
+ if (!message) {
1737
+ message = "# Wait for user input. Press any key to continue";
1738
+ }
1739
+ else {
1740
+ message = "# Wait for user input. " + message;
1741
+ }
1742
+ message += "\n";
1743
+ const value = await new Promise((resolve) => {
1744
+ const rl = readline.createInterface({
1745
+ input: process.stdin,
1746
+ output: process.stdout,
1747
+ });
1748
+ rl.question(message, (answer) => {
1749
+ rl.close();
1750
+ resolve(answer);
1751
+ });
1752
+ });
1753
+ if (value) {
1754
+ this.logger.info(`{{userInput}} was set to: ${value}`);
1755
+ }
1756
+ this.setTestData({ userInput: value }, world);
1757
+ }
1544
1758
  setTestData(testData, world = null) {
1545
1759
  if (!testData) {
1546
1760
  return;
@@ -1728,7 +1942,6 @@ class StableBrowser {
1728
1942
  }
1729
1943
  async takeScreenshot(screenshotPath) {
1730
1944
  const playContext = this.context.playContext;
1731
- const client = await playContext.newCDPSession(this.page);
1732
1945
  // Using CDP to capture the screenshot
1733
1946
  const viewportWidth = Math.max(...(await this.page.evaluate(() => [
1734
1947
  document.body.scrollWidth,
@@ -1738,41 +1951,40 @@ class StableBrowser {
1738
1951
  document.body.clientWidth,
1739
1952
  document.documentElement.clientWidth,
1740
1953
  ])));
1741
- const viewportHeight = Math.max(...(await this.page.evaluate(() => [
1742
- document.body.scrollHeight,
1743
- document.documentElement.scrollHeight,
1744
- document.body.offsetHeight,
1745
- document.documentElement.offsetHeight,
1746
- document.body.clientHeight,
1747
- document.documentElement.clientHeight,
1748
- ])));
1749
- const { data } = await client.send("Page.captureScreenshot", {
1750
- format: "png",
1751
- // clip: {
1752
- // x: 0,
1753
- // y: 0,
1754
- // width: viewportWidth,
1755
- // height: viewportHeight,
1756
- // scale: 1,
1757
- // },
1758
- });
1759
- if (!screenshotPath) {
1760
- return data;
1761
- }
1762
- let screenshotBuffer = Buffer.from(data, "base64");
1763
- const sharpBuffer = sharp(screenshotBuffer);
1764
- const metadata = await sharpBuffer.metadata();
1765
- //check if you are on retina display and reduce the quality of the image
1766
- if (metadata.width > viewportWidth || metadata.height > viewportHeight) {
1767
- screenshotBuffer = await sharpBuffer
1768
- .resize(viewportWidth, viewportHeight, {
1769
- fit: sharp.fit.inside,
1770
- withoutEnlargement: true,
1771
- })
1772
- .toBuffer();
1773
- }
1774
- fs.writeFileSync(screenshotPath, screenshotBuffer);
1775
- await client.detach();
1954
+ let screenshotBuffer = null;
1955
+ if (this.context.browserName === "chromium") {
1956
+ const client = await playContext.newCDPSession(this.page);
1957
+ const { data } = await client.send("Page.captureScreenshot", {
1958
+ format: "png",
1959
+ // clip: {
1960
+ // x: 0,
1961
+ // y: 0,
1962
+ // width: viewportWidth,
1963
+ // height: viewportHeight,
1964
+ // scale: 1,
1965
+ // },
1966
+ });
1967
+ await client.detach();
1968
+ if (!screenshotPath) {
1969
+ return data;
1970
+ }
1971
+ screenshotBuffer = Buffer.from(data, "base64");
1972
+ }
1973
+ else {
1974
+ screenshotBuffer = await this.page.screenshot();
1975
+ }
1976
+ let image = await Jimp.read(screenshotBuffer);
1977
+ // Get the image dimensions
1978
+ const { width, height } = image.bitmap;
1979
+ const resizeRatio = viewportWidth / width;
1980
+ // Resize the image to fit within the viewport dimensions without enlarging
1981
+ if (width > viewportWidth) {
1982
+ image = image.resize({ w: viewportWidth, h: height * resizeRatio }); // Resize the image while maintaining aspect ratio
1983
+ await image.write(screenshotPath);
1984
+ }
1985
+ else {
1986
+ fs.writeFileSync(screenshotPath, screenshotBuffer);
1987
+ }
1776
1988
  }
1777
1989
  async verifyElementExistInPage(selectors, _params = null, options = {}, world = null) {
1778
1990
  this._validateSelectors(selectors);
@@ -2132,20 +2344,20 @@ class StableBrowser {
2132
2344
  for (let i = 0; i < frames.length; i++) {
2133
2345
  if (dateAlternatives.date) {
2134
2346
  for (let j = 0; j < dateAlternatives.dates.length; j++) {
2135
- const result = await this._locateElementByText(frames[i], dateAlternatives.dates[j], "*", true, {});
2347
+ const result = await this._locateElementByText(frames[i], dateAlternatives.dates[j], "*", true, true, {});
2136
2348
  result.frame = frames[i];
2137
2349
  results.push(result);
2138
2350
  }
2139
2351
  }
2140
2352
  else if (numberAlternatives.number) {
2141
2353
  for (let j = 0; j < numberAlternatives.numbers.length; j++) {
2142
- const result = await this._locateElementByText(frames[i], numberAlternatives.numbers[j], "*", true, {});
2354
+ const result = await this._locateElementByText(frames[i], numberAlternatives.numbers[j], "*", true, true, {});
2143
2355
  result.frame = frames[i];
2144
2356
  results.push(result);
2145
2357
  }
2146
2358
  }
2147
2359
  else {
2148
- const result = await this._locateElementByText(frames[i], text, "*", true, {});
2360
+ const result = await this._locateElementByText(frames[i], text, "*", true, true, {});
2149
2361
  result.frame = frames[i];
2150
2362
  results.push(result);
2151
2363
  }
@@ -2580,13 +2792,13 @@ class StableBrowser {
2580
2792
  }
2581
2793
  catch (e) {
2582
2794
  if (e.label === "networkidle") {
2583
- console.log("waitted for the network to be idle timeout");
2795
+ console.log("waited for the network to be idle timeout");
2584
2796
  }
2585
2797
  else if (e.label === "load") {
2586
- console.log("waitted for the load timeout");
2798
+ console.log("waited for the load timeout");
2587
2799
  }
2588
2800
  else if (e.label === "domcontentloaded") {
2589
- console.log("waitted for the domcontent loaded timeout");
2801
+ console.log("waited for the domcontent loaded timeout");
2590
2802
  }
2591
2803
  console.log(".");
2592
2804
  }
@@ -2729,33 +2941,18 @@ class StableBrowser {
2729
2941
  }
2730
2942
  async scrollIfNeeded(element, info) {
2731
2943
  try {
2732
- let didScroll = await element.evaluate((node) => {
2733
- const rect = node.getBoundingClientRect();
2734
- if (rect &&
2735
- rect.top >= 0 &&
2736
- rect.left >= 0 &&
2737
- rect.bottom <= (window.innerHeight || document.documentElement.clientHeight) &&
2738
- rect.right <= (window.innerWidth || document.documentElement.clientWidth)) {
2739
- return false;
2740
- }
2741
- else {
2742
- node.scrollIntoView({
2743
- behavior: "smooth",
2744
- block: "center",
2745
- inline: "center",
2746
- });
2747
- return true;
2748
- }
2944
+ await element.scrollIntoViewIfNeeded({
2945
+ timeout: 2000,
2749
2946
  });
2750
- if (didScroll) {
2751
- await new Promise((resolve) => setTimeout(resolve, 500));
2752
- if (info) {
2753
- info.box = await element.boundingBox();
2754
- }
2947
+ await new Promise((resolve) => setTimeout(resolve, 500));
2948
+ if (info) {
2949
+ info.box = await element.boundingBox({
2950
+ timeout: 1000,
2951
+ });
2755
2952
  }
2756
2953
  }
2757
2954
  catch (e) {
2758
- console.log("scroll failed");
2955
+ console.log("#-#");
2759
2956
  }
2760
2957
  }
2761
2958
  _reportToWorld(world, properties) {