automation_model 1.0.930-dev → 1.0.932-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.
@@ -165,14 +165,20 @@ class StableBrowser {
165
165
  context.playContext.on("page", async function (page) {
166
166
  if (this.configuration && this.configuration.closePopups === true) {
167
167
  console.log("close unexpected popups");
168
+ const _perf_t0 = Date.now();
169
+ logEvent("[registerEventListeners] before: page.close");
168
170
  await page.close();
171
+ logEvent(`[registerEventListeners] after: page.close took ${Date.now() - _perf_t0}ms`);
169
172
  return;
170
173
  }
171
174
  context.pageLoading.status = true;
172
175
  this.page = page;
173
176
  try {
174
177
  if (this.configuration && this.configuration.acceptDialog) {
178
+ const _perf_t1 = Date.now();
179
+ logEvent("[registerEventListeners] before: page.on");
175
180
  await page.on("dialog", (dialog) => dialog.accept());
181
+ logEvent(`[registerEventListeners] after: page.on took ${Date.now() - _perf_t1}ms`);
176
182
  }
177
183
  }
178
184
  catch (error) {
@@ -189,7 +195,10 @@ class StableBrowser {
189
195
  this.page = this.context.pages[this.context.pages.length - 1];
190
196
  this.context.page = this.page;
191
197
  try {
198
+ const _perf_t2 = Date.now();
199
+ logEvent("[registerEventListeners] before: page.title");
192
200
  let title = await this.page.title();
201
+ logEvent(`[registerEventListeners] after: page.title took ${Date.now() - _perf_t2}ms`);
193
202
  console.log("Switched to page " + title);
194
203
  }
195
204
  catch (error) {
@@ -203,7 +212,10 @@ class StableBrowser {
203
212
  }
204
213
  });
205
214
  try {
215
+ const _perf_t3 = Date.now();
216
+ logEvent("[registerEventListeners] before: waitForPageLoad");
206
217
  await this.waitForPageLoad();
218
+ logEvent(`[registerEventListeners] after: waitForPageLoad took ${Date.now() - _perf_t3}ms`);
207
219
  console.log("Switch page: " + (await page.title()));
208
220
  }
209
221
  catch (e) {
@@ -224,7 +236,10 @@ class StableBrowser {
224
236
  }
225
237
  let newContextCreated = false;
226
238
  if (!apps[appName]) {
239
+ const _perf_t4 = Date.now();
240
+ logEvent("[switchApp] before: getContext");
227
241
  let newContext = await getContext(null, this.context.headless ? this.context.headless : false, this, this.logger, appName, false, this, -1, this.context.reportFolder, null, null, this.tags);
242
+ logEvent(`[switchApp] after: getContext took ${Date.now() - _perf_t4}ms`);
228
243
  newContextCreated = true;
229
244
  apps[appName] = {
230
245
  context: newContext,
@@ -239,9 +254,15 @@ class StableBrowser {
239
254
  this.appName = appName;
240
255
  if (newContextCreated) {
241
256
  this.registerEventListeners(this.context);
257
+ const _perf_t5 = Date.now();
258
+ logEvent("[switchApp] before: goto");
242
259
  await this.goto(this.context.environment.baseUrl);
260
+ logEvent(`[switchApp] after: goto took ${Date.now() - _perf_t5}ms`);
243
261
  if (!this.fastMode && !this.stepTags.includes("fast-mode")) {
262
+ const _perf_t6 = Date.now();
263
+ logEvent("[switchApp] before: waitForPageLoad");
244
264
  await this.waitForPageLoad();
265
+ logEvent(`[switchApp] after: waitForPageLoad took ${Date.now() - _perf_t6}ms`);
245
266
  }
246
267
  }
247
268
  }
@@ -252,18 +273,27 @@ class StableBrowser {
252
273
  if (index >= 0 && index < this.context.pages.length) {
253
274
  this.page = this.context.pages[index];
254
275
  this.context.page = this.page;
276
+ const _perf_t7 = Date.now();
277
+ logEvent("[switchTab] before: page.bringToFront");
255
278
  await this.page.bringToFront();
279
+ logEvent(`[switchTab] after: page.bringToFront took ${Date.now() - _perf_t7}ms`);
256
280
  return;
257
281
  }
258
282
  }
259
283
  // if the tabNameOrIndex is a string, find the tab by name
260
284
  for (let i = 0; i < this.context.pages.length; i++) {
261
285
  let page = this.context.pages[i];
286
+ const _perf_t8 = Date.now();
287
+ logEvent("[switchTab] before: page.title");
262
288
  let title = await page.title();
289
+ logEvent(`[switchTab] after: page.title took ${Date.now() - _perf_t8}ms`);
263
290
  if (title.includes(tabTitleOrIndex)) {
264
291
  this.page = page;
265
292
  this.context.page = this.page;
293
+ const _perf_t9 = Date.now();
294
+ logEvent("[switchTab] before: page.bringToFront");
266
295
  await this.page.bringToFront();
296
+ logEvent(`[switchTab] after: page.bringToFront took ${Date.now() - _perf_t9}ms`);
267
297
  return;
268
298
  }
269
299
  }
@@ -298,13 +328,19 @@ class StableBrowser {
298
328
  if (pageUrl.hostname === requestUrl.hostname) {
299
329
  const method = data.method();
300
330
  if (["POST", "GET", "PUT", "DELETE", "PATCH"].includes(method)) {
331
+ const _perf_t10 = Date.now();
332
+ logEvent("[registerRequestListener] before: data.headerValue");
301
333
  const token = await data.headerValue("Authorization");
334
+ logEvent(`[registerRequestListener] after: data.headerValue took ${Date.now() - _perf_t10}ms`);
302
335
  if (token) {
303
336
  context.authtoken = token;
304
337
  }
305
338
  }
306
339
  }
340
+ const _perf_t11 = Date.now();
341
+ logEvent("[registerRequestListener] before: data.response");
307
342
  const response = await data.response();
343
+ logEvent(`[registerRequestListener] after: data.response took ${Date.now() - _perf_t11}ms`);
308
344
  const endTime = new Date().getTime();
309
345
  const obj = {
310
346
  url: data.url(),
@@ -336,7 +372,10 @@ class StableBrowser {
336
372
  if (!url) {
337
373
  throw new Error("url is null, verify that the environment file is correct");
338
374
  }
375
+ const _perf_t12 = Date.now();
376
+ logEvent("[goto] before: _replaceWithLocalData");
339
377
  url = await this._replaceWithLocalData(url, this.world);
378
+ logEvent(`[goto] after: _replaceWithLocalData took ${Date.now() - _perf_t12}ms`);
340
379
  if (!url.startsWith("http")) {
341
380
  url = "https://" + url;
342
381
  }
@@ -361,18 +400,33 @@ class StableBrowser {
361
400
  timeout = options["timeout"];
362
401
  }
363
402
  try {
403
+ const _perf_t13 = Date.now();
404
+ logEvent("[goto] before: _preCommand");
364
405
  await _preCommand(state, this);
406
+ logEvent(`[goto] after: _preCommand took ${Date.now() - _perf_t13}ms`);
407
+ const _perf_t14 = Date.now();
408
+ logEvent("[goto] before: page.goto");
365
409
  await this.page.goto(url, {
366
410
  timeout: timeout,
367
411
  });
412
+ logEvent(`[goto] after: page.goto took ${Date.now() - _perf_t14}ms`);
413
+ const _perf_t15 = Date.now();
414
+ logEvent("[goto] before: _screenshot");
368
415
  await _screenshot(state, this);
416
+ logEvent(`[goto] after: _screenshot took ${Date.now() - _perf_t15}ms`);
369
417
  }
370
418
  catch (error) {
371
419
  console.error("Error on goto", error);
420
+ const _perf_t16 = Date.now();
421
+ logEvent("[goto] before: _commandError");
372
422
  await _commandError(state, error, this);
423
+ logEvent(`[goto] after: _commandError took ${Date.now() - _perf_t16}ms`);
373
424
  }
374
425
  finally {
426
+ const _perf_t17 = Date.now();
427
+ logEvent("[goto] before: _commandFinally");
375
428
  await _commandFinally(state, this);
429
+ logEvent(`[goto] after: _commandFinally took ${Date.now() - _perf_t17}ms`);
376
430
  }
377
431
  }
378
432
  async goBack(options, world = null) {
@@ -390,18 +444,33 @@ class StableBrowser {
390
444
  highlight: false,
391
445
  };
392
446
  try {
447
+ const _perf_t18 = Date.now();
448
+ logEvent("[goBack] before: _preCommand");
393
449
  await _preCommand(state, this);
450
+ logEvent(`[goBack] after: _preCommand took ${Date.now() - _perf_t18}ms`);
451
+ const _perf_t19 = Date.now();
452
+ logEvent("[goBack] before: page.goBack");
394
453
  await this.page.goBack({
395
454
  waitUntil: "load",
396
455
  });
456
+ logEvent(`[goBack] after: page.goBack took ${Date.now() - _perf_t19}ms`);
457
+ const _perf_t20 = Date.now();
458
+ logEvent("[goBack] before: _screenshot");
397
459
  await _screenshot(state, this);
460
+ logEvent(`[goBack] after: _screenshot took ${Date.now() - _perf_t20}ms`);
398
461
  }
399
462
  catch (error) {
400
463
  console.error("Error on goBack", error);
464
+ const _perf_t21 = Date.now();
465
+ logEvent("[goBack] before: _commandError");
401
466
  await _commandError(state, error, this);
467
+ logEvent(`[goBack] after: _commandError took ${Date.now() - _perf_t21}ms`);
402
468
  }
403
469
  finally {
470
+ const _perf_t22 = Date.now();
471
+ logEvent("[goBack] before: _commandFinally");
404
472
  await _commandFinally(state, this);
473
+ logEvent(`[goBack] after: _commandFinally took ${Date.now() - _perf_t22}ms`);
405
474
  }
406
475
  }
407
476
  async goForward(options, world = null) {
@@ -419,18 +488,33 @@ class StableBrowser {
419
488
  highlight: false,
420
489
  };
421
490
  try {
491
+ const _perf_t23 = Date.now();
492
+ logEvent("[goForward] before: _preCommand");
422
493
  await _preCommand(state, this);
494
+ logEvent(`[goForward] after: _preCommand took ${Date.now() - _perf_t23}ms`);
495
+ const _perf_t24 = Date.now();
496
+ logEvent("[goForward] before: page.goForward");
423
497
  await this.page.goForward({
424
498
  waitUntil: "load",
425
499
  });
500
+ logEvent(`[goForward] after: page.goForward took ${Date.now() - _perf_t24}ms`);
501
+ const _perf_t25 = Date.now();
502
+ logEvent("[goForward] before: _screenshot");
426
503
  await _screenshot(state, this);
504
+ logEvent(`[goForward] after: _screenshot took ${Date.now() - _perf_t25}ms`);
427
505
  }
428
506
  catch (error) {
429
507
  console.error("Error on goForward", error);
508
+ const _perf_t26 = Date.now();
509
+ logEvent("[goForward] before: _commandError");
430
510
  await _commandError(state, error, this);
511
+ logEvent(`[goForward] after: _commandError took ${Date.now() - _perf_t26}ms`);
431
512
  }
432
513
  finally {
514
+ const _perf_t27 = Date.now();
515
+ logEvent("[goForward] before: _commandFinally");
433
516
  await _commandFinally(state, this);
517
+ logEvent(`[goForward] after: _commandFinally took ${Date.now() - _perf_t27}ms`);
434
518
  }
435
519
  }
436
520
  async _getLocator(locator, scope, _params) {
@@ -440,7 +524,10 @@ class StableBrowser {
440
524
  if (typeof locator[key] !== "string")
441
525
  continue;
442
526
  if (locator[key].includes("{{") && locator[key].includes("}}")) {
527
+ const _perf_t28 = Date.now();
528
+ logEvent("[_getLocator] before: _replaceWithLocalData");
443
529
  locator[key] = await this._replaceWithLocalData(locator[key], this.world);
530
+ logEvent(`[_getLocator] after: _replaceWithLocalData took ${Date.now() - _perf_t28}ms`);
444
531
  }
445
532
  }
446
533
  let locatorReturn;
@@ -493,7 +580,10 @@ class StableBrowser {
493
580
  if (css && css.locator) {
494
581
  css = css.locator;
495
582
  }
583
+ const _perf_t29 = Date.now();
584
+ logEvent("[_locateElmentByTextClimbCss] before: _locateElementByText");
496
585
  let result = await this._locateElementByText(scope, _fixUsingParams(text, _params), "*:not(script, style, head)", false, false, true, _params);
586
+ logEvent(`[_locateElmentByTextClimbCss] after: _locateElementByText took ${Date.now() - _perf_t29}ms`);
497
587
  if (result.elementCount === 0) {
498
588
  return;
499
589
  }
@@ -511,9 +601,13 @@ class StableBrowser {
511
601
  return resultCss;
512
602
  }
513
603
  async _locateElementByText(scope, text1, tag1, regex1 = false, partial1, ignoreCase = true, _params) {
604
+ logEvent("[_locateElementByText] locating element by text: " + text1 + ", tag: " + tag1 + ", regex: " + regex1);
514
605
  const query = `${_convertToRegexQuery(text1, regex1, !partial1, ignoreCase)}`;
515
606
  const locator = scope.locator(query);
607
+ const _perf_t30 = Date.now();
608
+ logEvent("[_locateElementByText] before: locator.count");
516
609
  const count = await locator.count();
610
+ logEvent(`[_locateElementByText] after: locator.count took ${Date.now() - _perf_t30}ms`);
517
611
  if (!tag1) {
518
612
  tag1 = "*";
519
613
  }
@@ -522,22 +616,26 @@ class StableBrowser {
522
616
  for (let i = 0; i < count; i++) {
523
617
  const element = locator.nth(i);
524
618
  // check if the tag matches
525
- if (!(await element.evaluate((el, [tag, randomToken]) => {
526
- if (!tag.startsWith("*")) {
527
- if (el.tagName.toLowerCase() !== tag) {
619
+ logEvent('[_locateElementByText] ❓ before: element.evaluate');
620
+ const condition = (await element.evaluate((el, [tagToIgnore, randomToken]) => {
621
+ if (!tagToIgnore.startsWith("*")) {
622
+ if (el.tagName.toLowerCase() !== tagToIgnore) {
528
623
  return false;
529
624
  }
530
625
  }
531
626
  if (!el.setAttribute) {
532
627
  el = el.parentElement;
533
628
  }
534
- el.setAttribute("data-blinq-id-" + randomToken, "");
629
+ el.setAttribute("data-blinq-id-" + randomToken, ""); //? example: waiting for locator('[data-blinq-id-mozaeg]').first()
535
630
  return true;
536
- }, [tag1, randomToken]))) {
631
+ }, [tag1, randomToken]));
632
+ logEvent(`[_locateElementByText] ❓ CONDITION VALUE: ${condition} after: element.evaluate took ${Date.now() - _perf_t30}ms`);
633
+ if (!condition) {
537
634
  continue;
538
635
  }
539
636
  tagCount++;
540
637
  }
638
+ logEvent(`[_locateElementByText] 🌟 total elements with text ${text1} and tag ${tag1}: ${tagCount}`);
541
639
  return { elementCount: tagCount, randomToken };
542
640
  }
543
641
  async _collectLocatorInformation(selectorHierarchy, index = 0, scope, foundLocators, _params, info, visibleOnly = true, allowDisabled = false, element_name = null, logErrors = false) {
@@ -562,18 +660,30 @@ class StableBrowser {
562
660
  //info.log += "searching for locator " + JSON.stringify(locatorSearch) + "\n";
563
661
  let locator = null;
564
662
  if (locatorSearch.climb && locatorSearch.climb >= 0) {
663
+ const _perf_t31 = Date.now();
664
+ logEvent("[_collectLocatorInformation] before: _replaceWithLocalData");
565
665
  const replacedText = await this._replaceWithLocalData(locatorSearch.text, this.world);
666
+ logEvent(`[_collectLocatorInformation] after: _replaceWithLocalData took ${Date.now() - _perf_t31}ms`);
667
+ const _perf_t32 = Date.now();
668
+ logEvent("[_collectLocatorInformation] before: _locateElmentByTextClimbCss");
566
669
  let locatorString = await this._locateElmentByTextClimbCss(scope, replacedText, locatorSearch.climb, locatorSearch.css, _params);
670
+ logEvent(`[_collectLocatorInformation] after: _locateElmentByTextClimbCss took ${Date.now() - _perf_t32}ms`);
567
671
  if (!locatorString) {
568
672
  info.failCause.textNotFound = true;
569
673
  info.failCause.lastError = `failed to locate ${formatElementName(element_name)} by text: ${locatorSearch.text}`;
570
674
  return;
571
675
  }
676
+ const _perf_t33 = Date.now();
677
+ logEvent("[_collectLocatorInformation] before: _getLocator");
572
678
  locator = await this._getLocator({ css: locatorString }, scope, _params);
679
+ logEvent(`[_collectLocatorInformation] after: _getLocator took ${Date.now() - _perf_t33}ms`);
573
680
  }
574
681
  else if (locatorSearch.text) {
575
682
  let text = _fixUsingParams(locatorSearch.text, _params);
683
+ const _perf_t34 = Date.now();
684
+ logEvent("[_collectLocatorInformation] before: _locateElementByText");
576
685
  let result = await this._locateElementByText(scope, text, locatorSearch.tag, false, locatorSearch.partial === true, true, _params);
686
+ logEvent(`[_collectLocatorInformation] after: _locateElementByText took ${Date.now() - _perf_t34}ms`);
577
687
  if (result.elementCount === 0) {
578
688
  info.failCause.textNotFound = true;
579
689
  info.failCause.lastError = `failed to locate ${formatElementName(element_name)} by text: ${text}`;
@@ -583,16 +693,25 @@ class StableBrowser {
583
693
  if (locatorSearch.childCss) {
584
694
  locatorSearch.css = locatorSearch.css + " " + locatorSearch.childCss;
585
695
  }
696
+ const _perf_t35 = Date.now();
697
+ logEvent("[_collectLocatorInformation] before: _getLocator");
586
698
  locator = await this._getLocator(locatorSearch, scope, _params);
699
+ logEvent(`[_collectLocatorInformation] after: _getLocator took ${Date.now() - _perf_t35}ms`);
587
700
  }
588
701
  else {
702
+ const _perf_t36 = Date.now();
703
+ logEvent("[_collectLocatorInformation] before: _getLocator");
589
704
  locator = await this._getLocator(locatorSearch, scope, _params);
705
+ logEvent(`[_collectLocatorInformation] after: _getLocator took ${Date.now() - _perf_t36}ms`);
590
706
  }
591
707
  // let cssHref = false;
592
708
  // if (locatorSearch.css && locatorSearch.css.includes("href=")) {
593
709
  // cssHref = true;
594
710
  // }
711
+ const _perf_t37 = Date.now();
712
+ logEvent("[_collectLocatorInformation] before: locator.count");
595
713
  let count = await locator.count();
714
+ logEvent(`[_collectLocatorInformation] after: locator.count took ${Date.now() - _perf_t37}ms`);
596
715
  if (count > 0 && !info.failCause.count) {
597
716
  info.failCause.count = count;
598
717
  }
@@ -610,8 +729,14 @@ class StableBrowser {
610
729
  info.locatorLog.setLocatorSearchStatus(originalLocatorSearch, "NOT_FOUND");
611
730
  }
612
731
  for (let j = 0; j < count; j++) {
732
+ const _perf_t38 = Date.now();
733
+ logEvent("[_collectLocatorInformation] before: locator.nth");
613
734
  let visible = await locator.nth(j).isVisible();
735
+ logEvent(`[_collectLocatorInformation] after: locator.nth took ${Date.now() - _perf_t38}ms`);
736
+ const _perf_t39 = Date.now();
737
+ logEvent("[_collectLocatorInformation] before: locator.nth");
614
738
  const enabled = await locator.nth(j).isEnabled();
739
+ logEvent(`[_collectLocatorInformation] after: locator.nth took ${Date.now() - _perf_t39}ms`);
615
740
  if (!visibleOnly) {
616
741
  visible = true;
617
742
  }
@@ -661,7 +786,10 @@ class StableBrowser {
661
786
  let result = null;
662
787
  let scope = null;
663
788
  for (let i = 0; i < scopes.length; i++) {
789
+ const _perf_t40 = Date.now();
790
+ logEvent("[closeUnexpectedPopups] before: _scanLocatorsGroup");
664
791
  result = await this._scanLocatorsGroup(handlerGroup, scopes[i], _params, info, true);
792
+ logEvent(`[closeUnexpectedPopups] after: _scanLocatorsGroup took ${Date.now() - _perf_t40}ms`);
665
793
  if (result.foundElements.length > 0) {
666
794
  scope = scopes[i];
667
795
  break;
@@ -672,7 +800,10 @@ class StableBrowser {
672
800
  const closeHandlerGroup = [];
673
801
  closeHandlerGroup.push(this.configuration.popupHandlers[result.locatorIndex].close_dialog_locator);
674
802
  for (let i = 0; i < scopes.length; i++) {
803
+ const _perf_t41 = Date.now();
804
+ logEvent("[closeUnexpectedPopups] before: _scanLocatorsGroup");
675
805
  result = await this._scanLocatorsGroup(closeHandlerGroup, scopes[i], _params, info, true);
806
+ logEvent(`[closeUnexpectedPopups] after: _scanLocatorsGroup took ${Date.now() - _perf_t41}ms`);
676
807
  if (result.foundElements.length > 0) {
677
808
  break;
678
809
  }
@@ -680,19 +811,31 @@ class StableBrowser {
680
811
  if (result.foundElements.length > 0) {
681
812
  let dialogCloseLocator = result.foundElements[0].locator;
682
813
  try {
814
+ const _perf_t42 = Date.now();
815
+ logEvent("[closeUnexpectedPopups] before: scope");
683
816
  await scope?.evaluate(() => {
684
817
  window.__isClosingPopups = true;
685
818
  });
819
+ logEvent(`[closeUnexpectedPopups] after: scope took ${Date.now() - _perf_t42}ms`);
820
+ const _perf_t43 = Date.now();
821
+ logEvent("[closeUnexpectedPopups] before: dialogCloseLocator.click");
686
822
  await dialogCloseLocator.click();
823
+ logEvent(`[closeUnexpectedPopups] after: dialogCloseLocator.click took ${Date.now() - _perf_t43}ms`);
687
824
  // wait for the dialog to close
825
+ const _perf_t44 = Date.now();
826
+ logEvent("[closeUnexpectedPopups] before: dialogCloseLocator.waitFor");
688
827
  await dialogCloseLocator.waitFor({ state: "hidden" });
828
+ logEvent(`[closeUnexpectedPopups] after: dialogCloseLocator.waitFor took ${Date.now() - _perf_t44}ms`);
689
829
  }
690
830
  catch (e) {
691
831
  }
692
832
  finally {
833
+ const _perf_t45 = Date.now();
834
+ logEvent("[closeUnexpectedPopups] before: scope");
693
835
  await scope?.evaluate(() => {
694
836
  window.__isClosingPopups = false;
695
837
  });
838
+ logEvent(`[closeUnexpectedPopups] after: scope took ${Date.now() - _perf_t45}ms`);
696
839
  }
697
840
  return { rerun: true };
698
841
  }
@@ -787,7 +930,10 @@ class StableBrowser {
787
930
  if (strategyLocators && strategyLocators.length) {
788
931
  try {
789
932
  selectors.locators = strategyLocators;
933
+ const _perf_t46 = Date.now();
934
+ logEvent("[_locate] before: _locate_internal");
790
935
  element = await this._locate_internal(selectors, info, _params, 10_000, allowDisabled);
936
+ logEvent(`[_locate] after: _locate_internal took ${Date.now() - _perf_t46}ms`);
791
937
  info.selectedStrategy = selectedStrategy;
792
938
  info.log += "element found using strategy " + selectedStrategy + "\n";
793
939
  }
@@ -805,7 +951,10 @@ class StableBrowser {
805
951
  try {
806
952
  info.log += "using strategy " + key + " with locators " + JSON.stringify(strategyLocators) + "\n";
807
953
  selectors.locators = strategyLocators;
954
+ const _perf_t47 = Date.now();
955
+ logEvent("[_locate] before: _locate_internal");
808
956
  element = await this._locate_internal(selectors, info, _params, 10_000, allowDisabled);
957
+ logEvent(`[_locate] after: _locate_internal took ${Date.now() - _perf_t47}ms`);
809
958
  err = null;
810
959
  info.selectedStrategy = key;
811
960
  info.log += "element found using strategy " + key + "\n";
@@ -822,11 +971,16 @@ class StableBrowser {
822
971
  }
823
972
  }
824
973
  else {
974
+ const _perf_t48 = Date.now();
975
+ logEvent("[_locate] before: _locate_internal");
825
976
  element = await this._locate_internal(selectors, info, _params, timeout, allowDisabled);
977
+ logEvent(`[_locate] after: _locate_internal took ${Date.now() - _perf_t48}ms`);
826
978
  }
827
979
  if (!element.rerun) {
828
980
  let newElementSelector = "";
829
981
  if (this.configuration && this.configuration.stableLocatorStrategy === "csschain") {
982
+ const _perf_t49 = Date.now();
983
+ logEvent("[_locate] before: element.evaluate");
830
984
  const cssSelector = await element.evaluate((el) => {
831
985
  function getCssSelector(el) {
832
986
  if (!el || el.nodeType !== 1 || el === document.body)
@@ -849,15 +1003,19 @@ class StableBrowser {
849
1003
  const cssSelector = getCssSelector(el);
850
1004
  return cssSelector;
851
1005
  });
1006
+ logEvent(`[_locate] after: element.evaluate took ${Date.now() - _perf_t49}ms`);
852
1007
  newElementSelector = cssSelector;
853
1008
  }
854
1009
  else {
855
1010
  const randomToken = "blinq_" + Math.random().toString(36).substring(7);
856
1011
  if (this.configuration && this.configuration.stableLocatorStrategy === "data-attribute") {
857
1012
  const dataAttribute = "data-blinq-id";
1013
+ const _perf_t50 = Date.now();
1014
+ logEvent("[_locate] before: element.evaluate");
858
1015
  await element.evaluate((el, [dataAttribute, randomToken]) => {
859
1016
  el.setAttribute(dataAttribute, randomToken);
860
1017
  }, [dataAttribute, randomToken]);
1018
+ logEvent(`[_locate] after: element.evaluate took ${Date.now() - _perf_t50}ms`);
861
1019
  newElementSelector = `[${dataAttribute}="${randomToken}"]`;
862
1020
  }
863
1021
  else {
@@ -905,9 +1063,12 @@ class StableBrowser {
905
1063
  testframescope = framescope.nth(frameLocator.index);
906
1064
  }
907
1065
  try {
1066
+ const _perf_t51 = Date.now();
1067
+ logEvent("[_findFrameScope] before: testframescope.owner");
908
1068
  await testframescope.owner().evaluateHandle(() => true, null, {
909
1069
  timeout: 5000,
910
1070
  });
1071
+ logEvent(`[_findFrameScope] after: testframescope.owner took ${Date.now() - _perf_t51}ms`);
911
1072
  framescope = testframescope;
912
1073
  break;
913
1074
  }
@@ -917,7 +1078,10 @@ class StableBrowser {
917
1078
  }
918
1079
  }
919
1080
  if (frame.children) {
1081
+ const _perf_t52 = Date.now();
1082
+ logEvent("[_findFrameScope] before: findFrame");
920
1083
  return await findFrame(frame.children, framescope);
1084
+ logEvent(`[_findFrameScope] after: findFrame took ${Date.now() - _perf_t52}ms`);
921
1085
  }
922
1086
  return framescope;
923
1087
  };
@@ -926,7 +1090,10 @@ class StableBrowser {
926
1090
  let frameFound = false;
927
1091
  if (selectors.nestFrmLoc) {
928
1092
  fLocator = selectors.nestFrmLoc;
1093
+ const _perf_t53 = Date.now();
1094
+ logEvent("[_findFrameScope] before: findFrame");
929
1095
  scope = await findFrame(selectors.nestFrmLoc, scope);
1096
+ logEvent(`[_findFrameScope] after: findFrame took ${Date.now() - _perf_t53}ms`);
930
1097
  frameFound = true;
931
1098
  break;
932
1099
  }
@@ -955,7 +1122,10 @@ class StableBrowser {
955
1122
  info.failCause.lastError = `unable to locate iframe "${selectors.iframe_src}"`;
956
1123
  throw new Error("unable to locate iframe " + selectors.iframe_src);
957
1124
  }
1125
+ const _perf_t54 = Date.now();
1126
+ logEvent("[_findFrameScope] before: new Promise");
958
1127
  await new Promise((resolve) => setTimeout(resolve, 1000));
1128
+ logEvent(`[_findFrameScope] after: new Promise took ${Date.now() - _perf_t54}ms`);
959
1129
  }
960
1130
  else {
961
1131
  if (info && info.locatorLog) {
@@ -971,7 +1141,10 @@ class StableBrowser {
971
1141
  return scope;
972
1142
  }
973
1143
  async _getDocumentBody(selectors, timeout = 30000, info) {
1144
+ const _perf_t55 = Date.now();
1145
+ logEvent("[_getDocumentBody] before: _findFrameScope");
974
1146
  let scope = await this._findFrameScope(selectors, timeout, info);
1147
+ logEvent(`[_getDocumentBody] after: _findFrameScope took ${Date.now() - _perf_t55}ms`);
975
1148
  return scope.evaluate(() => {
976
1149
  var bodyContent = document.body.innerHTML;
977
1150
  return bodyContent;
@@ -1026,22 +1199,37 @@ class StableBrowser {
1026
1199
  let highPriorityOnly = true;
1027
1200
  let visibleOnly = true;
1028
1201
  while (true) {
1202
+ const _perf_t56 = Date.now();
1203
+ logEvent("[_locate_internal] before: _findFrameScope");
1029
1204
  let scope = await this._findFrameScope(selectors, timeout, info);
1205
+ logEvent(`[_locate_internal] after: _findFrameScope took ${Date.now() - _perf_t56}ms`);
1030
1206
  locatorsCount = 0;
1031
1207
  let result = [];
1208
+ const _perf_t57 = Date.now();
1209
+ logEvent("[_locate_internal] before: closeUnexpectedPopups");
1032
1210
  let popupResult = await this.closeUnexpectedPopups(info, _params);
1211
+ logEvent(`[_locate_internal] after: closeUnexpectedPopups took ${Date.now() - _perf_t57}ms`);
1033
1212
  if (popupResult.rerun) {
1034
1213
  return popupResult;
1035
1214
  }
1036
1215
  // info.log += "scanning locators in priority 1" + "\n";
1037
1216
  let onlyPriority3 = selectorsLocators[0].priority === 3;
1217
+ const _perf_t58 = Date.now();
1218
+ logEvent("[_locate_internal] before: _scanLocatorsGroup");
1038
1219
  result = await this._scanLocatorsGroup(locatorsByPriority["1"], scope, _params, info, visibleOnly, allowDisabled, selectors?.element_name);
1220
+ logEvent(`[_locate_internal] after: _scanLocatorsGroup took ${Date.now() - _perf_t58}ms`);
1039
1221
  if (result.foundElements.length === 0) {
1040
1222
  // info.log += "scanning locators in priority 2" + "\n";
1223
+ const _perf_t59 = Date.now();
1224
+ logEvent("[_locate_internal] before: _scanLocatorsGroup");
1041
1225
  result = await this._scanLocatorsGroup(locatorsByPriority["2"], scope, _params, info, visibleOnly, allowDisabled, selectors?.element_name);
1226
+ logEvent(`[_locate_internal] after: _scanLocatorsGroup took ${Date.now() - _perf_t59}ms`);
1042
1227
  }
1043
1228
  if (result.foundElements.length === 0 && (onlyPriority3 || !highPriorityOnly)) {
1229
+ const _perf_t60 = Date.now();
1230
+ logEvent("[_locate_internal] before: _scanLocatorsGroup");
1044
1231
  result = await this._scanLocatorsGroup(locatorsByPriority["3"], scope, _params, info, visibleOnly, allowDisabled, selectors?.element_name);
1232
+ logEvent(`[_locate_internal] after: _scanLocatorsGroup took ${Date.now() - _perf_t60}ms`);
1045
1233
  }
1046
1234
  let foundElements = result.foundElements;
1047
1235
  if (foundElements.length === 1 && foundElements[0].unique) {
@@ -1077,7 +1265,10 @@ class StableBrowser {
1077
1265
  }
1078
1266
  if (maxCountElement) {
1079
1267
  info.log += "unique element was found, locator: " + maxCountElement.locator + "\n";
1268
+ const _perf_t61 = Date.now();
1269
+ logEvent("[_locate_internal] before: maxCountElement.locator.boundingBox");
1080
1270
  info.box = await maxCountElement.locator.boundingBox();
1271
+ logEvent(`[_locate_internal] after: maxCountElement.locator.boundingBox took ${Date.now() - _perf_t61}ms`);
1081
1272
  return maxCountElement.locator;
1082
1273
  }
1083
1274
  }
@@ -1089,14 +1280,20 @@ class StableBrowser {
1089
1280
  highPriorityOnly = false;
1090
1281
  if (this.configuration && this.configuration.load_all_lazy === true && !lazy_scroll) {
1091
1282
  lazy_scroll = true;
1283
+ const _perf_t62 = Date.now();
1284
+ logEvent("[_locate_internal] before: scrollPageToLoadLazyElements");
1092
1285
  await scrollPageToLoadLazyElements(this.page);
1286
+ logEvent(`[_locate_internal] after: scrollPageToLoadLazyElements took ${Date.now() - _perf_t62}ms`);
1093
1287
  }
1094
1288
  }
1095
1289
  if (Date.now() - startTime > visibleOnlyTimeout) {
1096
1290
  //info.log += "visible only timeout, will try all elements" + "\n";
1097
1291
  visibleOnly = false;
1098
1292
  }
1293
+ const _perf_t63 = Date.now();
1294
+ logEvent("[_locate_internal] before: new Promise");
1099
1295
  await new Promise((resolve) => setTimeout(resolve, 1000));
1296
+ logEvent(`[_locate_internal] after: new Promise took ${Date.now() - _perf_t63}ms`);
1100
1297
  // sheck of more of half of the timeout has passed
1101
1298
  if (Date.now() - startTime > timeout / 2) {
1102
1299
  highPriorityOnly = false;
@@ -1125,7 +1322,10 @@ class StableBrowser {
1125
1322
  for (let i = 0; i < locatorsGroup.length; i++) {
1126
1323
  let foundLocators = [];
1127
1324
  try {
1325
+ const _perf_t64 = Date.now();
1326
+ logEvent("[_scanLocatorsGroup] before: _collectLocatorInformation");
1128
1327
  await this._collectLocatorInformation(locatorsGroup, i, scope, foundLocators, _params, info, visibleOnly, allowDisabled, element_name);
1328
+ logEvent(`[_scanLocatorsGroup] after: _collectLocatorInformation took ${Date.now() - _perf_t64}ms`);
1129
1329
  }
1130
1330
  catch (e) {
1131
1331
  // this call can fail it the browser is navigating
@@ -1133,7 +1333,10 @@ class StableBrowser {
1133
1333
  // logEvent(e);
1134
1334
  foundLocators = [];
1135
1335
  try {
1336
+ const _perf_t65 = Date.now();
1337
+ logEvent("[_scanLocatorsGroup] before: _collectLocatorInformation");
1136
1338
  await this._collectLocatorInformation(locatorsGroup, i, this.page, foundLocators, _params, info, visibleOnly, allowDisabled, element_name);
1339
+ logEvent(`[_scanLocatorsGroup] after: _collectLocatorInformation took ${Date.now() - _perf_t65}ms`);
1137
1340
  }
1138
1341
  catch (e) {
1139
1342
  if (logErrors) {
@@ -1144,7 +1347,10 @@ class StableBrowser {
1144
1347
  if (foundLocators.length === 1) {
1145
1348
  let box = null;
1146
1349
  if (!this.onlyFailuresScreenshot) {
1350
+ const _perf_t66 = Date.now();
1351
+ logEvent("[_scanLocatorsGroup] before: foundLocators[0]");
1147
1352
  box = await foundLocators[0].boundingBox();
1353
+ logEvent(`[_scanLocatorsGroup] after: foundLocators[0] took ${Date.now() - _perf_t66}ms`);
1148
1354
  }
1149
1355
  result.foundElements.push({
1150
1356
  locator: foundLocators[0],
@@ -1206,7 +1412,10 @@ class StableBrowser {
1206
1412
  operation: "simpleClick",
1207
1413
  log: "***** click on " + elementDescription + " *****\n",
1208
1414
  };
1415
+ const _perf_t67 = Date.now();
1416
+ logEvent("[simpleClick] before: _preCommand");
1209
1417
  await _preCommand(state, this);
1418
+ logEvent(`[simpleClick] after: _preCommand took ${Date.now() - _perf_t67}ms`);
1210
1419
  const startTime = Date.now();
1211
1420
  let timeout = 30000;
1212
1421
  if (options && options.timeout) {
@@ -1214,7 +1423,10 @@ class StableBrowser {
1214
1423
  }
1215
1424
  while (true) {
1216
1425
  try {
1426
+ const _perf_t68 = Date.now();
1427
+ logEvent("[simpleClick] before: locate_element");
1217
1428
  const result = await locate_element(this.context, elementDescription, "click");
1429
+ logEvent(`[simpleClick] after: locate_element took ${Date.now() - _perf_t68}ms`);
1218
1430
  if (result?.elementNumber >= 0) {
1219
1431
  const selectors = {
1220
1432
  frame: result?.frame,
@@ -1224,7 +1436,10 @@ class StableBrowser {
1224
1436
  },
1225
1437
  ],
1226
1438
  };
1439
+ const _perf_t69 = Date.now();
1440
+ logEvent("[simpleClick] before: click");
1227
1441
  await this.click(selectors, _params, options, world);
1442
+ logEvent(`[simpleClick] after: click took ${Date.now() - _perf_t69}ms`);
1228
1443
  return;
1229
1444
  }
1230
1445
  }
@@ -1232,14 +1447,23 @@ class StableBrowser {
1232
1447
  if (performance.now() - startTime > timeout) {
1233
1448
  // throw e;
1234
1449
  try {
1450
+ const _perf_t70 = Date.now();
1451
+ logEvent("[simpleClick] before: _commandError");
1235
1452
  await _commandError(state, "timeout looking for " + elementDescription, this);
1453
+ logEvent(`[simpleClick] after: _commandError took ${Date.now() - _perf_t70}ms`);
1236
1454
  }
1237
1455
  finally {
1456
+ const _perf_t71 = Date.now();
1457
+ logEvent("[simpleClick] before: _commandFinally");
1238
1458
  await _commandFinally(state, this);
1459
+ logEvent(`[simpleClick] after: _commandFinally took ${Date.now() - _perf_t71}ms`);
1239
1460
  }
1240
1461
  }
1241
1462
  }
1463
+ const _perf_t72 = Date.now();
1464
+ logEvent("[simpleClick] before: new Promise");
1242
1465
  await new Promise((resolve) => setTimeout(resolve, 3000));
1466
+ logEvent(`[simpleClick] after: new Promise took ${Date.now() - _perf_t72}ms`);
1243
1467
  }
1244
1468
  }
1245
1469
  async simpleClickType(elementDescription, value, _params, options = {}, world = null) {
@@ -1255,7 +1479,10 @@ class StableBrowser {
1255
1479
  operation: "simpleClickType",
1256
1480
  log: "***** click type on " + elementDescription + " *****\n",
1257
1481
  };
1482
+ const _perf_t73 = Date.now();
1483
+ logEvent("[simpleClickType] before: _preCommand");
1258
1484
  await _preCommand(state, this);
1485
+ logEvent(`[simpleClickType] after: _preCommand took ${Date.now() - _perf_t73}ms`);
1259
1486
  const startTime = Date.now();
1260
1487
  let timeout = 30000;
1261
1488
  if (options && options.timeout) {
@@ -1263,7 +1490,10 @@ class StableBrowser {
1263
1490
  }
1264
1491
  while (true) {
1265
1492
  try {
1493
+ const _perf_t74 = Date.now();
1494
+ logEvent("[simpleClickType] before: locate_element");
1266
1495
  const result = await locate_element(this.context, elementDescription, "fill", value);
1496
+ logEvent(`[simpleClickType] after: locate_element took ${Date.now() - _perf_t74}ms`);
1267
1497
  if (result?.elementNumber >= 0) {
1268
1498
  const selectors = {
1269
1499
  frame: result?.frame,
@@ -1273,7 +1503,10 @@ class StableBrowser {
1273
1503
  },
1274
1504
  ],
1275
1505
  };
1506
+ const _perf_t75 = Date.now();
1507
+ logEvent("[simpleClickType] before: clickType");
1276
1508
  await this.clickType(selectors, value, false, _params, options, world);
1509
+ logEvent(`[simpleClickType] after: clickType took ${Date.now() - _perf_t75}ms`);
1277
1510
  return;
1278
1511
  }
1279
1512
  }
@@ -1281,14 +1514,23 @@ class StableBrowser {
1281
1514
  if (performance.now() - startTime > timeout) {
1282
1515
  // throw e;
1283
1516
  try {
1517
+ const _perf_t76 = Date.now();
1518
+ logEvent("[simpleClickType] before: _commandError");
1284
1519
  await _commandError(state, "timeout looking for " + elementDescription, this);
1520
+ logEvent(`[simpleClickType] after: _commandError took ${Date.now() - _perf_t76}ms`);
1285
1521
  }
1286
1522
  finally {
1523
+ const _perf_t77 = Date.now();
1524
+ logEvent("[simpleClickType] before: _commandFinally");
1287
1525
  await _commandFinally(state, this);
1526
+ logEvent(`[simpleClickType] after: _commandFinally took ${Date.now() - _perf_t77}ms`);
1288
1527
  }
1289
1528
  }
1290
1529
  }
1530
+ const _perf_t78 = Date.now();
1531
+ logEvent("[simpleClickType] before: new Promise");
1291
1532
  await new Promise((resolve) => setTimeout(resolve, 3000));
1533
+ logEvent(`[simpleClickType] after: new Promise took ${Date.now() - _perf_t78}ms`);
1292
1534
  }
1293
1535
  }
1294
1536
  async click(selectors, _params, options = {}, world = null) {
@@ -1312,22 +1554,37 @@ class StableBrowser {
1312
1554
  }
1313
1555
  try {
1314
1556
  check_performance("click_preCommand", this.context, true);
1557
+ const _perf_t79 = Date.now();
1558
+ logEvent("[click] before: _preCommand");
1315
1559
  await _preCommand(state, this);
1560
+ logEvent(`[click] after: _preCommand took ${Date.now() - _perf_t79}ms`);
1316
1561
  check_performance("click_preCommand", this.context, false);
1562
+ const _perf_t80 = Date.now();
1563
+ logEvent("[click] before: performAction");
1317
1564
  await performAction("click", state.element, options, this, state, _params);
1565
+ logEvent(`[click] after: performAction took ${Date.now() - _perf_t80}ms`);
1318
1566
  if (!this.fastMode && !this.stepTags.includes("fast-mode")) {
1319
1567
  check_performance("click_waitForPageLoad", this.context, true);
1568
+ const _perf_t81 = Date.now();
1569
+ logEvent("[click] before: waitForPageLoad");
1320
1570
  await this.waitForPageLoad({ noSleep: true });
1571
+ logEvent(`[click] after: waitForPageLoad took ${Date.now() - _perf_t81}ms`);
1321
1572
  check_performance("click_waitForPageLoad", this.context, false);
1322
1573
  }
1323
1574
  return state.info;
1324
1575
  }
1325
1576
  catch (e) {
1577
+ const _perf_t82 = Date.now();
1578
+ logEvent("[click] before: _commandError");
1326
1579
  await _commandError(state, e, this);
1580
+ logEvent(`[click] after: _commandError took ${Date.now() - _perf_t82}ms`);
1327
1581
  }
1328
1582
  finally {
1329
1583
  check_performance("click_commandFinally", this.context, true);
1584
+ const _perf_t83 = Date.now();
1585
+ logEvent("[click] before: _commandFinally");
1330
1586
  await _commandFinally(state, this);
1587
+ logEvent(`[click] after: _commandFinally took ${Date.now() - _perf_t83}ms`);
1331
1588
  check_performance("click_commandFinally", this.context, false);
1332
1589
  check_performance("click_all ***", this.context, false);
1333
1590
  if (this.context.profile) {
@@ -1350,11 +1607,17 @@ class StableBrowser {
1350
1607
  };
1351
1608
  let found = false;
1352
1609
  try {
1610
+ const _perf_t84 = Date.now();
1611
+ logEvent("[waitForElement] before: _preCommand");
1353
1612
  await _preCommand(state, this);
1613
+ logEvent(`[waitForElement] after: _preCommand took ${Date.now() - _perf_t84}ms`);
1354
1614
  // if (state.options && state.options.context) {
1355
1615
  // state.selectors.locators[0].text = state.options.context;
1356
1616
  // }
1617
+ const _perf_t85 = Date.now();
1618
+ logEvent("[waitForElement] before: state.element.waitFor");
1357
1619
  await state.element.waitFor({ timeout: timeout });
1620
+ logEvent(`[waitForElement] after: state.element.waitFor took ${Date.now() - _perf_t85}ms`);
1358
1621
  found = true;
1359
1622
  // await new Promise((resolve) => setTimeout(resolve, 1000));
1360
1623
  }
@@ -1363,7 +1626,10 @@ class StableBrowser {
1363
1626
  // await _commandError(state, e, this);
1364
1627
  }
1365
1628
  finally {
1629
+ const _perf_t86 = Date.now();
1630
+ logEvent("[waitForElement] before: _commandFinally");
1366
1631
  await _commandFinally(state, this);
1632
+ logEvent(`[waitForElement] after: _commandFinally took ${Date.now() - _perf_t86}ms`);
1367
1633
  }
1368
1634
  return found;
1369
1635
  }
@@ -1380,16 +1646,28 @@ class StableBrowser {
1380
1646
  log: "***** check " + selectors.element_name + " *****\n",
1381
1647
  };
1382
1648
  try {
1649
+ const _perf_t87 = Date.now();
1650
+ logEvent("[setCheck] before: _preCommand");
1383
1651
  await _preCommand(state, this);
1652
+ logEvent(`[setCheck] after: _preCommand took ${Date.now() - _perf_t87}ms`);
1384
1653
  state.info.checked = checked;
1385
1654
  // let element = await this._locate(selectors, info, _params);
1386
1655
  // ({ screenshotId, screenshotPath } = await this._screenShot(options, world, info));
1387
1656
  try {
1388
1657
  // if (world && world.screenshot && !world.screenshotPath) {
1389
1658
  // console.log(`Highlighting while running from recorder`);
1659
+ const _perf_t88 = Date.now();
1660
+ logEvent("[setCheck] before: _highlightElements");
1390
1661
  await this._highlightElements(state.element);
1662
+ logEvent(`[setCheck] after: _highlightElements took ${Date.now() - _perf_t88}ms`);
1663
+ const _perf_t89 = Date.now();
1664
+ logEvent("[setCheck] before: state.element.setChecked");
1391
1665
  await state.element.setChecked(checked, { timeout: 2000 });
1666
+ logEvent(`[setCheck] after: state.element.setChecked took ${Date.now() - _perf_t89}ms`);
1667
+ const _perf_t90 = Date.now();
1668
+ logEvent("[setCheck] before: new Promise");
1392
1669
  await new Promise((resolve) => setTimeout(resolve, 1000));
1670
+ logEvent(`[setCheck] after: new Promise took ${Date.now() - _perf_t90}ms`);
1393
1671
  // await this._unHighlightElements(element);
1394
1672
  // }
1395
1673
  // await new Promise((resolve) => setTimeout(resolve, 1000));
@@ -1400,12 +1678,18 @@ class StableBrowser {
1400
1678
  this.logger.info("element did not change its state, ignoring...");
1401
1679
  }
1402
1680
  else {
1681
+ const _perf_t91 = Date.now();
1682
+ logEvent("[setCheck] before: new Promise");
1403
1683
  await new Promise((resolve) => setTimeout(resolve, 1000));
1684
+ logEvent(`[setCheck] after: new Promise took ${Date.now() - _perf_t91}ms`);
1404
1685
  //await this.closeUnexpectedPopups();
1405
1686
  state.info.log += "setCheck failed, will try again" + "\n";
1406
1687
  state.element_found = false;
1407
1688
  try {
1689
+ const _perf_t92 = Date.now();
1690
+ logEvent("[setCheck] before: _locate");
1408
1691
  state.element = await this._locate(selectors, state.info, _params, 100);
1692
+ logEvent(`[setCheck] after: _locate took ${Date.now() - _perf_t92}ms`);
1409
1693
  state.element_found = true;
1410
1694
  // check the check state
1411
1695
  }
@@ -1413,10 +1697,16 @@ class StableBrowser {
1413
1697
  // element dismissed
1414
1698
  }
1415
1699
  if (state.element_found) {
1700
+ const _perf_t93 = Date.now();
1701
+ logEvent("[setCheck] before: state.element.isChecked");
1416
1702
  const isChecked = await state.element.isChecked();
1703
+ logEvent(`[setCheck] after: state.element.isChecked took ${Date.now() - _perf_t93}ms`);
1417
1704
  if (isChecked !== checked) {
1418
1705
  // perform click
1706
+ const _perf_t94 = Date.now();
1707
+ logEvent("[setCheck] before: state.element.click");
1419
1708
  await state.element.click({ timeout: 2000, force: true });
1709
+ logEvent(`[setCheck] after: state.element.click took ${Date.now() - _perf_t94}ms`);
1420
1710
  }
1421
1711
  else {
1422
1712
  this.logger.info(`Element ${selectors.element_name} is already in the desired state (${checked})`);
@@ -1428,10 +1718,16 @@ class StableBrowser {
1428
1718
  return state.info;
1429
1719
  }
1430
1720
  catch (e) {
1721
+ const _perf_t95 = Date.now();
1722
+ logEvent("[setCheck] before: _commandError");
1431
1723
  await _commandError(state, e, this);
1724
+ logEvent(`[setCheck] after: _commandError took ${Date.now() - _perf_t95}ms`);
1432
1725
  }
1433
1726
  finally {
1727
+ const _perf_t96 = Date.now();
1728
+ logEvent("[setCheck] before: _commandFinally");
1434
1729
  await _commandFinally(state, this);
1730
+ logEvent(`[setCheck] after: _commandFinally took ${Date.now() - _perf_t96}ms`);
1435
1731
  }
1436
1732
  }
1437
1733
  async hover(selectors, _params, options = {}, world = null) {
@@ -1447,17 +1743,32 @@ class StableBrowser {
1447
1743
  log: "***** hover " + selectors.element_name + " *****\n",
1448
1744
  };
1449
1745
  try {
1746
+ const _perf_t97 = Date.now();
1747
+ logEvent("[hover] before: _preCommand");
1450
1748
  await _preCommand(state, this);
1749
+ logEvent(`[hover] after: _preCommand took ${Date.now() - _perf_t97}ms`);
1750
+ const _perf_t98 = Date.now();
1751
+ logEvent("[hover] before: performAction");
1451
1752
  await performAction("hover", state.element, options, this, state, _params);
1753
+ logEvent(`[hover] after: performAction took ${Date.now() - _perf_t98}ms`);
1754
+ const _perf_t99 = Date.now();
1755
+ logEvent("[hover] before: _screenshot");
1452
1756
  await _screenshot(state, this);
1757
+ logEvent(`[hover] after: _screenshot took ${Date.now() - _perf_t99}ms`);
1453
1758
  //await this.waitForPageLoad();
1454
1759
  return state.info;
1455
1760
  }
1456
1761
  catch (e) {
1762
+ const _perf_t100 = Date.now();
1763
+ logEvent("[hover] before: _commandError");
1457
1764
  await _commandError(state, e, this);
1765
+ logEvent(`[hover] after: _commandError took ${Date.now() - _perf_t100}ms`);
1458
1766
  }
1459
1767
  finally {
1768
+ const _perf_t101 = Date.now();
1769
+ logEvent("[hover] before: _commandFinally");
1460
1770
  await _commandFinally(state, this);
1771
+ logEvent(`[hover] after: _commandFinally took ${Date.now() - _perf_t101}ms`);
1461
1772
  }
1462
1773
  }
1463
1774
  async selectOption(selectors, values, _params = null, options = {}, world = null) {
@@ -1478,23 +1789,38 @@ class StableBrowser {
1478
1789
  log: "***** select option " + selectors.element_name + " *****\n",
1479
1790
  };
1480
1791
  try {
1792
+ const _perf_t102 = Date.now();
1793
+ logEvent("[selectOption] before: _preCommand");
1481
1794
  await _preCommand(state, this);
1795
+ logEvent(`[selectOption] after: _preCommand took ${Date.now() - _perf_t102}ms`);
1482
1796
  try {
1797
+ const _perf_t103 = Date.now();
1798
+ logEvent("[selectOption] before: state.element.selectOption");
1483
1799
  await state.element.selectOption(values);
1800
+ logEvent(`[selectOption] after: state.element.selectOption took ${Date.now() - _perf_t103}ms`);
1484
1801
  }
1485
1802
  catch (e) {
1486
1803
  //await this.closeUnexpectedPopups();
1487
1804
  state.info.log += "selectOption failed, will try force" + "\n";
1805
+ const _perf_t104 = Date.now();
1806
+ logEvent("[selectOption] before: state.element.selectOption");
1488
1807
  await state.element.selectOption(values, { timeout: 10000, force: true });
1808
+ logEvent(`[selectOption] after: state.element.selectOption took ${Date.now() - _perf_t104}ms`);
1489
1809
  }
1490
1810
  //await this.waitForPageLoad();
1491
1811
  return state.info;
1492
1812
  }
1493
1813
  catch (e) {
1814
+ const _perf_t105 = Date.now();
1815
+ logEvent("[selectOption] before: _commandError");
1494
1816
  await _commandError(state, e, this);
1817
+ logEvent(`[selectOption] after: _commandError took ${Date.now() - _perf_t105}ms`);
1495
1818
  }
1496
1819
  finally {
1820
+ const _perf_t106 = Date.now();
1821
+ logEvent("[selectOption] before: _commandFinally");
1497
1822
  await _commandFinally(state, this);
1823
+ logEvent(`[selectOption] after: _commandFinally took ${Date.now() - _perf_t106}ms`);
1498
1824
  }
1499
1825
  }
1500
1826
  async type(_value, _params = null, options = {}, world = null) {
@@ -1513,14 +1839,23 @@ class StableBrowser {
1513
1839
  log: "",
1514
1840
  };
1515
1841
  try {
1842
+ const _perf_t107 = Date.now();
1843
+ logEvent("[type] before: _preCommand");
1516
1844
  await _preCommand(state, this);
1845
+ logEvent(`[type] after: _preCommand took ${Date.now() - _perf_t107}ms`);
1517
1846
  const valueSegment = state.value.split("&&");
1518
1847
  for (let i = 0; i < valueSegment.length; i++) {
1519
1848
  if (i > 0) {
1849
+ const _perf_t108 = Date.now();
1850
+ logEvent("[type] before: new Promise");
1520
1851
  await new Promise((resolve) => setTimeout(resolve, 1000));
1852
+ logEvent(`[type] after: new Promise took ${Date.now() - _perf_t108}ms`);
1521
1853
  }
1522
1854
  let value = valueSegment[i];
1855
+ const _perf_t109 = Date.now();
1856
+ logEvent("[type] before: _replaceWithLocalData");
1523
1857
  value = await this._replaceWithLocalData(value, this);
1858
+ logEvent(`[type] after: _replaceWithLocalData took ${Date.now() - _perf_t109}ms`);
1524
1859
  let keyEvent = false;
1525
1860
  KEYBOARD_EVENTS.forEach((event) => {
1526
1861
  if (value === event || value.startsWith(event + "+")) {
@@ -1528,19 +1863,31 @@ class StableBrowser {
1528
1863
  }
1529
1864
  });
1530
1865
  if (keyEvent) {
1866
+ const _perf_t110 = Date.now();
1867
+ logEvent("[type] before: page.keyboard.press");
1531
1868
  await this.page.keyboard.press(value);
1869
+ logEvent(`[type] after: page.keyboard.press took ${Date.now() - _perf_t110}ms`);
1532
1870
  }
1533
1871
  else {
1872
+ const _perf_t111 = Date.now();
1873
+ logEvent("[type] before: page.keyboard.type");
1534
1874
  await this.page.keyboard.type(value);
1875
+ logEvent(`[type] after: page.keyboard.type took ${Date.now() - _perf_t111}ms`);
1535
1876
  }
1536
1877
  }
1537
1878
  return state.info;
1538
1879
  }
1539
1880
  catch (e) {
1881
+ const _perf_t112 = Date.now();
1882
+ logEvent("[type] before: _commandError");
1540
1883
  await _commandError(state, e, this);
1884
+ logEvent(`[type] after: _commandError took ${Date.now() - _perf_t112}ms`);
1541
1885
  }
1542
1886
  finally {
1887
+ const _perf_t113 = Date.now();
1888
+ logEvent("[type] before: _commandFinally");
1543
1889
  await _commandFinally(state, this);
1890
+ logEvent(`[type] after: _commandFinally took ${Date.now() - _perf_t113}ms`);
1544
1891
  }
1545
1892
  }
1546
1893
  async setInputValue(selectors, value, _params = null, options = {}, world = null) {
@@ -1556,27 +1903,48 @@ class StableBrowser {
1556
1903
  log: "***** set input value " + selectors.element_name + " *****\n",
1557
1904
  };
1558
1905
  try {
1906
+ const _perf_t114 = Date.now();
1907
+ logEvent("[setInputValue] before: _preCommand");
1559
1908
  await _preCommand(state, this);
1909
+ logEvent(`[setInputValue] after: _preCommand took ${Date.now() - _perf_t114}ms`);
1910
+ const _perf_t115 = Date.now();
1911
+ logEvent("[setInputValue] before: _replaceWithLocalData");
1560
1912
  let value = await this._replaceWithLocalData(state.value, this);
1913
+ logEvent(`[setInputValue] after: _replaceWithLocalData took ${Date.now() - _perf_t115}ms`);
1561
1914
  try {
1915
+ const _perf_t116 = Date.now();
1916
+ logEvent("[setInputValue] before: state.element.evaluateHandle");
1562
1917
  await state.element.evaluateHandle((el, value) => {
1563
1918
  el.value = value;
1564
1919
  }, value);
1920
+ logEvent(`[setInputValue] after: state.element.evaluateHandle took ${Date.now() - _perf_t116}ms`);
1565
1921
  }
1566
1922
  catch (error) {
1567
1923
  this.logger.error("setInputValue failed, will try again");
1924
+ const _perf_t117 = Date.now();
1925
+ logEvent("[setInputValue] before: _screenshot");
1568
1926
  await _screenshot(state, this);
1927
+ logEvent(`[setInputValue] after: _screenshot took ${Date.now() - _perf_t117}ms`);
1569
1928
  Object.assign(error, { info: state.info });
1929
+ const _perf_t118 = Date.now();
1930
+ logEvent("[setInputValue] before: state.element.evaluateHandle");
1570
1931
  await state.element.evaluateHandle((el, value) => {
1571
1932
  el.value = value;
1572
1933
  });
1934
+ logEvent(`[setInputValue] after: state.element.evaluateHandle took ${Date.now() - _perf_t118}ms`);
1573
1935
  }
1574
1936
  }
1575
1937
  catch (e) {
1938
+ const _perf_t119 = Date.now();
1939
+ logEvent("[setInputValue] before: _commandError");
1576
1940
  await _commandError(state, e, this);
1941
+ logEvent(`[setInputValue] after: _commandError took ${Date.now() - _perf_t119}ms`);
1577
1942
  }
1578
1943
  finally {
1944
+ const _perf_t120 = Date.now();
1945
+ logEvent("[setInputValue] before: _commandFinally");
1579
1946
  await _commandFinally(state, this);
1947
+ logEvent(`[setInputValue] after: _commandFinally took ${Date.now() - _perf_t120}ms`);
1580
1948
  }
1581
1949
  }
1582
1950
  async setDateTime(selectors, value, format = null, enter = false, _params = null, options = {}, world = null) {
@@ -1594,63 +1962,126 @@ class StableBrowser {
1594
1962
  // throwError: false,
1595
1963
  };
1596
1964
  try {
1965
+ const _perf_t121 = Date.now();
1966
+ logEvent("[setDateTime] before: _preCommand");
1597
1967
  await _preCommand(state, this);
1968
+ logEvent(`[setDateTime] after: _preCommand took ${Date.now() - _perf_t121}ms`);
1598
1969
  try {
1970
+ const _perf_t122 = Date.now();
1971
+ logEvent("[setDateTime] before: performAction");
1599
1972
  await performAction("click", state.element, options, this, state, _params);
1973
+ logEvent(`[setDateTime] after: performAction took ${Date.now() - _perf_t122}ms`);
1974
+ const _perf_t123 = Date.now();
1975
+ logEvent("[setDateTime] before: new Promise");
1600
1976
  await new Promise((resolve) => setTimeout(resolve, 500));
1977
+ logEvent(`[setDateTime] after: new Promise took ${Date.now() - _perf_t123}ms`);
1601
1978
  if (format) {
1602
1979
  state.value = dayjs(state.value).format(format);
1980
+ const _perf_t124 = Date.now();
1981
+ logEvent("[setDateTime] before: state.element.fill");
1603
1982
  await state.element.fill(state.value);
1983
+ logEvent(`[setDateTime] after: state.element.fill took ${Date.now() - _perf_t124}ms`);
1604
1984
  }
1605
1985
  else {
1986
+ const _perf_t125 = Date.now();
1987
+ logEvent("[setDateTime] before: getDateTimeValue");
1606
1988
  const dateTimeValue = await getDateTimeValue({ value: state.value, element: state.element });
1989
+ logEvent(`[setDateTime] after: getDateTimeValue took ${Date.now() - _perf_t125}ms`);
1990
+ const _perf_t126 = Date.now();
1991
+ logEvent("[setDateTime] before: state.element.evaluateHandle");
1607
1992
  await state.element.evaluateHandle((el, dateTimeValue) => {
1608
1993
  el.value = ""; // clear input
1609
1994
  el.value = dateTimeValue;
1610
1995
  }, dateTimeValue);
1996
+ logEvent(`[setDateTime] after: state.element.evaluateHandle took ${Date.now() - _perf_t126}ms`);
1611
1997
  }
1612
1998
  if (enter) {
1999
+ const _perf_t127 = Date.now();
2000
+ logEvent("[setDateTime] before: new Promise");
1613
2001
  await new Promise((resolve) => setTimeout(resolve, 2000));
2002
+ logEvent(`[setDateTime] after: new Promise took ${Date.now() - _perf_t127}ms`);
2003
+ const _perf_t128 = Date.now();
2004
+ logEvent("[setDateTime] before: page.keyboard.press");
1614
2005
  await this.page.keyboard.press("Enter");
2006
+ logEvent(`[setDateTime] after: page.keyboard.press took ${Date.now() - _perf_t128}ms`);
2007
+ const _perf_t129 = Date.now();
2008
+ logEvent("[setDateTime] before: waitForPageLoad");
1615
2009
  await this.waitForPageLoad();
2010
+ logEvent(`[setDateTime] after: waitForPageLoad took ${Date.now() - _perf_t129}ms`);
1616
2011
  }
1617
2012
  }
1618
2013
  catch (err) {
1619
2014
  //await this.closeUnexpectedPopups();
1620
2015
  this.logger.error("setting date time input failed " + JSON.stringify(state.info));
1621
2016
  this.logger.info("Trying again");
2017
+ const _perf_t130 = Date.now();
2018
+ logEvent("[setDateTime] before: _screenshot");
1622
2019
  await _screenshot(state, this);
2020
+ logEvent(`[setDateTime] after: _screenshot took ${Date.now() - _perf_t130}ms`);
1623
2021
  Object.assign(err, { info: state.info });
2022
+ const _perf_t131 = Date.now();
2023
+ logEvent("[setDateTime] before: element.click");
1624
2024
  await element.click();
2025
+ logEvent(`[setDateTime] after: element.click took ${Date.now() - _perf_t131}ms`);
2026
+ const _perf_t132 = Date.now();
2027
+ logEvent("[setDateTime] before: new Promise");
1625
2028
  await new Promise((resolve) => setTimeout(resolve, 500));
2029
+ logEvent(`[setDateTime] after: new Promise took ${Date.now() - _perf_t132}ms`);
1626
2030
  if (format) {
1627
2031
  state.value = dayjs(state.value).format(format);
2032
+ const _perf_t133 = Date.now();
2033
+ logEvent("[setDateTime] before: state.element.fill");
1628
2034
  await state.element.fill(state.value);
2035
+ logEvent(`[setDateTime] after: state.element.fill took ${Date.now() - _perf_t133}ms`);
1629
2036
  }
1630
2037
  else {
2038
+ const _perf_t134 = Date.now();
2039
+ logEvent("[setDateTime] before: getDateTimeValue");
1631
2040
  const dateTimeValue = await getDateTimeValue({ value: state.value, element: state.element });
2041
+ logEvent(`[setDateTime] after: getDateTimeValue took ${Date.now() - _perf_t134}ms`);
2042
+ const _perf_t135 = Date.now();
2043
+ logEvent("[setDateTime] before: state.element.evaluateHandle");
1632
2044
  await state.element.evaluateHandle((el, dateTimeValue) => {
1633
2045
  el.value = ""; // clear input
1634
2046
  el.value = dateTimeValue;
1635
2047
  }, dateTimeValue);
2048
+ logEvent(`[setDateTime] after: state.element.evaluateHandle took ${Date.now() - _perf_t135}ms`);
1636
2049
  }
1637
2050
  if (enter) {
2051
+ const _perf_t136 = Date.now();
2052
+ logEvent("[setDateTime] before: new Promise");
1638
2053
  await new Promise((resolve) => setTimeout(resolve, 2000));
2054
+ logEvent(`[setDateTime] after: new Promise took ${Date.now() - _perf_t136}ms`);
2055
+ const _perf_t137 = Date.now();
2056
+ logEvent("[setDateTime] before: page.keyboard.press");
1639
2057
  await this.page.keyboard.press("Enter");
2058
+ logEvent(`[setDateTime] after: page.keyboard.press took ${Date.now() - _perf_t137}ms`);
2059
+ const _perf_t138 = Date.now();
2060
+ logEvent("[setDateTime] before: waitForPageLoad");
1640
2061
  await this.waitForPageLoad();
2062
+ logEvent(`[setDateTime] after: waitForPageLoad took ${Date.now() - _perf_t138}ms`);
1641
2063
  }
1642
2064
  }
1643
2065
  }
1644
2066
  catch (e) {
2067
+ const _perf_t139 = Date.now();
2068
+ logEvent("[setDateTime] before: _commandError");
1645
2069
  await _commandError(state, e, this);
2070
+ logEvent(`[setDateTime] after: _commandError took ${Date.now() - _perf_t139}ms`);
1646
2071
  }
1647
2072
  finally {
2073
+ const _perf_t140 = Date.now();
2074
+ logEvent("[setDateTime] before: _commandFinally");
1648
2075
  await _commandFinally(state, this);
2076
+ logEvent(`[setDateTime] after: _commandFinally took ${Date.now() - _perf_t140}ms`);
1649
2077
  }
1650
2078
  }
1651
2079
  async clickType(selectors, _value, enter = false, _params = null, options = {}, world = null) {
1652
2080
  _value = unEscapeString(_value);
2081
+ const _perf_t141 = Date.now();
2082
+ logEvent("[clickType] before: _replaceWithLocalData");
1653
2083
  const newValue = await this._replaceWithLocalData(_value, world);
2084
+ logEvent(`[clickType] after: _replaceWithLocalData took ${Date.now() - _perf_t141}ms`);
1654
2085
  const state = {
1655
2086
  selectors,
1656
2087
  _params,
@@ -1672,21 +2103,33 @@ class StableBrowser {
1672
2103
  _value = newValue;
1673
2104
  }
1674
2105
  try {
2106
+ const _perf_t142 = Date.now();
2107
+ logEvent("[clickType] before: _preCommand");
1675
2108
  await _preCommand(state, this);
2109
+ logEvent(`[clickType] after: _preCommand took ${Date.now() - _perf_t142}ms`);
1676
2110
  const randomToken = "blinq_" + Math.random().toString(36).substring(7);
1677
2111
  // tag the element
2112
+ const _perf_t143 = Date.now();
2113
+ logEvent("[clickType] before: state.element.evaluate");
1678
2114
  let newElementSelector = await state.element.evaluate((el, token) => {
1679
2115
  // use attribute and not id
1680
2116
  const attrName = `data-blinq-id-${token}`;
1681
2117
  el.setAttribute(attrName, "");
1682
2118
  return `[${attrName}]`;
1683
2119
  }, randomToken);
2120
+ logEvent(`[clickType] after: state.element.evaluate took ${Date.now() - _perf_t143}ms`);
1684
2121
  state.info.value = _value;
1685
2122
  if (!options.press) {
1686
2123
  try {
2124
+ const _perf_t144 = Date.now();
2125
+ logEvent("[clickType] before: state.element.inputValue");
1687
2126
  let currentValue = await state.element.inputValue();
2127
+ logEvent(`[clickType] after: state.element.inputValue took ${Date.now() - _perf_t144}ms`);
1688
2128
  if (currentValue) {
2129
+ const _perf_t145 = Date.now();
2130
+ logEvent("[clickType] before: state.element.fill");
1689
2131
  await state.element.fill("");
2132
+ logEvent(`[clickType] after: state.element.fill took ${Date.now() - _perf_t145}ms`);
1690
2133
  }
1691
2134
  }
1692
2135
  catch (e) {
@@ -1695,19 +2138,34 @@ class StableBrowser {
1695
2138
  }
1696
2139
  if (options.press) {
1697
2140
  options.timeout = 5000;
2141
+ const _perf_t146 = Date.now();
2142
+ logEvent("[clickType] before: performAction");
1698
2143
  await performAction("click", state.element, options, this, state, _params);
2144
+ logEvent(`[clickType] after: performAction took ${Date.now() - _perf_t146}ms`);
1699
2145
  }
1700
2146
  else {
1701
2147
  try {
2148
+ const _perf_t147 = Date.now();
2149
+ logEvent("[clickType] before: state.element.focus");
1702
2150
  await state.element.focus();
2151
+ logEvent(`[clickType] after: state.element.focus took ${Date.now() - _perf_t147}ms`);
1703
2152
  }
1704
2153
  catch (e) {
2154
+ const _perf_t148 = Date.now();
2155
+ logEvent("[clickType] before: state.element.dispatchEvent");
1705
2156
  await state.element.dispatchEvent("focus");
2157
+ logEvent(`[clickType] after: state.element.dispatchEvent took ${Date.now() - _perf_t148}ms`);
1706
2158
  }
1707
2159
  }
2160
+ const _perf_t149 = Date.now();
2161
+ logEvent("[clickType] before: new Promise");
1708
2162
  await new Promise((resolve) => setTimeout(resolve, 500));
2163
+ logEvent(`[clickType] after: new Promise took ${Date.now() - _perf_t149}ms`);
1709
2164
  // check if the element exist after the click (no wait)
2165
+ const _perf_t150 = Date.now();
2166
+ logEvent("[clickType] before: state.element.count");
1710
2167
  const count = await state.element.count({ timeout: 0 });
2168
+ logEvent(`[clickType] after: state.element.count took ${Date.now() - _perf_t150}ms`);
1711
2169
  if (count === 0) {
1712
2170
  // the locator changed after the click (placeholder) we need to locate the element using the data-blinq-id
1713
2171
  const scope = state.element._frame ?? element.page();
@@ -1728,7 +2186,10 @@ class StableBrowser {
1728
2186
  const valueSegment = state.value.split("&&");
1729
2187
  for (let i = 0; i < valueSegment.length; i++) {
1730
2188
  if (i > 0) {
2189
+ const _perf_t151 = Date.now();
2190
+ logEvent("[clickType] before: new Promise");
1731
2191
  await new Promise((resolve) => setTimeout(resolve, 1000));
2192
+ logEvent(`[clickType] after: new Promise took ${Date.now() - _perf_t151}ms`);
1732
2193
  }
1733
2194
  let value = valueSegment[i];
1734
2195
  let keyEvent = false;
@@ -1738,24 +2199,48 @@ class StableBrowser {
1738
2199
  }
1739
2200
  });
1740
2201
  if (keyEvent) {
2202
+ const _perf_t152 = Date.now();
2203
+ logEvent("[clickType] before: page.keyboard.press");
1741
2204
  await this.page.keyboard.press(value);
2205
+ logEvent(`[clickType] after: page.keyboard.press took ${Date.now() - _perf_t152}ms`);
1742
2206
  }
1743
2207
  else {
2208
+ const _perf_t153 = Date.now();
2209
+ logEvent("[clickType] before: page.keyboard.type");
1744
2210
  await this.page.keyboard.type(value);
2211
+ logEvent(`[clickType] after: page.keyboard.type took ${Date.now() - _perf_t153}ms`);
2212
+ const _perf_t154 = Date.now();
2213
+ logEvent("[clickType] before: new Promise");
1745
2214
  await new Promise((resolve) => setTimeout(resolve, 500));
2215
+ logEvent(`[clickType] after: new Promise took ${Date.now() - _perf_t154}ms`);
1746
2216
  }
1747
2217
  }
1748
2218
  //if (!this.fastMode) {
2219
+ const _perf_t155 = Date.now();
2220
+ logEvent("[clickType] before: _screenshot");
1749
2221
  await _screenshot(state, this);
2222
+ logEvent(`[clickType] after: _screenshot took ${Date.now() - _perf_t155}ms`);
1750
2223
  //}
1751
2224
  if (enter === true) {
2225
+ const _perf_t156 = Date.now();
2226
+ logEvent("[clickType] before: new Promise");
1752
2227
  await new Promise((resolve) => setTimeout(resolve, 2000));
2228
+ logEvent(`[clickType] after: new Promise took ${Date.now() - _perf_t156}ms`);
2229
+ const _perf_t157 = Date.now();
2230
+ logEvent("[clickType] before: page.keyboard.press");
1753
2231
  await this.page.keyboard.press("Enter");
2232
+ logEvent(`[clickType] after: page.keyboard.press took ${Date.now() - _perf_t157}ms`);
2233
+ const _perf_t158 = Date.now();
2234
+ logEvent("[clickType] before: waitForPageLoad");
1754
2235
  await this.waitForPageLoad();
2236
+ logEvent(`[clickType] after: waitForPageLoad took ${Date.now() - _perf_t158}ms`);
1755
2237
  }
1756
2238
  else if (enter === false) {
1757
2239
  try {
2240
+ const _perf_t159 = Date.now();
2241
+ logEvent("[clickType] before: state.element.dispatchEvent");
1758
2242
  await state.element.dispatchEvent("change", null, { timeout: 5000 });
2243
+ logEvent(`[clickType] after: state.element.dispatchEvent took ${Date.now() - _perf_t159}ms`);
1759
2244
  }
1760
2245
  catch (e) {
1761
2246
  // ignore
@@ -1764,17 +2249,29 @@ class StableBrowser {
1764
2249
  }
1765
2250
  else {
1766
2251
  if (enter !== "" && enter !== null && enter !== undefined) {
2252
+ const _perf_t160 = Date.now();
2253
+ logEvent("[clickType] before: page.keyboard.press");
1767
2254
  await this.page.keyboard.press(enter);
2255
+ logEvent(`[clickType] after: page.keyboard.press took ${Date.now() - _perf_t160}ms`);
2256
+ const _perf_t161 = Date.now();
2257
+ logEvent("[clickType] before: waitForPageLoad");
1768
2258
  await this.waitForPageLoad();
2259
+ logEvent(`[clickType] after: waitForPageLoad took ${Date.now() - _perf_t161}ms`);
1769
2260
  }
1770
2261
  }
1771
2262
  return state.info;
1772
2263
  }
1773
2264
  catch (e) {
2265
+ const _perf_t162 = Date.now();
2266
+ logEvent("[clickType] before: _commandError");
1774
2267
  await _commandError(state, e, this);
2268
+ logEvent(`[clickType] after: _commandError took ${Date.now() - _perf_t162}ms`);
1775
2269
  }
1776
2270
  finally {
2271
+ const _perf_t163 = Date.now();
2272
+ logEvent("[clickType] before: _commandFinally");
1777
2273
  await _commandFinally(state, this);
2274
+ logEvent(`[clickType] after: _commandFinally took ${Date.now() - _perf_t163}ms`);
1778
2275
  }
1779
2276
  }
1780
2277
  async fill(selectors, value, enter = false, _params = null, options = {}, world = null) {
@@ -1790,21 +2287,45 @@ class StableBrowser {
1790
2287
  log: "***** fill on " + selectors.element_name + " with value " + value + "*****\n",
1791
2288
  };
1792
2289
  try {
2290
+ const _perf_t164 = Date.now();
2291
+ logEvent("[fill] before: _preCommand");
1793
2292
  await _preCommand(state, this);
2293
+ logEvent(`[fill] after: _preCommand took ${Date.now() - _perf_t164}ms`);
2294
+ const _perf_t165 = Date.now();
2295
+ logEvent("[fill] before: state.element.fill");
1794
2296
  await state.element.fill(value);
2297
+ logEvent(`[fill] after: state.element.fill took ${Date.now() - _perf_t165}ms`);
2298
+ const _perf_t166 = Date.now();
2299
+ logEvent("[fill] before: state.element.dispatchEvent");
1795
2300
  await state.element.dispatchEvent("change");
2301
+ logEvent(`[fill] after: state.element.dispatchEvent took ${Date.now() - _perf_t166}ms`);
1796
2302
  if (enter) {
2303
+ const _perf_t167 = Date.now();
2304
+ logEvent("[fill] before: new Promise");
1797
2305
  await new Promise((resolve) => setTimeout(resolve, 2000));
2306
+ logEvent(`[fill] after: new Promise took ${Date.now() - _perf_t167}ms`);
2307
+ const _perf_t168 = Date.now();
2308
+ logEvent("[fill] before: page.keyboard.press");
1798
2309
  await this.page.keyboard.press("Enter");
2310
+ logEvent(`[fill] after: page.keyboard.press took ${Date.now() - _perf_t168}ms`);
2311
+ const _perf_t169 = Date.now();
2312
+ logEvent("[fill] before: waitForPageLoad");
1799
2313
  await this.waitForPageLoad();
2314
+ logEvent(`[fill] after: waitForPageLoad took ${Date.now() - _perf_t169}ms`);
1800
2315
  }
1801
2316
  return state.info;
1802
2317
  }
1803
2318
  catch (e) {
2319
+ const _perf_t170 = Date.now();
2320
+ logEvent("[fill] before: _commandError");
1804
2321
  await _commandError(state, e, this);
2322
+ logEvent(`[fill] after: _commandError took ${Date.now() - _perf_t170}ms`);
1805
2323
  }
1806
2324
  finally {
2325
+ const _perf_t171 = Date.now();
2326
+ logEvent("[fill] before: _commandFinally");
1807
2327
  await _commandFinally(state, this);
2328
+ logEvent(`[fill] after: _commandFinally took ${Date.now() - _perf_t171}ms`);
1808
2329
  }
1809
2330
  }
1810
2331
  async setInputFiles(selectors, files, _params = null, options = {}, world = null) {
@@ -1823,7 +2344,10 @@ class StableBrowser {
1823
2344
  };
1824
2345
  const uploadsFolder = this.configuration.uploadsFolder ?? "data/uploads";
1825
2346
  try {
2347
+ const _perf_t172 = Date.now();
2348
+ logEvent("[setInputFiles] before: _preCommand");
1826
2349
  await _preCommand(state, this);
2350
+ logEvent(`[setInputFiles] after: _preCommand took ${Date.now() - _perf_t172}ms`);
1827
2351
  for (let i = 0; i < files.length; i++) {
1828
2352
  const file = files[i];
1829
2353
  const filePath = path.join(uploadsFolder, file);
@@ -1832,18 +2356,30 @@ class StableBrowser {
1832
2356
  }
1833
2357
  state.files[i] = filePath;
1834
2358
  }
2359
+ const _perf_t173 = Date.now();
2360
+ logEvent("[setInputFiles] before: state.element.setInputFiles");
1835
2361
  await state.element.setInputFiles(files);
2362
+ logEvent(`[setInputFiles] after: state.element.setInputFiles took ${Date.now() - _perf_t173}ms`);
1836
2363
  return state.info;
1837
2364
  }
1838
2365
  catch (e) {
2366
+ const _perf_t174 = Date.now();
2367
+ logEvent("[setInputFiles] before: _commandError");
1839
2368
  await _commandError(state, e, this);
2369
+ logEvent(`[setInputFiles] after: _commandError took ${Date.now() - _perf_t174}ms`);
1840
2370
  }
1841
2371
  finally {
2372
+ const _perf_t175 = Date.now();
2373
+ logEvent("[setInputFiles] before: _commandFinally");
1842
2374
  await _commandFinally(state, this);
2375
+ logEvent(`[setInputFiles] after: _commandFinally took ${Date.now() - _perf_t175}ms`);
1843
2376
  }
1844
2377
  }
1845
2378
  async getText(selectors, _params = null, options = {}, info = {}, world = null) {
2379
+ const _perf_t176 = Date.now();
2380
+ logEvent("[getText] before: _getText");
1846
2381
  return await this._getText(selectors, 0, _params, options, info, world);
2382
+ logEvent(`[getText] after: _getText took ${Date.now() - _perf_t176}ms`);
1847
2383
  }
1848
2384
  async _getText(selectors, climb, _params = null, options = {}, info = {}, world = null) {
1849
2385
  const timeout = this._getFindElementTimeout(options);
@@ -1856,7 +2392,10 @@ class StableBrowser {
1856
2392
  }
1857
2393
  info.operation = "getText";
1858
2394
  info.selectors = selectors;
2395
+ const _perf_t177 = Date.now();
2396
+ logEvent("[_getText] before: _locate");
1859
2397
  let element = await this._locate(selectors, info, _params, timeout);
2398
+ logEvent(`[_getText] after: _locate took ${Date.now() - _perf_t177}ms`);
1860
2399
  if (climb > 0) {
1861
2400
  const climbArray = [];
1862
2401
  for (let i = 0; i < climb; i++) {
@@ -1867,14 +2406,20 @@ class StableBrowser {
1867
2406
  }
1868
2407
  let value = null;
1869
2408
  try {
2409
+ const _perf_t178 = Date.now();
2410
+ logEvent("[_getText] before: element.inputValue");
1870
2411
  value = await element.inputValue();
2412
+ logEvent(`[_getText] after: element.inputValue took ${Date.now() - _perf_t178}ms`);
1871
2413
  }
1872
2414
  catch (e) {
1873
2415
  //ignore
1874
2416
  }
1875
2417
  ({ screenshotId, screenshotPath } = await this._screenShot(options, world, info));
1876
2418
  try {
2419
+ const _perf_t179 = Date.now();
2420
+ logEvent("[_getText] before: _highlightElements");
1877
2421
  await this._highlightElements(element);
2422
+ logEvent(`[_getText] after: _highlightElements took ${Date.now() - _perf_t179}ms`);
1878
2423
  // if (world && world.screenshot && !world.screenshotPath) {
1879
2424
  // // console.log(`Highlighting for get text while running from recorder`);
1880
2425
  // this._highlightElements(element)
@@ -1887,7 +2432,10 @@ class StableBrowser {
1887
2432
  // })
1888
2433
  // .catch(e);
1889
2434
  // }
2435
+ const _perf_t180 = Date.now();
2436
+ logEvent("[_getText] before: element.innerText");
1890
2437
  const elementText = await element.innerText();
2438
+ logEvent(`[_getText] after: element.innerText took ${Date.now() - _perf_t180}ms`);
1891
2439
  return {
1892
2440
  text: elementText,
1893
2441
  screenshotId,
@@ -1899,7 +2447,10 @@ class StableBrowser {
1899
2447
  catch (e) {
1900
2448
  //await this.closeUnexpectedPopups();
1901
2449
  this.logger.info("no innerText, will use textContent");
2450
+ const _perf_t181 = Date.now();
2451
+ logEvent("[_getText] before: element.textContent");
1902
2452
  const elementText = await element.textContent();
2453
+ logEvent(`[_getText] after: element.textContent took ${Date.now() - _perf_t181}ms`);
1903
2454
  return { text: elementText, screenshotId, screenshotPath, value: value };
1904
2455
  }
1905
2456
  }
@@ -1927,20 +2478,35 @@ class StableBrowser {
1927
2478
  operation: "containsPattern",
1928
2479
  log: "***** verify element " + selectors.element_name + " contains pattern " + pattern + " *****\n",
1929
2480
  };
2481
+ const _perf_t182 = Date.now();
2482
+ logEvent("[containsPattern] before: _replaceWithLocalData");
1930
2483
  const newValue = await this._replaceWithLocalData(text, world);
2484
+ logEvent(`[containsPattern] after: _replaceWithLocalData took ${Date.now() - _perf_t182}ms`);
1931
2485
  if (newValue !== text) {
1932
2486
  this.logger.info(text + "=" + newValue);
1933
2487
  text = newValue;
1934
2488
  }
1935
2489
  let foundObj = null;
1936
2490
  try {
2491
+ const _perf_t183 = Date.now();
2492
+ logEvent("[containsPattern] before: _preCommand");
1937
2493
  await _preCommand(state, this);
2494
+ logEvent(`[containsPattern] after: _preCommand took ${Date.now() - _perf_t183}ms`);
1938
2495
  state.info.pattern = pattern;
2496
+ const _perf_t184 = Date.now();
2497
+ logEvent("[containsPattern] before: _getText");
1939
2498
  foundObj = await this._getText(selectors, 0, _params, options, state.info, world);
2499
+ logEvent(`[containsPattern] after: _getText took ${Date.now() - _perf_t184}ms`);
1940
2500
  if (foundObj && foundObj.element) {
2501
+ const _perf_t185 = Date.now();
2502
+ logEvent("[containsPattern] before: scrollIfNeeded");
1941
2503
  await this.scrollIfNeeded(foundObj.element, state.info);
2504
+ logEvent(`[containsPattern] after: scrollIfNeeded took ${Date.now() - _perf_t185}ms`);
1942
2505
  }
2506
+ const _perf_t186 = Date.now();
2507
+ logEvent("[containsPattern] before: _screenshot");
1943
2508
  await _screenshot(state, this);
2509
+ logEvent(`[containsPattern] after: _screenshot took ${Date.now() - _perf_t186}ms`);
1944
2510
  let escapedText = text.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, "\\$&");
1945
2511
  pattern = pattern.replace("{text}", escapedText);
1946
2512
  let regex = new RegExp(pattern, "im");
@@ -1952,10 +2518,16 @@ class StableBrowser {
1952
2518
  }
1953
2519
  catch (e) {
1954
2520
  this.logger.error("found text " + foundObj?.text + " pattern " + pattern);
2521
+ const _perf_t187 = Date.now();
2522
+ logEvent("[containsPattern] before: _commandError");
1955
2523
  await _commandError(state, e, this);
2524
+ logEvent(`[containsPattern] after: _commandError took ${Date.now() - _perf_t187}ms`);
1956
2525
  }
1957
2526
  finally {
2527
+ const _perf_t188 = Date.now();
2528
+ logEvent("[containsPattern] before: _commandFinally");
1958
2529
  await _commandFinally(state, this);
2530
+ logEvent(`[containsPattern] after: _commandFinally took ${Date.now() - _perf_t188}ms`);
1959
2531
  }
1960
2532
  }
1961
2533
  async containsText(selectors, text, climb, _params = null, options = {}, world = null) {
@@ -1980,7 +2552,10 @@ class StableBrowser {
1980
2552
  throw new Error("text is null");
1981
2553
  }
1982
2554
  text = unEscapeString(text);
2555
+ const _perf_t189 = Date.now();
2556
+ logEvent("[containsText] before: _replaceWithLocalData");
1983
2557
  const newValue = await this._replaceWithLocalData(text, world);
2558
+ logEvent(`[containsText] after: _replaceWithLocalData took ${Date.now() - _perf_t189}ms`);
1984
2559
  if (newValue !== text) {
1985
2560
  this.logger.info(text + "=" + newValue);
1986
2561
  text = newValue;
@@ -1989,12 +2564,24 @@ class StableBrowser {
1989
2564
  try {
1990
2565
  while (Date.now() - startTime < timeout) {
1991
2566
  try {
2567
+ const _perf_t190 = Date.now();
2568
+ logEvent("[containsText] before: _preCommand");
1992
2569
  await _preCommand(state, this);
2570
+ logEvent(`[containsText] after: _preCommand took ${Date.now() - _perf_t190}ms`);
2571
+ const _perf_t191 = Date.now();
2572
+ logEvent("[containsText] before: _getText");
1993
2573
  foundObj = await this._getText(selectors, climb, _params, { timeout: 3000 }, state.info, world);
2574
+ logEvent(`[containsText] after: _getText took ${Date.now() - _perf_t191}ms`);
1994
2575
  if (foundObj && foundObj.element) {
2576
+ const _perf_t192 = Date.now();
2577
+ logEvent("[containsText] before: scrollIfNeeded");
1995
2578
  await this.scrollIfNeeded(foundObj.element, state.info);
2579
+ logEvent(`[containsText] after: scrollIfNeeded took ${Date.now() - _perf_t192}ms`);
1996
2580
  }
2581
+ const _perf_t193 = Date.now();
2582
+ logEvent("[containsText] before: _screenshot");
1997
2583
  await _screenshot(state, this);
2584
+ logEvent(`[containsText] after: _screenshot took ${Date.now() - _perf_t193}ms`);
1998
2585
  const dateAlternatives = findDateAlternatives(text);
1999
2586
  const numberAlternatives = findNumberAlternatives(text);
2000
2587
  if (dateAlternatives.date) {
@@ -2021,18 +2608,27 @@ class StableBrowser {
2021
2608
  // Log error but continue retrying until timeout is reached
2022
2609
  this.logger.warn("Retrying containsText due to: " + e.message);
2023
2610
  }
2611
+ const _perf_t194 = Date.now();
2612
+ logEvent("[containsText] before: new Promise");
2024
2613
  await new Promise((resolve) => setTimeout(resolve, 1000)); // Wait 1 second before retrying
2025
2614
  }
2026
2615
  state.info.foundText = foundObj?.text;
2616
+ logEvent(`[containsText] after: new Promise took ${Date.now() - _perf_t194}ms`);
2027
2617
  state.info.value = foundObj?.value;
2028
2618
  throw new Error("element doesn't contain text " + text);
2029
2619
  }
2030
2620
  catch (e) {
2621
+ const _perf_t195 = Date.now();
2622
+ logEvent("[containsText] before: _commandError");
2031
2623
  await _commandError(state, e, this);
2624
+ logEvent(`[containsText] after: _commandError took ${Date.now() - _perf_t195}ms`);
2032
2625
  throw e;
2033
2626
  }
2034
2627
  finally {
2628
+ const _perf_t196 = Date.now();
2629
+ logEvent("[containsText] before: _commandFinally");
2035
2630
  await _commandFinally(state, this);
2631
+ logEvent(`[containsText] after: _commandFinally took ${Date.now() - _perf_t196}ms`);
2036
2632
  }
2037
2633
  }
2038
2634
  async snapshotValidation(frameSelectors, referanceSnapshot, _params = null, options = {}, world = null) {
@@ -2070,8 +2666,14 @@ class StableBrowser {
2070
2666
  throw new Error("referenceSnapshot file not found: " + referanceSnapshot);
2071
2667
  }
2072
2668
  state.text = text;
2669
+ const _perf_t197 = Date.now();
2670
+ logEvent("[snapshotValidation] before: _replaceWithLocalData");
2073
2671
  const newValue = await this._replaceWithLocalData(text, world);
2672
+ logEvent(`[snapshotValidation] after: _replaceWithLocalData took ${Date.now() - _perf_t197}ms`);
2673
+ const _perf_t198 = Date.now();
2674
+ logEvent("[snapshotValidation] before: _preCommand");
2074
2675
  await _preCommand(state, this);
2676
+ logEvent(`[snapshotValidation] after: _preCommand took ${Date.now() - _perf_t198}ms`);
2075
2677
  let foundObj = null;
2076
2678
  try {
2077
2679
  let matchResult = null;
@@ -2082,9 +2684,15 @@ class StableBrowser {
2082
2684
  scope = this.page;
2083
2685
  }
2084
2686
  else {
2687
+ const _perf_t199 = Date.now();
2688
+ logEvent("[snapshotValidation] before: _findFrameScope");
2085
2689
  scope = await this._findFrameScope(frameSelectors, timeout, state.info);
2690
+ logEvent(`[snapshotValidation] after: _findFrameScope took ${Date.now() - _perf_t199}ms`);
2086
2691
  }
2692
+ const _perf_t200 = Date.now();
2693
+ logEvent("[snapshotValidation] before: scope.locator");
2087
2694
  const snapshot = await scope.locator("body").ariaSnapshot({ timeout });
2695
+ logEvent(`[snapshotValidation] after: scope.locator took ${Date.now() - _perf_t200}ms`);
2088
2696
  if (snapshot && snapshot.length <= 10) {
2089
2697
  console.log("Page snapshot length is suspiciously small:", snapshot);
2090
2698
  }
@@ -2097,8 +2705,14 @@ class StableBrowser {
2097
2705
  }
2098
2706
  // highlight and screenshot
2099
2707
  try {
2708
+ const _perf_t201 = Date.now();
2709
+ logEvent("[snapshotValidation] before: await");
2100
2710
  await await highlightSnapshot(newValue, scope);
2711
+ logEvent(`[snapshotValidation] after: await took ${Date.now() - _perf_t201}ms`);
2712
+ const _perf_t202 = Date.now();
2713
+ logEvent("[snapshotValidation] before: _screenshot");
2101
2714
  await _screenshot(state, this);
2715
+ logEvent(`[snapshotValidation] after: _screenshot took ${Date.now() - _perf_t202}ms`);
2102
2716
  }
2103
2717
  catch (e) { }
2104
2718
  return state.info;
@@ -2107,16 +2721,25 @@ class StableBrowser {
2107
2721
  // Log error but continue retrying until timeout is reached
2108
2722
  //this.logger.warn("Retrying snapshot validation due to: " + e.message);
2109
2723
  }
2724
+ const _perf_t203 = Date.now();
2725
+ logEvent("[snapshotValidation] before: new Promise");
2110
2726
  await new Promise((resolve) => setTimeout(resolve, 2000)); // Wait 1 second before retrying
2111
2727
  }
2112
2728
  throw new Error("No snapshot match " + matchResult?.errorLineText);
2729
+ logEvent(`[snapshotValidation] after: new Promise took ${Date.now() - _perf_t203}ms`);
2113
2730
  }
2114
2731
  catch (e) {
2732
+ const _perf_t204 = Date.now();
2733
+ logEvent("[snapshotValidation] before: _commandError");
2115
2734
  await _commandError(state, e, this);
2735
+ logEvent(`[snapshotValidation] after: _commandError took ${Date.now() - _perf_t204}ms`);
2116
2736
  throw e;
2117
2737
  }
2118
2738
  finally {
2739
+ const _perf_t205 = Date.now();
2740
+ logEvent("[snapshotValidation] before: _commandFinally");
2119
2741
  await _commandFinally(state, this);
2742
+ logEvent(`[snapshotValidation] after: _commandFinally took ${Date.now() - _perf_t205}ms`);
2120
2743
  }
2121
2744
  }
2122
2745
  async waitForUserInput(message, world = null) {
@@ -2127,6 +2750,8 @@ class StableBrowser {
2127
2750
  message = "# Wait for user input. " + message;
2128
2751
  }
2129
2752
  message += "\n";
2753
+ const _perf_t206 = Date.now();
2754
+ logEvent("[waitForUserInput] before: new Promise");
2130
2755
  const value = await new Promise((resolve) => {
2131
2756
  const rl = readline.createInterface({
2132
2757
  input: process.stdin,
@@ -2137,6 +2762,7 @@ class StableBrowser {
2137
2762
  resolve(answer);
2138
2763
  });
2139
2764
  });
2765
+ logEvent(`[waitForUserInput] after: new Promise took ${Date.now() - _perf_t206}ms`);
2140
2766
  if (value) {
2141
2767
  this.logger.info(`{{userInput}} was set to: ${value}`);
2142
2768
  }
@@ -2240,7 +2866,10 @@ class StableBrowser {
2240
2866
  rowNumber = parseInt(parts[1]);
2241
2867
  }
2242
2868
  let dataFile = this._getDataFilePath(parts[0]);
2869
+ const _perf_t207 = Date.now();
2870
+ logEvent("[loadTestDataAsync] before: _parseCSVSync");
2243
2871
  const results = await this._parseCSVSync(dataFile);
2872
+ logEvent(`[loadTestDataAsync] after: _parseCSVSync took ${Date.now() - _perf_t207}ms`);
2244
2873
  // result stracture:
2245
2874
  // [
2246
2875
  // { NAME: 'Daffy Duck', AGE: '24' },
@@ -2269,7 +2898,10 @@ class StableBrowser {
2269
2898
  if (info) {
2270
2899
  if (!info.title) {
2271
2900
  try {
2901
+ const _perf_t208 = Date.now();
2902
+ logEvent("[_screenShot] before: page.title");
2272
2903
  info.title = await this.page.title();
2904
+ logEvent(`[_screenShot] after: page.title took ${Date.now() - _perf_t208}ms`);
2273
2905
  }
2274
2906
  catch (e) {
2275
2907
  // ignore
@@ -2293,7 +2925,10 @@ class StableBrowser {
2293
2925
  const uuidStr = "id_" + randomUUID();
2294
2926
  const screenshotPath = path.join(world.screenshotPath, uuidStr + ".png");
2295
2927
  try {
2928
+ const _perf_t209 = Date.now();
2929
+ logEvent("[_screenShot] before: takeScreenshot");
2296
2930
  await this.takeScreenshot(screenshotPath, options.fullPage === true);
2931
+ logEvent(`[_screenShot] after: takeScreenshot took ${Date.now() - _perf_t209}ms`);
2297
2932
  // let buffer = await this.page.screenshot({ timeout: 4000 });
2298
2933
  // // save the buffer to the screenshot path asynchrously
2299
2934
  // fs.writeFile(screenshotPath, buffer, (err) => {
@@ -2304,7 +2939,10 @@ class StableBrowser {
2304
2939
  result.screenshotId = uuidStr;
2305
2940
  result.screenshotPath = screenshotPath;
2306
2941
  if (info && info.box) {
2942
+ const _perf_t210 = Date.now();
2943
+ logEvent("[_screenShot] before: drawRectangle");
2307
2944
  await drawRectangle(screenshotPath, info.box.x, info.box.y, info.box.width, info.box.height);
2945
+ logEvent(`[_screenShot] after: drawRectangle took ${Date.now() - _perf_t210}ms`);
2308
2946
  }
2309
2947
  }
2310
2948
  catch (e) {
@@ -2314,7 +2952,10 @@ class StableBrowser {
2314
2952
  else if (options && options.screenshot) {
2315
2953
  result.screenshotPath = options.screenshotPath;
2316
2954
  try {
2955
+ const _perf_t211 = Date.now();
2956
+ logEvent("[_screenShot] before: takeScreenshot");
2317
2957
  await this.takeScreenshot(options.screenshotPath, options.fullPage === true);
2958
+ logEvent(`[_screenShot] after: takeScreenshot took ${Date.now() - _perf_t211}ms`);
2318
2959
  // let buffer = await this.page.screenshot({ timeout: 4000 });
2319
2960
  // // save the buffer to the screenshot path asynchrously
2320
2961
  // fs.writeFile(options.screenshotPath, buffer, (err) => {
@@ -2327,7 +2968,10 @@ class StableBrowser {
2327
2968
  this.logger.info("unable to take screenshot, ignored");
2328
2969
  }
2329
2970
  if (info && info.box) {
2971
+ const _perf_t212 = Date.now();
2972
+ logEvent("[_screenShot] before: drawRectangle");
2330
2973
  await drawRectangle(options.screenshotPath, info.box.x, info.box.y, info.box.width, info.box.height);
2974
+ logEvent(`[_screenShot] after: drawRectangle took ${Date.now() - _perf_t212}ms`);
2331
2975
  }
2332
2976
  }
2333
2977
  return result;
@@ -2354,32 +2998,50 @@ class StableBrowser {
2354
2998
  // await this._highlightElements(focusedElement);
2355
2999
  // }
2356
3000
  if (this.context.browserName === "chromium") {
3001
+ const _perf_t213 = Date.now();
3002
+ logEvent("[takeScreenshot] before: playContext.newCDPSession");
2357
3003
  const client = await playContext.newCDPSession(this.page);
3004
+ logEvent(`[takeScreenshot] after: playContext.newCDPSession took ${Date.now() - _perf_t213}ms`);
3005
+ const _perf_t214 = Date.now();
3006
+ logEvent("[takeScreenshot] before: client.send");
2358
3007
  const { data } = await client.send("Page.captureScreenshot", {
2359
3008
  format: "png",
2360
3009
  captureBeyondViewport: fullPage,
2361
3010
  });
3011
+ logEvent(`[takeScreenshot] after: client.send took ${Date.now() - _perf_t214}ms`);
3012
+ const _perf_t215 = Date.now();
3013
+ logEvent("[takeScreenshot] before: client.detach");
2362
3014
  await client.detach();
3015
+ logEvent(`[takeScreenshot] after: client.detach took ${Date.now() - _perf_t215}ms`);
2363
3016
  if (!screenshotPath) {
2364
3017
  return data;
2365
3018
  }
2366
3019
  screenshotBuffer = Buffer.from(data, "base64");
2367
3020
  }
2368
3021
  else {
3022
+ const _perf_t216 = Date.now();
3023
+ logEvent("[takeScreenshot] before: page.screenshot");
2369
3024
  screenshotBuffer = await this.page.screenshot({ fullPage: fullPage });
3025
+ logEvent(`[takeScreenshot] after: page.screenshot took ${Date.now() - _perf_t216}ms`);
2370
3026
  }
2371
3027
  // if (focusedElement) {
2372
3028
  // // console.log(`Focused element ${JSON.stringify(focusedElement._selector)}`)
2373
3029
  // await this._unhighlightElements(focusedElement);
2374
3030
  // }
3031
+ const _perf_t217 = Date.now();
3032
+ logEvent("[takeScreenshot] before: Jimp.read");
2375
3033
  let image = await Jimp.read(screenshotBuffer);
3034
+ logEvent(`[takeScreenshot] after: Jimp.read took ${Date.now() - _perf_t217}ms`);
2376
3035
  // Get the image dimensions
2377
3036
  const { width, height } = image.bitmap;
2378
3037
  const resizeRatio = viewportWidth / width;
2379
3038
  // Resize the image to fit within the viewport dimensions without enlarging
2380
3039
  if (width > viewportWidth) {
2381
3040
  image = image.resize({ w: viewportWidth, h: height * resizeRatio }); // Resize the image while maintaining aspect ratio
3041
+ const _perf_t218 = Date.now();
3042
+ logEvent("[takeScreenshot] before: image.write");
2382
3043
  await image.write(screenshotPath);
3044
+ logEvent(`[takeScreenshot] after: image.write took ${Date.now() - _perf_t218}ms`);
2383
3045
  }
2384
3046
  else {
2385
3047
  fs.writeFileSync(screenshotPath, screenshotBuffer);
@@ -2397,17 +3059,32 @@ class StableBrowser {
2397
3059
  operation: "verifyElementExistInPage",
2398
3060
  log: "***** verify element " + selectors.element_name + " exists in page *****\n",
2399
3061
  };
3062
+ const _perf_t219 = Date.now();
3063
+ logEvent("[verifyElementExistInPage] before: new Promise");
2400
3064
  await new Promise((resolve) => setTimeout(resolve, 2000));
3065
+ logEvent(`[verifyElementExistInPage] after: new Promise took ${Date.now() - _perf_t219}ms`);
2401
3066
  try {
3067
+ const _perf_t220 = Date.now();
3068
+ logEvent("[verifyElementExistInPage] before: _preCommand");
2402
3069
  await _preCommand(state, this);
3070
+ logEvent(`[verifyElementExistInPage] after: _preCommand took ${Date.now() - _perf_t220}ms`);
3071
+ const _perf_t221 = Date.now();
3072
+ logEvent("[verifyElementExistInPage] before: expect");
2403
3073
  await expect(state.element).toHaveCount(1, { timeout: 10000 });
3074
+ logEvent(`[verifyElementExistInPage] after: expect took ${Date.now() - _perf_t221}ms`);
2404
3075
  return state.info;
2405
3076
  }
2406
3077
  catch (e) {
3078
+ const _perf_t222 = Date.now();
3079
+ logEvent("[verifyElementExistInPage] before: _commandError");
2407
3080
  await _commandError(state, e, this);
3081
+ logEvent(`[verifyElementExistInPage] after: _commandError took ${Date.now() - _perf_t222}ms`);
2408
3082
  }
2409
3083
  finally {
3084
+ const _perf_t223 = Date.now();
3085
+ logEvent("[verifyElementExistInPage] before: _commandFinally");
2410
3086
  await _commandFinally(state, this);
3087
+ logEvent(`[verifyElementExistInPage] after: _commandFinally took ${Date.now() - _perf_t223}ms`);
2411
3088
  }
2412
3089
  }
2413
3090
  async extractAttribute(selectors, attribute, variable, _params = null, options = {}, world = null) {
@@ -2425,24 +3102,45 @@ class StableBrowser {
2425
3102
  log: "***** extract attribute " + attribute + " from " + selectors.element_name + " *****\n",
2426
3103
  allowDisabled: true,
2427
3104
  };
3105
+ const _perf_t224 = Date.now();
3106
+ logEvent("[extractAttribute] before: new Promise");
2428
3107
  await new Promise((resolve) => setTimeout(resolve, 2000));
3108
+ logEvent(`[extractAttribute] after: new Promise took ${Date.now() - _perf_t224}ms`);
2429
3109
  try {
3110
+ const _perf_t225 = Date.now();
3111
+ logEvent("[extractAttribute] before: _preCommand");
2430
3112
  await _preCommand(state, this);
3113
+ logEvent(`[extractAttribute] after: _preCommand took ${Date.now() - _perf_t225}ms`);
2431
3114
  switch (attribute) {
2432
3115
  case "inner_text":
3116
+ const _perf_t226 = Date.now();
3117
+ logEvent("[extractAttribute] before: state.element.innerText");
2433
3118
  state.value = await state.element.innerText();
3119
+ logEvent(`[extractAttribute] after: state.element.innerText took ${Date.now() - _perf_t226}ms`);
2434
3120
  break;
2435
3121
  case "href":
3122
+ const _perf_t227 = Date.now();
3123
+ logEvent("[extractAttribute] before: state.element.getAttribute");
2436
3124
  state.value = await state.element.getAttribute("href");
3125
+ logEvent(`[extractAttribute] after: state.element.getAttribute took ${Date.now() - _perf_t227}ms`);
2437
3126
  break;
2438
3127
  case "value":
3128
+ const _perf_t228 = Date.now();
3129
+ logEvent("[extractAttribute] before: state.element.inputValue");
2439
3130
  state.value = await state.element.inputValue();
3131
+ logEvent(`[extractAttribute] after: state.element.inputValue took ${Date.now() - _perf_t228}ms`);
2440
3132
  break;
2441
3133
  case "text":
3134
+ const _perf_t229 = Date.now();
3135
+ logEvent("[extractAttribute] before: state.element.textContent");
2442
3136
  state.value = await state.element.textContent();
3137
+ logEvent(`[extractAttribute] after: state.element.textContent took ${Date.now() - _perf_t229}ms`);
2443
3138
  break;
2444
3139
  default:
3140
+ const _perf_t230 = Date.now();
3141
+ logEvent("[extractAttribute] before: state.element.getAttribute");
2445
3142
  state.value = await state.element.getAttribute(attribute);
3143
+ logEvent(`[extractAttribute] after: state.element.getAttribute took ${Date.now() - _perf_t230}ms`);
2446
3144
  break;
2447
3145
  }
2448
3146
  if (options !== null) {
@@ -2476,10 +3174,16 @@ class StableBrowser {
2476
3174
  return state.info;
2477
3175
  }
2478
3176
  catch (e) {
3177
+ const _perf_t231 = Date.now();
3178
+ logEvent("[extractAttribute] before: _commandError");
2479
3179
  await _commandError(state, e, this);
3180
+ logEvent(`[extractAttribute] after: _commandError took ${Date.now() - _perf_t231}ms`);
2480
3181
  }
2481
3182
  finally {
3183
+ const _perf_t232 = Date.now();
3184
+ logEvent("[extractAttribute] before: _commandFinally");
2482
3185
  await _commandFinally(state, this);
3186
+ logEvent(`[extractAttribute] after: _commandFinally took ${Date.now() - _perf_t232}ms`);
2483
3187
  }
2484
3188
  }
2485
3189
  async extractProperty(selectors, property, variable, _params = null, options = {}, world = null) {
@@ -2497,21 +3201,39 @@ class StableBrowser {
2497
3201
  log: "***** extract property " + property + " from " + selectors.element_name + " *****\n",
2498
3202
  allowDisabled: true,
2499
3203
  };
3204
+ const _perf_t233 = Date.now();
3205
+ logEvent("[extractProperty] before: new Promise");
2500
3206
  await new Promise((resolve) => setTimeout(resolve, 2000));
3207
+ logEvent(`[extractProperty] after: new Promise took ${Date.now() - _perf_t233}ms`);
2501
3208
  try {
3209
+ const _perf_t234 = Date.now();
3210
+ logEvent("[extractProperty] before: _preCommand");
2502
3211
  await _preCommand(state, this);
3212
+ logEvent(`[extractProperty] after: _preCommand took ${Date.now() - _perf_t234}ms`);
2503
3213
  switch (property) {
2504
3214
  case "inner_text":
3215
+ const _perf_t235 = Date.now();
3216
+ logEvent("[extractProperty] before: state.element.innerText");
2505
3217
  state.value = await state.element.innerText();
3218
+ logEvent(`[extractProperty] after: state.element.innerText took ${Date.now() - _perf_t235}ms`);
2506
3219
  break;
2507
3220
  case "href":
3221
+ const _perf_t236 = Date.now();
3222
+ logEvent("[extractProperty] before: state.element.getAttribute");
2508
3223
  state.value = await state.element.getAttribute("href");
3224
+ logEvent(`[extractProperty] after: state.element.getAttribute took ${Date.now() - _perf_t236}ms`);
2509
3225
  break;
2510
3226
  case "value":
3227
+ const _perf_t237 = Date.now();
3228
+ logEvent("[extractProperty] before: state.element.inputValue");
2511
3229
  state.value = await state.element.inputValue();
3230
+ logEvent(`[extractProperty] after: state.element.inputValue took ${Date.now() - _perf_t237}ms`);
2512
3231
  break;
2513
3232
  case "text":
3233
+ const _perf_t238 = Date.now();
3234
+ logEvent("[extractProperty] before: state.element.textContent");
2514
3235
  state.value = await state.element.textContent();
3236
+ logEvent(`[extractProperty] after: state.element.textContent took ${Date.now() - _perf_t238}ms`);
2515
3237
  break;
2516
3238
  default:
2517
3239
  if (property.startsWith("dataset.")) {
@@ -2553,10 +3275,16 @@ class StableBrowser {
2553
3275
  return state.info;
2554
3276
  }
2555
3277
  catch (e) {
3278
+ const _perf_t239 = Date.now();
3279
+ logEvent("[extractProperty] before: _commandError");
2556
3280
  await _commandError(state, e, this);
3281
+ logEvent(`[extractProperty] after: _commandError took ${Date.now() - _perf_t239}ms`);
2557
3282
  }
2558
3283
  finally {
3284
+ const _perf_t240 = Date.now();
3285
+ logEvent("[extractProperty] before: _commandFinally");
2559
3286
  await _commandFinally(state, this);
3287
+ logEvent(`[extractProperty] after: _commandFinally took ${Date.now() - _perf_t240}ms`);
2560
3288
  }
2561
3289
  }
2562
3290
  async verifyAttribute(selectors, attribute, value, _params = null, options = {}, world = null) {
@@ -2576,12 +3304,21 @@ class StableBrowser {
2576
3304
  log: "***** verify attribute " + attribute + " from " + selectors.element_name + " *****\n",
2577
3305
  allowDisabled: true,
2578
3306
  };
3307
+ const _perf_t241 = Date.now();
3308
+ logEvent("[verifyAttribute] before: new Promise");
2579
3309
  await new Promise((resolve) => setTimeout(resolve, 2000));
3310
+ logEvent(`[verifyAttribute] after: new Promise took ${Date.now() - _perf_t241}ms`);
2580
3311
  let val;
2581
3312
  let expectedValue;
2582
3313
  try {
3314
+ const _perf_t242 = Date.now();
3315
+ logEvent("[verifyAttribute] before: _preCommand");
2583
3316
  await _preCommand(state, this);
3317
+ logEvent(`[verifyAttribute] after: _preCommand took ${Date.now() - _perf_t242}ms`);
3318
+ const _perf_t243 = Date.now();
3319
+ logEvent("[verifyAttribute] before: replaceWithLocalTestData");
2584
3320
  expectedValue = await replaceWithLocalTestData(state.value, world);
3321
+ logEvent(`[verifyAttribute] after: replaceWithLocalTestData took ${Date.now() - _perf_t243}ms`);
2585
3322
  state.info.expectedValue = expectedValue;
2586
3323
  switch (attribute) {
2587
3324
  case "innerText":
@@ -2600,7 +3337,10 @@ class StableBrowser {
2600
3337
  val = String(await state.element.isDisabled());
2601
3338
  break;
2602
3339
  case "readOnly":
3340
+ const _perf_t244 = Date.now();
3341
+ logEvent("[verifyAttribute] before: state.element.isEditable");
2603
3342
  const isEditable = await state.element.isEditable();
3343
+ logEvent(`[verifyAttribute] after: state.element.isEditable took ${Date.now() - _perf_t244}ms`);
2604
3344
  val = String(!isEditable);
2605
3345
  break;
2606
3346
  default:
@@ -2651,10 +3391,16 @@ class StableBrowser {
2651
3391
  return state.info;
2652
3392
  }
2653
3393
  catch (e) {
3394
+ const _perf_t245 = Date.now();
3395
+ logEvent("[verifyAttribute] before: _commandError");
2654
3396
  await _commandError(state, e, this);
3397
+ logEvent(`[verifyAttribute] after: _commandError took ${Date.now() - _perf_t245}ms`);
2655
3398
  }
2656
3399
  finally {
3400
+ const _perf_t246 = Date.now();
3401
+ logEvent("[verifyAttribute] before: _commandFinally");
2657
3402
  await _commandFinally(state, this);
3403
+ logEvent(`[verifyAttribute] after: _commandFinally took ${Date.now() - _perf_t246}ms`);
2658
3404
  }
2659
3405
  }
2660
3406
  async verifyProperty(selectors, property, value, _params = null, options = {}, world = null) {
@@ -2674,12 +3420,21 @@ class StableBrowser {
2674
3420
  log: "***** verify property " + property + " from " + selectors.element_name + " *****\n",
2675
3421
  allowDisabled: true,
2676
3422
  };
3423
+ const _perf_t247 = Date.now();
3424
+ logEvent("[verifyProperty] before: new Promise");
2677
3425
  await new Promise((resolve) => setTimeout(resolve, 2000));
3426
+ logEvent(`[verifyProperty] after: new Promise took ${Date.now() - _perf_t247}ms`);
2678
3427
  let val;
2679
3428
  let expectedValue;
2680
3429
  try {
3430
+ const _perf_t248 = Date.now();
3431
+ logEvent("[verifyProperty] before: _preCommand");
2681
3432
  await _preCommand(state, this);
3433
+ logEvent(`[verifyProperty] after: _preCommand took ${Date.now() - _perf_t248}ms`);
3434
+ const _perf_t249 = Date.now();
3435
+ logEvent("[verifyProperty] before: _replaceWithLocalData");
2682
3436
  expectedValue = await this._replaceWithLocalData(value, world);
3437
+ logEvent(`[verifyProperty] after: _replaceWithLocalData took ${Date.now() - _perf_t249}ms`);
2683
3438
  state.info.expectedValue = expectedValue;
2684
3439
  switch (property) {
2685
3440
  case "innerText":
@@ -2698,7 +3453,10 @@ class StableBrowser {
2698
3453
  val = String(await state.element.isDisabled());
2699
3454
  break;
2700
3455
  case "readOnly":
3456
+ const _perf_t250 = Date.now();
3457
+ logEvent("[verifyProperty] before: state.element.isEditable");
2701
3458
  const isEditable = await state.element.isEditable();
3459
+ logEvent(`[verifyProperty] after: state.element.isEditable took ${Date.now() - _perf_t250}ms`);
2702
3460
  val = String(!isEditable);
2703
3461
  break;
2704
3462
  case "innerHTML":
@@ -2779,10 +3537,16 @@ class StableBrowser {
2779
3537
  return state.info;
2780
3538
  }
2781
3539
  catch (e) {
3540
+ const _perf_t251 = Date.now();
3541
+ logEvent("[verifyProperty] before: _commandError");
2782
3542
  await _commandError(state, e, this);
3543
+ logEvent(`[verifyProperty] after: _commandError took ${Date.now() - _perf_t251}ms`);
2783
3544
  }
2784
3545
  finally {
3546
+ const _perf_t252 = Date.now();
3547
+ logEvent("[verifyProperty] before: _commandFinally");
2785
3548
  await _commandFinally(state, this);
3549
+ logEvent(`[verifyProperty] after: _commandFinally took ${Date.now() - _perf_t252}ms`);
2786
3550
  }
2787
3551
  }
2788
3552
  async conditionalWait(selectors, condition, timeout = 1000, _params = null, options = {}, world = null) {
@@ -2817,32 +3581,56 @@ class StableBrowser {
2817
3581
  const remainingTime = timeoutMs - elapsedTime;
2818
3582
  try {
2819
3583
  // Try to execute _preCommand (element location)
3584
+ const _perf_t253 = Date.now();
3585
+ logEvent("[conditionalWait] before: _preCommand");
2820
3586
  await _preCommand(state, this);
3587
+ logEvent(`[conditionalWait] after: _preCommand took ${Date.now() - _perf_t253}ms`);
2821
3588
  // If _preCommand succeeds, start condition checking
2822
3589
  const checkCondition = async () => {
2823
3590
  try {
2824
3591
  switch (condition.toLowerCase()) {
2825
3592
  case "checked":
3593
+ const _perf_t254 = Date.now();
3594
+ logEvent("[conditionalWait] before: state.element.isChecked");
2826
3595
  currentValue = await state.element.isChecked();
3596
+ logEvent(`[conditionalWait] after: state.element.isChecked took ${Date.now() - _perf_t254}ms`);
2827
3597
  return currentValue === true;
2828
3598
  case "unchecked":
3599
+ const _perf_t255 = Date.now();
3600
+ logEvent("[conditionalWait] before: state.element.isChecked");
2829
3601
  currentValue = await state.element.isChecked();
3602
+ logEvent(`[conditionalWait] after: state.element.isChecked took ${Date.now() - _perf_t255}ms`);
2830
3603
  return currentValue === false;
2831
3604
  case "visible":
3605
+ const _perf_t256 = Date.now();
3606
+ logEvent("[conditionalWait] before: state.element.isVisible");
2832
3607
  currentValue = await state.element.isVisible();
3608
+ logEvent(`[conditionalWait] after: state.element.isVisible took ${Date.now() - _perf_t256}ms`);
2833
3609
  return currentValue === true;
2834
3610
  case "hidden":
3611
+ const _perf_t257 = Date.now();
3612
+ logEvent("[conditionalWait] before: state.element.isVisible");
2835
3613
  currentValue = await state.element.isVisible();
3614
+ logEvent(`[conditionalWait] after: state.element.isVisible took ${Date.now() - _perf_t257}ms`);
2836
3615
  return currentValue === false;
2837
3616
  case "enabled":
3617
+ const _perf_t258 = Date.now();
3618
+ logEvent("[conditionalWait] before: state.element.isDisabled");
2838
3619
  currentValue = await state.element.isDisabled();
3620
+ logEvent(`[conditionalWait] after: state.element.isDisabled took ${Date.now() - _perf_t258}ms`);
2839
3621
  return currentValue === false;
2840
3622
  case "disabled":
3623
+ const _perf_t259 = Date.now();
3624
+ logEvent("[conditionalWait] before: state.element.isDisabled");
2841
3625
  currentValue = await state.element.isDisabled();
3626
+ logEvent(`[conditionalWait] after: state.element.isDisabled took ${Date.now() - _perf_t259}ms`);
2842
3627
  return currentValue === true;
2843
3628
  case "editable":
2844
3629
  // currentValue = await String(await state.element.evaluate((element, prop) => element[prop], "isContentEditable"));
3630
+ const _perf_t260 = Date.now();
3631
+ logEvent("[conditionalWait] before: state.element.isContentEditable");
2845
3632
  currentValue = await state.element.isContentEditable();
3633
+ logEvent(`[conditionalWait] after: state.element.isContentEditable took ${Date.now() - _perf_t260}ms`);
2846
3634
  return currentValue === true;
2847
3635
  default:
2848
3636
  state.info.message = `Unsupported condition: '${condition}'. Supported conditions are: checked, unchecked, visible, hidden, enabled, disabled, editable.`;
@@ -2852,19 +3640,26 @@ class StableBrowser {
2852
3640
  }
2853
3641
  catch (error) {
2854
3642
  // Don't throw here, just return false to continue retrying
3643
+ logEvent(`[conditionalWait] ❌❌ condition check error: ${error.message}`);
2855
3644
  return false;
2856
3645
  }
2857
3646
  };
2858
3647
  // Inner loop for condition checking (once element is located)
2859
3648
  while (Date.now() - startTime < timeoutMs) {
2860
3649
  const currentElapsedTime = Date.now() - startTime;
3650
+ const _perf_t261 = Date.now();
3651
+ logEvent("[conditionalWait] before: checkCondition");
2861
3652
  conditionMet = await checkCondition();
3653
+ logEvent(`[conditionalWait] after: checkCondition took ${Date.now() - _perf_t261}ms`);
2862
3654
  if (conditionMet) {
2863
3655
  break;
2864
3656
  }
2865
3657
  // Check if we still have time for another attempt
2866
3658
  if (Date.now() - startTime + 50 < timeoutMs) {
3659
+ const _perf_t262 = Date.now();
3660
+ logEvent("[conditionalWait] before: new Promise");
2867
3661
  await new Promise((res) => setTimeout(res, 50));
3662
+ logEvent(`[conditionalWait] after: new Promise took ${Date.now() - _perf_t262}ms`);
2868
3663
  }
2869
3664
  else {
2870
3665
  break;
@@ -2883,7 +3678,10 @@ class StableBrowser {
2883
3678
  const timeLeft = timeoutMs - currentElapsedTime;
2884
3679
  // Check if we have enough time left to retry
2885
3680
  if (timeLeft > 100) {
3681
+ const _perf_t263 = Date.now();
3682
+ logEvent("[conditionalWait] before: new Promise");
2886
3683
  await new Promise((resolve) => setTimeout(resolve, 50));
3684
+ logEvent(`[conditionalWait] after: new Promise took ${Date.now() - _perf_t263}ms`);
2887
3685
  }
2888
3686
  else {
2889
3687
  break;
@@ -2905,7 +3703,10 @@ class StableBrowser {
2905
3703
  state.log += `Last error: ${lastError.message}\n`;
2906
3704
  }
2907
3705
  try {
3706
+ const _perf_t264 = Date.now();
3707
+ logEvent("[conditionalWait] before: _commandFinally");
2908
3708
  await _commandFinally(state, this);
3709
+ logEvent(`[conditionalWait] after: _commandFinally took ${Date.now() - _perf_t264}ms`);
2909
3710
  }
2910
3711
  catch (finallyError) {
2911
3712
  state.log += `Error in _commandFinally: ${finallyError.message}\n`;
@@ -2945,7 +3746,10 @@ class StableBrowser {
2945
3746
  let errorCount = 0;
2946
3747
  while (true) {
2947
3748
  try {
3749
+ const _perf_t265 = Date.now();
3750
+ logEvent("[extractEmailData] before: context.api.request");
2948
3751
  let result = await this.context.api.request(request);
3752
+ logEvent(`[extractEmailData] after: context.api.request took ${Date.now() - _perf_t265}ms`);
2949
3753
  // the response body expected to be the following:
2950
3754
  // {
2951
3755
  // "status": true,
@@ -2993,7 +3797,10 @@ class StableBrowser {
2993
3797
  errorCount++;
2994
3798
  if (errorCount > 3) {
2995
3799
  // throw e;
3800
+ const _perf_t266 = Date.now();
3801
+ logEvent("[extractEmailData] before: _commandError");
2996
3802
  await _commandError({ text: "extractEmailData", operation: "extractEmailData", emailAddress, info: {} }, e, this);
3803
+ logEvent(`[extractEmailData] after: _commandError took ${Date.now() - _perf_t266}ms`);
2997
3804
  }
2998
3805
  // ignore
2999
3806
  }
@@ -3001,7 +3808,10 @@ class StableBrowser {
3001
3808
  if (Date.now() - startTime > timeout) {
3002
3809
  throw new Error("timeout reached");
3003
3810
  }
3811
+ const _perf_t267 = Date.now();
3812
+ logEvent("[extractEmailData] before: new Promise");
3004
3813
  await new Promise((resolve) => setTimeout(resolve, 5000));
3814
+ logEvent(`[extractEmailData] after: new Promise took ${Date.now() - _perf_t267}ms`);
3005
3815
  }
3006
3816
  }
3007
3817
  async _highlightElements(scope, css) {
@@ -3121,11 +3931,17 @@ class StableBrowser {
3121
3931
  let error = null;
3122
3932
  let screenshotId = null;
3123
3933
  let screenshotPath = null;
3934
+ const _perf_t268 = Date.now();
3935
+ logEvent("[verifyPagePath] before: new Promise");
3124
3936
  await new Promise((resolve) => setTimeout(resolve, 2000));
3937
+ logEvent(`[verifyPagePath] after: new Promise took ${Date.now() - _perf_t268}ms`);
3125
3938
  const info = {};
3126
3939
  info.log = "***** verify page path " + pathPart + " *****\n";
3127
3940
  info.operation = "verifyPagePath";
3941
+ const _perf_t269 = Date.now();
3942
+ logEvent("[verifyPagePath] before: _replaceWithLocalData");
3128
3943
  const newValue = await this._replaceWithLocalData(pathPart, world);
3944
+ logEvent(`[verifyPagePath] after: _replaceWithLocalData took ${Date.now() - _perf_t269}ms`);
3129
3945
  if (newValue !== pathPart) {
3130
3946
  this.logger.info(pathPart + "=" + newValue);
3131
3947
  pathPart = newValue;
@@ -3146,17 +3962,26 @@ class StableBrowser {
3146
3962
  log: "***** verify page url is " + queryText + " *****\n",
3147
3963
  };
3148
3964
  try {
3965
+ const _perf_t270 = Date.now();
3966
+ logEvent("[verifyPagePath] before: _preCommand");
3149
3967
  await _preCommand(state, this);
3968
+ logEvent(`[verifyPagePath] after: _preCommand took ${Date.now() - _perf_t270}ms`);
3150
3969
  state.info.text = queryText;
3151
3970
  for (let i = 0; i < 30; i++) {
3971
+ const _perf_t271 = Date.now();
3972
+ logEvent("[verifyPagePath] before: page.url");
3152
3973
  const url = await this.page.url();
3974
+ logEvent(`[verifyPagePath] after: page.url took ${Date.now() - _perf_t271}ms`);
3153
3975
  switch (matcher) {
3154
3976
  case "exact":
3155
3977
  if (url !== queryText) {
3156
3978
  if (i === 29) {
3157
3979
  throw new Error(`Page URL ${url} is not equal to ${queryText}`);
3158
3980
  }
3981
+ const _perf_t272 = Date.now();
3982
+ logEvent("[verifyPagePath] before: new Promise");
3159
3983
  await new Promise((resolve) => setTimeout(resolve, 1000));
3984
+ logEvent(`[verifyPagePath] after: new Promise took ${Date.now() - _perf_t272}ms`);
3160
3985
  continue;
3161
3986
  }
3162
3987
  break;
@@ -3165,7 +3990,10 @@ class StableBrowser {
3165
3990
  if (i === 29) {
3166
3991
  throw new Error(`Page URL ${url} doesn't contain ${queryText}`);
3167
3992
  }
3993
+ const _perf_t273 = Date.now();
3994
+ logEvent("[verifyPagePath] before: new Promise");
3168
3995
  await new Promise((resolve) => setTimeout(resolve, 1000));
3996
+ logEvent(`[verifyPagePath] after: new Promise took ${Date.now() - _perf_t273}ms`);
3169
3997
  continue;
3170
3998
  }
3171
3999
  break;
@@ -3176,7 +4004,10 @@ class StableBrowser {
3176
4004
  if (i === 29) {
3177
4005
  throw new Error(`Page URL ${url} doesn't start with ${queryText}`);
3178
4006
  }
4007
+ const _perf_t274 = Date.now();
4008
+ logEvent("[verifyPagePath] before: new Promise");
3179
4009
  await new Promise((resolve) => setTimeout(resolve, 1000));
4010
+ logEvent(`[verifyPagePath] after: new Promise took ${Date.now() - _perf_t274}ms`);
3180
4011
  continue;
3181
4012
  }
3182
4013
  }
@@ -3195,7 +4026,10 @@ class StableBrowser {
3195
4026
  if (i === 29) {
3196
4027
  throw new Error(`Page URL ${url} doesn't end with ${queryText}`);
3197
4028
  }
4029
+ const _perf_t275 = Date.now();
4030
+ logEvent("[verifyPagePath] before: new Promise");
3198
4031
  await new Promise((resolve) => setTimeout(resolve, 1000));
4032
+ logEvent(`[verifyPagePath] after: new Promise took ${Date.now() - _perf_t275}ms`);
3199
4033
  continue;
3200
4034
  }
3201
4035
  }
@@ -3206,7 +4040,10 @@ class StableBrowser {
3206
4040
  if (i === 29) {
3207
4041
  throw new Error(`Page URL ${url} doesn't match regex ${queryText}`);
3208
4042
  }
4043
+ const _perf_t276 = Date.now();
4044
+ logEvent("[verifyPagePath] before: new Promise");
3209
4045
  await new Promise((resolve) => setTimeout(resolve, 1000));
4046
+ logEvent(`[verifyPagePath] after: new Promise took ${Date.now() - _perf_t276}ms`);
3210
4047
  continue;
3211
4048
  }
3212
4049
  break;
@@ -3216,21 +4053,33 @@ class StableBrowser {
3216
4053
  if (i === 29) {
3217
4054
  throw new Error(`Page URL ${url} does not contain ${pathPart}`);
3218
4055
  }
4056
+ const _perf_t277 = Date.now();
4057
+ logEvent("[verifyPagePath] before: new Promise");
3219
4058
  await new Promise((resolve) => setTimeout(resolve, 1000));
4059
+ logEvent(`[verifyPagePath] after: new Promise took ${Date.now() - _perf_t277}ms`);
3220
4060
  continue;
3221
4061
  }
3222
4062
  }
4063
+ const _perf_t278 = Date.now();
4064
+ logEvent("[verifyPagePath] before: _screenshot");
3223
4065
  await _screenshot(state, this);
4066
+ logEvent(`[verifyPagePath] after: _screenshot took ${Date.now() - _perf_t278}ms`);
3224
4067
  return state.info;
3225
4068
  }
3226
4069
  }
3227
4070
  catch (e) {
3228
4071
  state.info.failCause.lastError = e.message;
3229
4072
  state.info.failCause.assertionFailed = true;
4073
+ const _perf_t279 = Date.now();
4074
+ logEvent("[verifyPagePath] before: _commandError");
3230
4075
  await _commandError(state, e, this);
4076
+ logEvent(`[verifyPagePath] after: _commandError took ${Date.now() - _perf_t279}ms`);
3231
4077
  }
3232
4078
  finally {
4079
+ const _perf_t280 = Date.now();
4080
+ logEvent("[verifyPagePath] before: _commandFinally");
3233
4081
  await _commandFinally(state, this);
4082
+ logEvent(`[verifyPagePath] after: _commandFinally took ${Date.now() - _perf_t280}ms`);
3234
4083
  }
3235
4084
  }
3236
4085
  /**
@@ -3244,8 +4093,14 @@ class StableBrowser {
3244
4093
  let error = null;
3245
4094
  let screenshotId = null;
3246
4095
  let screenshotPath = null;
4096
+ const _perf_t281 = Date.now();
4097
+ logEvent("[verifyPageTitle] before: new Promise");
3247
4098
  await new Promise((resolve) => setTimeout(resolve, 2000));
4099
+ logEvent(`[verifyPageTitle] after: new Promise took ${Date.now() - _perf_t281}ms`);
4100
+ const _perf_t282 = Date.now();
4101
+ logEvent("[verifyPageTitle] before: _replaceWithLocalData");
3248
4102
  const newValue = await this._replaceWithLocalData(title, world);
4103
+ logEvent(`[verifyPageTitle] after: _replaceWithLocalData took ${Date.now() - _perf_t282}ms`);
3249
4104
  if (newValue !== title) {
3250
4105
  this.logger.info(title + "=" + newValue);
3251
4106
  title = newValue;
@@ -3265,17 +4120,26 @@ class StableBrowser {
3265
4120
  log: "***** verify page title is " + queryText + " *****\n",
3266
4121
  };
3267
4122
  try {
4123
+ const _perf_t283 = Date.now();
4124
+ logEvent("[verifyPageTitle] before: _preCommand");
3268
4125
  await _preCommand(state, this);
4126
+ logEvent(`[verifyPageTitle] after: _preCommand took ${Date.now() - _perf_t283}ms`);
3269
4127
  state.info.text = queryText;
3270
4128
  for (let i = 0; i < 30; i++) {
4129
+ const _perf_t284 = Date.now();
4130
+ logEvent("[verifyPageTitle] before: page.title");
3271
4131
  const foundTitle = await this.page.title();
4132
+ logEvent(`[verifyPageTitle] after: page.title took ${Date.now() - _perf_t284}ms`);
3272
4133
  switch (matcher) {
3273
4134
  case "exact":
3274
4135
  if (foundTitle !== queryText) {
3275
4136
  if (i === 29) {
3276
4137
  throw new Error(`Page Title ${foundTitle} is not equal to ${queryText}`);
3277
4138
  }
4139
+ const _perf_t285 = Date.now();
4140
+ logEvent("[verifyPageTitle] before: new Promise");
3278
4141
  await new Promise((resolve) => setTimeout(resolve, 1000));
4142
+ logEvent(`[verifyPageTitle] after: new Promise took ${Date.now() - _perf_t285}ms`);
3279
4143
  continue;
3280
4144
  }
3281
4145
  break;
@@ -3284,7 +4148,10 @@ class StableBrowser {
3284
4148
  if (i === 29) {
3285
4149
  throw new Error(`Page Title ${foundTitle} doesn't contain ${queryText}`);
3286
4150
  }
4151
+ const _perf_t286 = Date.now();
4152
+ logEvent("[verifyPageTitle] before: new Promise");
3287
4153
  await new Promise((resolve) => setTimeout(resolve, 1000));
4154
+ logEvent(`[verifyPageTitle] after: new Promise took ${Date.now() - _perf_t286}ms`);
3288
4155
  continue;
3289
4156
  }
3290
4157
  break;
@@ -3293,7 +4160,10 @@ class StableBrowser {
3293
4160
  if (i === 29) {
3294
4161
  throw new Error(`Page title ${foundTitle} doesn't start with ${queryText}`);
3295
4162
  }
4163
+ const _perf_t287 = Date.now();
4164
+ logEvent("[verifyPageTitle] before: new Promise");
3296
4165
  await new Promise((resolve) => setTimeout(resolve, 1000));
4166
+ logEvent(`[verifyPageTitle] after: new Promise took ${Date.now() - _perf_t287}ms`);
3297
4167
  continue;
3298
4168
  }
3299
4169
  break;
@@ -3302,7 +4172,10 @@ class StableBrowser {
3302
4172
  if (i === 29) {
3303
4173
  throw new Error(`Page Title ${foundTitle} doesn't end with ${queryText}`);
3304
4174
  }
4175
+ const _perf_t288 = Date.now();
4176
+ logEvent("[verifyPageTitle] before: new Promise");
3305
4177
  await new Promise((resolve) => setTimeout(resolve, 1000));
4178
+ logEvent(`[verifyPageTitle] after: new Promise took ${Date.now() - _perf_t288}ms`);
3306
4179
  continue;
3307
4180
  }
3308
4181
  break;
@@ -3312,7 +4185,10 @@ class StableBrowser {
3312
4185
  if (i === 29) {
3313
4186
  throw new Error(`Page Title ${foundTitle} doesn't match regex ${queryText}`);
3314
4187
  }
4188
+ const _perf_t289 = Date.now();
4189
+ logEvent("[verifyPageTitle] before: new Promise");
3315
4190
  await new Promise((resolve) => setTimeout(resolve, 1000));
4191
+ logEvent(`[verifyPageTitle] after: new Promise took ${Date.now() - _perf_t289}ms`);
3316
4192
  continue;
3317
4193
  }
3318
4194
  break;
@@ -3322,21 +4198,33 @@ class StableBrowser {
3322
4198
  if (i === 29) {
3323
4199
  throw new Error(`Page Title ${foundTitle} does not contain ${title}`);
3324
4200
  }
4201
+ const _perf_t290 = Date.now();
4202
+ logEvent("[verifyPageTitle] before: new Promise");
3325
4203
  await new Promise((resolve) => setTimeout(resolve, 1000));
4204
+ logEvent(`[verifyPageTitle] after: new Promise took ${Date.now() - _perf_t290}ms`);
3326
4205
  continue;
3327
4206
  }
3328
4207
  }
4208
+ const _perf_t291 = Date.now();
4209
+ logEvent("[verifyPageTitle] before: _screenshot");
3329
4210
  await _screenshot(state, this);
4211
+ logEvent(`[verifyPageTitle] after: _screenshot took ${Date.now() - _perf_t291}ms`);
3330
4212
  return state.info;
3331
4213
  }
3332
4214
  }
3333
4215
  catch (e) {
3334
4216
  state.info.failCause.lastError = e.message;
3335
4217
  state.info.failCause.assertionFailed = true;
4218
+ const _perf_t292 = Date.now();
4219
+ logEvent("[verifyPageTitle] before: _commandError");
3336
4220
  await _commandError(state, e, this);
4221
+ logEvent(`[verifyPageTitle] after: _commandError took ${Date.now() - _perf_t292}ms`);
3337
4222
  }
3338
4223
  finally {
4224
+ const _perf_t293 = Date.now();
4225
+ logEvent("[verifyPageTitle] before: _commandFinally");
3339
4226
  await _commandFinally(state, this);
4227
+ logEvent(`[verifyPageTitle] after: _commandFinally took ${Date.now() - _perf_t293}ms`);
3340
4228
  }
3341
4229
  }
3342
4230
  async findTextInAllFrames(dateAlternatives, numberAlternatives, text, state, partial = true, ignoreCase = false) {
@@ -3346,20 +4234,29 @@ class StableBrowser {
3346
4234
  for (let i = 0; i < frames.length; i++) {
3347
4235
  if (dateAlternatives.date) {
3348
4236
  for (let j = 0; j < dateAlternatives.dates.length; j++) {
4237
+ const _perf_t294 = Date.now();
4238
+ logEvent("[findTextInAllFrames] before: _locateElementByText");
3349
4239
  const result = await this._locateElementByText(frames[i], dateAlternatives.dates[j], "*:not(script, style, head)", false, partial, ignoreCase, {});
4240
+ logEvent(`[findTextInAllFrames] after: _locateElementByText took ${Date.now() - _perf_t294}ms`);
3350
4241
  result.frame = frames[i];
3351
4242
  results.push(result);
3352
4243
  }
3353
4244
  }
3354
4245
  else if (numberAlternatives.number) {
3355
4246
  for (let j = 0; j < numberAlternatives.numbers.length; j++) {
4247
+ const _perf_t295 = Date.now();
4248
+ logEvent("[findTextInAllFrames] before: _locateElementByText");
3356
4249
  const result = await this._locateElementByText(frames[i], numberAlternatives.numbers[j], "*:not(script, style, head)", false, partial, ignoreCase, {});
4250
+ logEvent(`[findTextInAllFrames] after: _locateElementByText took ${Date.now() - _perf_t295}ms`);
3357
4251
  result.frame = frames[i];
3358
4252
  results.push(result);
3359
4253
  }
3360
4254
  }
3361
4255
  else {
4256
+ const _perf_t296 = Date.now();
4257
+ logEvent("[findTextInAllFrames] before: _locateElementByText");
3362
4258
  const result = await this._locateElementByText(frames[i], text, "*:not(script, style, head)", false, partial, ignoreCase, {});
4259
+ logEvent(`[findTextInAllFrames] after: _locateElementByText took ${Date.now() - _perf_t296}ms`);
3363
4260
  result.frame = frames[i];
3364
4261
  results.push(result);
3365
4262
  }
@@ -3391,13 +4288,22 @@ class StableBrowser {
3391
4288
  let stepFastMode = this.stepTags.includes("fast-mode");
3392
4289
  if (!stepFastMode) {
3393
4290
  if (!this.fastMode) {
4291
+ const _perf_t297 = Date.now();
4292
+ logEvent("[verifyTextExistInPage] before: new Promise");
3394
4293
  await new Promise((resolve) => setTimeout(resolve, 2000));
4294
+ logEvent(`[verifyTextExistInPage] after: new Promise took ${Date.now() - _perf_t297}ms`);
3395
4295
  }
3396
4296
  else {
4297
+ const _perf_t298 = Date.now();
4298
+ logEvent("[verifyTextExistInPage] before: new Promise");
3397
4299
  await new Promise((resolve) => setTimeout(resolve, 500));
4300
+ logEvent(`[verifyTextExistInPage] after: new Promise took ${Date.now() - _perf_t298}ms`);
3398
4301
  }
3399
4302
  }
4303
+ const _perf_t299 = Date.now();
4304
+ logEvent("[verifyTextExistInPage] before: _replaceWithLocalData");
3400
4305
  const newValue = await this._replaceWithLocalData(text, world);
4306
+ logEvent(`[verifyTextExistInPage] after: _replaceWithLocalData took ${Date.now() - _perf_t299}ms`);
3401
4307
  if (newValue !== text) {
3402
4308
  this.logger.info(text + "=" + newValue);
3403
4309
  text = newValue;
@@ -3410,14 +4316,20 @@ class StableBrowser {
3410
4316
  state.highlight = false;
3411
4317
  }
3412
4318
  try {
4319
+ const _perf_t300 = Date.now();
4320
+ logEvent("[verifyTextExistInPage] before: _preCommand");
3413
4321
  await _preCommand(state, this);
4322
+ logEvent(`[verifyTextExistInPage] after: _preCommand took ${Date.now() - _perf_t300}ms`);
3414
4323
  state.info.text = text;
3415
4324
  while (true) {
3416
4325
  let resultWithElementsFound = {
3417
4326
  length: 0,
3418
4327
  };
3419
4328
  try {
4329
+ const _perf_t301 = Date.now();
4330
+ logEvent("[verifyTextExistInPage] before: findTextInAllFrames");
3420
4331
  resultWithElementsFound = await this.findTextInAllFrames(dateAlternatives, numberAlternatives, text, state);
4332
+ logEvent(`[verifyTextExistInPage] after: findTextInAllFrames took ${Date.now() - _perf_t301}ms`);
3421
4333
  }
3422
4334
  catch (error) {
3423
4335
  // ignore
@@ -3426,21 +4338,39 @@ class StableBrowser {
3426
4338
  if (Date.now() - state.startTime > timeout) {
3427
4339
  throw new Error(`Text ${text} not found in page`);
3428
4340
  }
4341
+ const _perf_t302 = Date.now();
4342
+ logEvent("[verifyTextExistInPage] before: new Promise");
3429
4343
  await new Promise((resolve) => setTimeout(resolve, 1000));
4344
+ logEvent(`[verifyTextExistInPage] after: new Promise took ${Date.now() - _perf_t302}ms`);
3430
4345
  continue;
3431
4346
  }
3432
4347
  try {
3433
4348
  if (resultWithElementsFound[0].randomToken) {
3434
4349
  const frame = resultWithElementsFound[0].frame;
3435
4350
  const dataAttribute = `[data-blinq-id-${resultWithElementsFound[0].randomToken}]`;
4351
+ const _perf_t303 = Date.now();
4352
+ logEvent("[verifyTextExistInPage] before: _highlightElements");
3436
4353
  await this._highlightElements(frame, dataAttribute);
4354
+ logEvent(`[verifyTextExistInPage] after: _highlightElements took ${Date.now() - _perf_t303}ms`);
4355
+ const _perf_t304 = Date.now();
4356
+ logEvent("[verifyTextExistInPage] before: frame.locator");
3437
4357
  const element = await frame.locator(dataAttribute).first();
4358
+ logEvent(`[verifyTextExistInPage] after: frame.locator took ${Date.now() - _perf_t304}ms`);
3438
4359
  if (element) {
4360
+ const _perf_t305 = Date.now();
4361
+ logEvent("[verifyTextExistInPage] before: scrollIfNeeded");
3439
4362
  await this.scrollIfNeeded(element, state.info);
4363
+ logEvent(`[verifyTextExistInPage] after: scrollIfNeeded took ${Date.now() - _perf_t305}ms`);
4364
+ const _perf_t306 = Date.now();
4365
+ logEvent("[verifyTextExistInPage] before: element.dispatchEvent");
3440
4366
  await element.dispatchEvent("bvt_verify_page_contains_text");
4367
+ logEvent(`[verifyTextExistInPage] after: element.dispatchEvent took ${Date.now() - _perf_t306}ms`);
3441
4368
  }
3442
4369
  }
4370
+ const _perf_t307 = Date.now();
4371
+ logEvent("[verifyTextExistInPage] before: _screenshot");
3443
4372
  await _screenshot(state, this);
4373
+ logEvent(`[verifyTextExistInPage] after: _screenshot took ${Date.now() - _perf_t307}ms`);
3444
4374
  return state.info;
3445
4375
  }
3446
4376
  catch (error) {
@@ -3449,10 +4379,16 @@ class StableBrowser {
3449
4379
  }
3450
4380
  }
3451
4381
  catch (e) {
4382
+ const _perf_t308 = Date.now();
4383
+ logEvent("[verifyTextExistInPage] before: _commandError");
3452
4384
  await _commandError(state, e, this);
4385
+ logEvent(`[verifyTextExistInPage] after: _commandError took ${Date.now() - _perf_t308}ms`);
3453
4386
  }
3454
4387
  finally {
4388
+ const _perf_t309 = Date.now();
4389
+ logEvent("[verifyTextExistInPage] before: _commandFinally");
3455
4390
  await _commandFinally(state, this);
4391
+ logEvent(`[verifyTextExistInPage] after: _commandFinally took ${Date.now() - _perf_t309}ms`);
3456
4392
  }
3457
4393
  }
3458
4394
  async waitForTextToDisappear(text, options = {}, world = null) {
@@ -3474,8 +4410,14 @@ class StableBrowser {
3474
4410
  text = text.replace(/\\"/g, '"');
3475
4411
  }
3476
4412
  const timeout = this._getFindElementTimeout(options);
4413
+ const _perf_t310 = Date.now();
4414
+ logEvent("[waitForTextToDisappear] before: new Promise");
3477
4415
  await new Promise((resolve) => setTimeout(resolve, 2000));
4416
+ logEvent(`[waitForTextToDisappear] after: new Promise took ${Date.now() - _perf_t310}ms`);
4417
+ const _perf_t311 = Date.now();
4418
+ logEvent("[waitForTextToDisappear] before: _replaceWithLocalData");
3478
4419
  const newValue = await this._replaceWithLocalData(text, world);
4420
+ logEvent(`[waitForTextToDisappear] after: _replaceWithLocalData took ${Date.now() - _perf_t311}ms`);
3479
4421
  if (newValue !== text) {
3480
4422
  this.logger.info(text + "=" + newValue);
3481
4423
  text = newValue;
@@ -3483,33 +4425,51 @@ class StableBrowser {
3483
4425
  let dateAlternatives = findDateAlternatives(text);
3484
4426
  let numberAlternatives = findNumberAlternatives(text);
3485
4427
  try {
4428
+ const _perf_t312 = Date.now();
4429
+ logEvent("[waitForTextToDisappear] before: _preCommand");
3486
4430
  await _preCommand(state, this);
4431
+ logEvent(`[waitForTextToDisappear] after: _preCommand took ${Date.now() - _perf_t312}ms`);
3487
4432
  state.info.text = text;
3488
4433
  let resultWithElementsFound = {
3489
4434
  length: null, // initial cannot be 0
3490
4435
  };
3491
4436
  while (true) {
3492
4437
  try {
4438
+ const _perf_t313 = Date.now();
4439
+ logEvent("[waitForTextToDisappear] before: findTextInAllFrames");
3493
4440
  resultWithElementsFound = await this.findTextInAllFrames(dateAlternatives, numberAlternatives, text, state);
4441
+ logEvent(`[waitForTextToDisappear] after: findTextInAllFrames took ${Date.now() - _perf_t313}ms`);
3494
4442
  }
3495
4443
  catch (error) {
3496
4444
  // ignore
3497
4445
  }
3498
4446
  if (resultWithElementsFound.length === 0) {
4447
+ const _perf_t314 = Date.now();
4448
+ logEvent("[waitForTextToDisappear] before: _screenshot");
3499
4449
  await _screenshot(state, this);
4450
+ logEvent(`[waitForTextToDisappear] after: _screenshot took ${Date.now() - _perf_t314}ms`);
3500
4451
  return state.info;
3501
4452
  }
3502
4453
  if (Date.now() - state.startTime > timeout) {
3503
4454
  throw new Error(`Text ${text} found in page`);
3504
4455
  }
4456
+ const _perf_t315 = Date.now();
4457
+ logEvent("[waitForTextToDisappear] before: new Promise");
3505
4458
  await new Promise((resolve) => setTimeout(resolve, 1000));
4459
+ logEvent(`[waitForTextToDisappear] after: new Promise took ${Date.now() - _perf_t315}ms`);
3506
4460
  }
3507
4461
  }
3508
4462
  catch (e) {
4463
+ const _perf_t316 = Date.now();
4464
+ logEvent("[waitForTextToDisappear] before: _commandError");
3509
4465
  await _commandError(state, e, this);
4466
+ logEvent(`[waitForTextToDisappear] after: _commandError took ${Date.now() - _perf_t316}ms`);
3510
4467
  }
3511
4468
  finally {
4469
+ const _perf_t317 = Date.now();
4470
+ logEvent("[waitForTextToDisappear] before: _commandFinally");
3512
4471
  await _commandFinally(state, this);
4472
+ logEvent(`[waitForTextToDisappear] after: _commandFinally took ${Date.now() - _perf_t317}ms`);
3513
4473
  }
3514
4474
  }
3515
4475
  async verifyTextRelatedToText(textAnchor, climb, textToVerify, options = {}, world = null) {
@@ -3531,13 +4491,22 @@ class StableBrowser {
3531
4491
  const cmdStartTime = Date.now();
3532
4492
  let cmdEndTime = null;
3533
4493
  const timeout = this._getFindElementTimeout(options);
4494
+ const _perf_t318 = Date.now();
4495
+ logEvent("[verifyTextRelatedToText] before: new Promise");
3534
4496
  await new Promise((resolve) => setTimeout(resolve, 2000));
4497
+ logEvent(`[verifyTextRelatedToText] after: new Promise took ${Date.now() - _perf_t318}ms`);
4498
+ const _perf_t319 = Date.now();
4499
+ logEvent("[verifyTextRelatedToText] before: _replaceWithLocalData");
3535
4500
  let newValue = await this._replaceWithLocalData(textAnchor, world);
4501
+ logEvent(`[verifyTextRelatedToText] after: _replaceWithLocalData took ${Date.now() - _perf_t319}ms`);
3536
4502
  if (newValue !== textAnchor) {
3537
4503
  this.logger.info(textAnchor + "=" + newValue);
3538
4504
  textAnchor = newValue;
3539
4505
  }
4506
+ const _perf_t320 = Date.now();
4507
+ logEvent("[verifyTextRelatedToText] before: _replaceWithLocalData");
3540
4508
  newValue = await this._replaceWithLocalData(textToVerify, world);
4509
+ logEvent(`[verifyTextRelatedToText] after: _replaceWithLocalData took ${Date.now() - _perf_t320}ms`);
3541
4510
  if (newValue !== textToVerify) {
3542
4511
  this.logger.info(textToVerify + "=" + newValue);
3543
4512
  textToVerify = newValue;
@@ -3546,14 +4515,20 @@ class StableBrowser {
3546
4515
  let numberAlternatives = findNumberAlternatives(textToVerify);
3547
4516
  let foundAncore = false;
3548
4517
  try {
4518
+ const _perf_t321 = Date.now();
4519
+ logEvent("[verifyTextRelatedToText] before: _preCommand");
3549
4520
  await _preCommand(state, this);
4521
+ logEvent(`[verifyTextRelatedToText] after: _preCommand took ${Date.now() - _perf_t321}ms`);
3550
4522
  state.info.text = textToVerify;
3551
4523
  let resultWithElementsFound = {
3552
4524
  length: 0,
3553
4525
  };
3554
4526
  while (true) {
3555
4527
  try {
4528
+ const _perf_t322 = Date.now();
4529
+ logEvent("[verifyTextRelatedToText] before: findTextInAllFrames");
3556
4530
  resultWithElementsFound = await this.findTextInAllFrames(findDateAlternatives(textAnchor), findNumberAlternatives(textAnchor), textAnchor, state, false);
4531
+ logEvent(`[verifyTextRelatedToText] after: findTextInAllFrames took ${Date.now() - _perf_t322}ms`);
3557
4532
  }
3558
4533
  catch (error) {
3559
4534
  // ignore
@@ -3562,7 +4537,10 @@ class StableBrowser {
3562
4537
  if (Date.now() - state.startTime > timeout) {
3563
4538
  throw new Error(`Text ${foundAncore ? textToVerify : textAnchor} not found in page`);
3564
4539
  }
4540
+ const _perf_t323 = Date.now();
4541
+ logEvent("[verifyTextRelatedToText] before: new Promise");
3565
4542
  await new Promise((resolve) => setTimeout(resolve, 1000));
4543
+ logEvent(`[verifyTextRelatedToText] after: new Promise took ${Date.now() - _perf_t323}ms`);
3566
4544
  continue;
3567
4545
  }
3568
4546
  else {
@@ -3591,13 +4569,25 @@ class StableBrowser {
3591
4569
  if (Number(climb) > 0) {
3592
4570
  css = css + " >> " + climbXpath;
3593
4571
  }
4572
+ const _perf_t324 = Date.now();
4573
+ logEvent("[verifyTextRelatedToText] before: frame.locator");
3594
4574
  const count = await frame.locator(css).count();
4575
+ logEvent(`[verifyTextRelatedToText] after: frame.locator took ${Date.now() - _perf_t324}ms`);
3595
4576
  for (let j = 0; j < count; j++) {
4577
+ const _perf_t325 = Date.now();
4578
+ logEvent("[verifyTextRelatedToText] before: frame.locator");
3596
4579
  const continer = await frame.locator(css).nth(j);
4580
+ logEvent(`[verifyTextRelatedToText] after: frame.locator took ${Date.now() - _perf_t325}ms`);
4581
+ const _perf_t326 = Date.now();
4582
+ logEvent("[verifyTextRelatedToText] before: _locateElementByText");
3597
4583
  const result = await this._locateElementByText(continer, textToVerify, "*:not(script, style, head)", false, true, true, {});
4584
+ logEvent(`[verifyTextRelatedToText] after: _locateElementByText took ${Date.now() - _perf_t326}ms`);
3598
4585
  if (result.elementCount > 0) {
3599
4586
  const dataAttribute = "[data-blinq-id-" + result.randomToken + "]";
4587
+ const _perf_t327 = Date.now();
4588
+ logEvent("[verifyTextRelatedToText] before: _highlightElements");
3600
4589
  await this._highlightElements(frame, dataAttribute);
4590
+ logEvent(`[verifyTextRelatedToText] after: _highlightElements took ${Date.now() - _perf_t327}ms`);
3601
4591
  //const cssAnchor = `[data-blinq-id="blinq-id-${token}-anchor"]`;
3602
4592
  // if (world && world.screenshot && !world.screenshotPath) {
3603
4593
  // console.log(`Highlighting for vtrt while running from recorder`);
@@ -3612,14 +4602,26 @@ class StableBrowser {
3612
4602
  // .catch(e);
3613
4603
  // }
3614
4604
  //await this._highlightElements(frame, cssAnchor);
4605
+ const _perf_t328 = Date.now();
4606
+ logEvent("[verifyTextRelatedToText] before: frame.locator");
3615
4607
  const element = await frame.locator(dataAttribute).first();
4608
+ logEvent(`[verifyTextRelatedToText] after: frame.locator took ${Date.now() - _perf_t328}ms`);
3616
4609
  // await new Promise((resolve) => setTimeout(resolve, 100));
3617
4610
  // await this._unhighlightElements(frame, dataAttribute);
3618
4611
  if (element) {
4612
+ const _perf_t329 = Date.now();
4613
+ logEvent("[verifyTextRelatedToText] before: scrollIfNeeded");
3619
4614
  await this.scrollIfNeeded(element, state.info);
4615
+ logEvent(`[verifyTextRelatedToText] after: scrollIfNeeded took ${Date.now() - _perf_t329}ms`);
4616
+ const _perf_t330 = Date.now();
4617
+ logEvent("[verifyTextRelatedToText] before: element.dispatchEvent");
3620
4618
  await element.dispatchEvent("bvt_verify_page_contains_text");
4619
+ logEvent(`[verifyTextRelatedToText] after: element.dispatchEvent took ${Date.now() - _perf_t330}ms`);
3621
4620
  }
4621
+ const _perf_t331 = Date.now();
4622
+ logEvent("[verifyTextRelatedToText] before: _screenshot");
3622
4623
  await _screenshot(state, this);
4624
+ logEvent(`[verifyTextRelatedToText] after: _screenshot took ${Date.now() - _perf_t331}ms`);
3623
4625
  return state.info;
3624
4626
  }
3625
4627
  }
@@ -3632,10 +4634,16 @@ class StableBrowser {
3632
4634
  // await expect(element).toHaveCount(1, { timeout: 10000 });
3633
4635
  }
3634
4636
  catch (e) {
4637
+ const _perf_t332 = Date.now();
4638
+ logEvent("[verifyTextRelatedToText] before: _commandError");
3635
4639
  await _commandError(state, e, this);
4640
+ logEvent(`[verifyTextRelatedToText] after: _commandError took ${Date.now() - _perf_t332}ms`);
3636
4641
  }
3637
4642
  finally {
4643
+ const _perf_t333 = Date.now();
4644
+ logEvent("[verifyTextRelatedToText] before: _commandFinally");
3638
4645
  await _commandFinally(state, this);
4646
+ logEvent(`[verifyTextRelatedToText] after: _commandFinally took ${Date.now() - _perf_t333}ms`);
3639
4647
  }
3640
4648
  }
3641
4649
  async findRelatedTextInAllFrames(textAnchor, climb, textToVerify, params = {}, options = {}, world = null) {
@@ -3643,7 +4651,10 @@ class StableBrowser {
3643
4651
  let results = [];
3644
4652
  let ignoreCase = false;
3645
4653
  for (let i = 0; i < frames.length; i++) {
4654
+ const _perf_t334 = Date.now();
4655
+ logEvent("[findRelatedTextInAllFrames] before: _locateElementByText");
3646
4656
  const result = await this._locateElementByText(frames[i], textAnchor, "*:not(script, style, head)", false, true, ignoreCase, {});
4657
+ logEvent(`[findRelatedTextInAllFrames] after: _locateElementByText took ${Date.now() - _perf_t334}ms`);
3647
4658
  result.frame = frames[i];
3648
4659
  const climbArray = [];
3649
4660
  for (let i = 0; i < climb; i++) {
@@ -3651,7 +4662,10 @@ class StableBrowser {
3651
4662
  }
3652
4663
  let climbXpath = "xpath=" + climbArray.join("/");
3653
4664
  const newLocator = `[data-blinq-id-${result.randomToken}] ${climb > 0 ? ">> " + climbXpath : ""} >> internal:text=${testForRegex(textToVerify) ? textToVerify : unEscapeString(textToVerify)}`;
4665
+ const _perf_t335 = Date.now();
4666
+ logEvent("[findRelatedTextInAllFrames] before: frames[i]");
3654
4667
  const count = await frames[i].locator(newLocator).count();
4668
+ logEvent(`[findRelatedTextInAllFrames] after: frames[i] took ${Date.now() - _perf_t335}ms`);
3655
4669
  if (count > 0) {
3656
4670
  result.elementCount = count;
3657
4671
  result.locator = newLocator;
@@ -3667,7 +4681,10 @@ class StableBrowser {
3667
4681
  let error = null;
3668
4682
  let screenshotId = null;
3669
4683
  let screenshotPath = null;
4684
+ const _perf_t336 = Date.now();
4685
+ logEvent("[visualVerification] before: new Promise");
3670
4686
  await new Promise((resolve) => setTimeout(resolve, 2000));
4687
+ logEvent(`[visualVerification] after: new Promise took ${Date.now() - _perf_t336}ms`);
3671
4688
  const info = {};
3672
4689
  info.log = "";
3673
4690
  info.operation = "visualVerification";
@@ -3679,7 +4696,10 @@ class StableBrowser {
3679
4696
  let serviceUrl = _getServerUrl();
3680
4697
  ({ screenshotId, screenshotPath } = await this._screenShot(options, world, info));
3681
4698
  info.screenshotPath = screenshotPath;
4699
+ const _perf_t337 = Date.now();
4700
+ logEvent("[visualVerification] before: takeScreenshot");
3682
4701
  const screenshot = await this.takeScreenshot();
4702
+ logEvent(`[visualVerification] after: takeScreenshot took ${Date.now() - _perf_t337}ms`);
3683
4703
  let request = {
3684
4704
  method: "post",
3685
4705
  maxBodyLength: Infinity,
@@ -3695,7 +4715,10 @@ class StableBrowser {
3695
4715
  screenshot: screenshot,
3696
4716
  }),
3697
4717
  };
4718
+ const _perf_t338 = Date.now();
4719
+ logEvent("[visualVerification] before: axios.request");
3698
4720
  const result = await axios.request(request);
4721
+ logEvent(`[visualVerification] after: axios.request took ${Date.now() - _perf_t338}ms`);
3699
4722
  if (result.data.status !== true) {
3700
4723
  throw new Error("Visual validation failed");
3701
4724
  }
@@ -3716,7 +4739,10 @@ class StableBrowser {
3716
4739
  Object.assign(e, { info: info });
3717
4740
  error = e;
3718
4741
  // throw e;
4742
+ const _perf_t339 = Date.now();
4743
+ logEvent("[visualVerification] before: _commandError");
3719
4744
  await _commandError({ text: "visualVerification", operation: "visualVerification", info }, e, this);
4745
+ logEvent(`[visualVerification] after: _commandError took ${Date.now() - _perf_t339}ms`);
3720
4746
  }
3721
4747
  finally {
3722
4748
  const endTime = Date.now();
@@ -3742,7 +4768,10 @@ class StableBrowser {
3742
4768
  }
3743
4769
  }
3744
4770
  async verifyTableData(selectors, data, _params = null, options = {}, world = null) {
4771
+ const _perf_t340 = Date.now();
4772
+ logEvent("[verifyTableData] before: getTableData");
3745
4773
  const tableData = await this.getTableData(selectors, _params, options, world);
4774
+ logEvent(`[verifyTableData] after: getTableData took ${Date.now() - _perf_t340}ms`);
3746
4775
  for (let i = 0; i < data.length; i++) {
3747
4776
  const row = data[i];
3748
4777
  const rowText = JSON.stringify(row);
@@ -3773,9 +4802,15 @@ class StableBrowser {
3773
4802
  info.operation = "getTableData";
3774
4803
  info.selectors = selectors;
3775
4804
  try {
4805
+ const _perf_t341 = Date.now();
4806
+ logEvent("[getTableData] before: _locate");
3776
4807
  let table = await this._locate(selectors, info, _params);
4808
+ logEvent(`[getTableData] after: _locate took ${Date.now() - _perf_t341}ms`);
3777
4809
  ({ screenshotId, screenshotPath } = await this._screenShot(options, world, info));
4810
+ const _perf_t342 = Date.now();
4811
+ logEvent("[getTableData] before: getTableData");
3778
4812
  const tableData = await getTableData(this.page, table);
4813
+ logEvent(`[getTableData] after: getTableData took ${Date.now() - _perf_t342}ms`);
3779
4814
  return tableData;
3780
4815
  }
3781
4816
  catch (e) {
@@ -3786,7 +4821,10 @@ class StableBrowser {
3786
4821
  Object.assign(e, { info: info });
3787
4822
  error = e;
3788
4823
  // throw e;
4824
+ const _perf_t343 = Date.now();
4825
+ logEvent("[getTableData] before: _commandError");
3789
4826
  await _commandError({ text: "getTableData", operation: "getTableData", selectors, info }, e, this);
4827
+ logEvent(`[getTableData] after: _commandError took ${Date.now() - _perf_t343}ms`);
3790
4828
  }
3791
4829
  finally {
3792
4830
  const endTime = Date.now();
@@ -3822,7 +4860,10 @@ class StableBrowser {
3822
4860
  if (!value) {
3823
4861
  throw new Error("value is null");
3824
4862
  }
4863
+ const _perf_t344 = Date.now();
4864
+ logEvent("[analyzeTable] before: _replaceWithLocalData");
3825
4865
  const newValue = await this._replaceWithLocalData(value, world);
4866
+ logEvent(`[analyzeTable] after: _replaceWithLocalData took ${Date.now() - _perf_t344}ms`);
3826
4867
  if (newValue !== value) {
3827
4868
  this.logger.info(value + "=" + newValue);
3828
4869
  value = newValue;
@@ -3850,9 +4891,15 @@ class StableBrowser {
3850
4891
  info.operator = operator;
3851
4892
  info.value = value;
3852
4893
  try {
4894
+ const _perf_t345 = Date.now();
4895
+ logEvent("[analyzeTable] before: _locate");
3853
4896
  let table = await this._locate(selectors, info, _params);
4897
+ logEvent(`[analyzeTable] after: _locate took ${Date.now() - _perf_t345}ms`);
3854
4898
  ({ screenshotId, screenshotPath } = await this._screenShot(options, world, info));
4899
+ const _perf_t346 = Date.now();
4900
+ logEvent("[analyzeTable] before: getTableCells");
3855
4901
  const cells = await getTableCells(this.page, table, query, info);
4902
+ logEvent(`[analyzeTable] after: getTableCells took ${Date.now() - _perf_t346}ms`);
3856
4903
  if (cells && cells.error) {
3857
4904
  throw new Error(cells.error);
3858
4905
  }
@@ -3952,7 +4999,10 @@ class StableBrowser {
3952
4999
  Object.assign(e, { info: info });
3953
5000
  error = e;
3954
5001
  // throw e;
5002
+ const _perf_t347 = Date.now();
5003
+ logEvent("[analyzeTable] before: _commandError");
3955
5004
  await _commandError({ text: "analyzeTable", operation: "analyzeTable", selectors, query, operator, value }, e, this);
5005
+ logEvent(`[analyzeTable] after: _commandError took ${Date.now() - _perf_t347}ms`);
3956
5006
  }
3957
5007
  finally {
3958
5008
  const endTime = Date.now();
@@ -4000,23 +5050,38 @@ class StableBrowser {
4000
5050
  log: `***** Sleep for ${duration} ms *****\n`,
4001
5051
  };
4002
5052
  try {
5053
+ const _perf_t348 = Date.now();
5054
+ logEvent("[sleep] before: _preCommand");
4003
5055
  await _preCommand(state, this);
5056
+ logEvent(`[sleep] after: _preCommand took ${Date.now() - _perf_t348}ms`);
4004
5057
  if (duration < 0) {
4005
5058
  throw new Error("Sleep duration cannot be negative");
4006
5059
  }
5060
+ const _perf_t349 = Date.now();
5061
+ logEvent("[sleep] before: new Promise");
4007
5062
  await new Promise((resolve) => setTimeout(resolve, duration));
5063
+ logEvent(`[sleep] after: new Promise took ${Date.now() - _perf_t349}ms`);
4008
5064
  return state.info;
4009
5065
  }
4010
5066
  catch (e) {
5067
+ const _perf_t350 = Date.now();
5068
+ logEvent("[sleep] before: _commandError");
4011
5069
  await _commandError(state, e, this);
5070
+ logEvent(`[sleep] after: _commandError took ${Date.now() - _perf_t350}ms`);
4012
5071
  }
4013
5072
  finally {
5073
+ const _perf_t351 = Date.now();
5074
+ logEvent("[sleep] before: _commandFinally");
4014
5075
  await _commandFinally(state, this);
5076
+ logEvent(`[sleep] after: _commandFinally took ${Date.now() - _perf_t351}ms`);
4015
5077
  }
4016
5078
  }
4017
5079
  async _replaceWithLocalData(value, world, _decrypt = true, totpWait = true) {
4018
5080
  try {
5081
+ const _perf_t352 = Date.now();
5082
+ logEvent("[_replaceWithLocalData] before: replaceWithLocalTestData");
4019
5083
  return await replaceWithLocalTestData(value, world, _decrypt, totpWait, this.context, this);
5084
+ logEvent(`[_replaceWithLocalData] after: replaceWithLocalTestData took ${Date.now() - _perf_t352}ms`);
4020
5085
  }
4021
5086
  catch (error) {
4022
5087
  logEvent(error);
@@ -4043,25 +5108,43 @@ class StableBrowser {
4043
5108
  return 30000;
4044
5109
  }
4045
5110
  async saveStoreState(path = null, world = null) {
5111
+ const _perf_t353 = Date.now();
5112
+ logEvent("[saveStoreState] before: page.context");
4046
5113
  const storageState = await this.page.context().storageState();
5114
+ logEvent(`[saveStoreState] after: page.context took ${Date.now() - _perf_t353}ms`);
5115
+ const _perf_t354 = Date.now();
5116
+ logEvent("[saveStoreState] before: _replaceWithLocalData");
4047
5117
  path = await this._replaceWithLocalData(path, this.world);
5118
+ logEvent(`[saveStoreState] after: _replaceWithLocalData took ${Date.now() - _perf_t354}ms`);
4048
5119
  //const testDataFile = _getDataFile(world, this.context, this);
4049
5120
  if (path) {
4050
5121
  // save { storageState: storageState } into the path
4051
5122
  fs.writeFileSync(path, JSON.stringify({ storageState: storageState }, null, 2));
4052
5123
  }
4053
5124
  else {
5125
+ const _perf_t355 = Date.now();
5126
+ logEvent("[saveStoreState] before: setTestData");
4054
5127
  await this.setTestData({ storageState: storageState }, world);
5128
+ logEvent(`[saveStoreState] after: setTestData took ${Date.now() - _perf_t355}ms`);
4055
5129
  }
4056
5130
  }
4057
5131
  async restoreSaveState(path = null, world = null) {
5132
+ const _perf_t356 = Date.now();
5133
+ logEvent("[restoreSaveState] before: _replaceWithLocalData");
4058
5134
  path = await this._replaceWithLocalData(path, this.world);
5135
+ logEvent(`[restoreSaveState] after: _replaceWithLocalData took ${Date.now() - _perf_t356}ms`);
5136
+ const _perf_t357 = Date.now();
5137
+ logEvent("[restoreSaveState] before: refreshBrowser");
4059
5138
  await refreshBrowser(this, path, world);
5139
+ logEvent(`[restoreSaveState] after: refreshBrowser took ${Date.now() - _perf_t357}ms`);
4060
5140
  this.registerEventListeners(this.context);
4061
5141
  registerNetworkEvents(this.world, this, this.context, this.page);
4062
5142
  registerDownloadEvent(this.page, this.world, this.context);
4063
5143
  if (this.onRestoreSaveState) {
5144
+ const _perf_t358 = Date.now();
5145
+ logEvent("[restoreSaveState] before: onRestoreSaveState");
4064
5146
  await this.onRestoreSaveState(path);
5147
+ logEvent(`[restoreSaveState] after: onRestoreSaveState took ${Date.now() - _perf_t358}ms`);
4065
5148
  }
4066
5149
  }
4067
5150
  async waitForPageLoad(options = {}, world = null) {
@@ -4101,7 +5184,10 @@ class StableBrowser {
4101
5184
  let screenshotId = null;
4102
5185
  let screenshotPath = null;
4103
5186
  try {
5187
+ const _perf_t359 = Date.now();
5188
+ logEvent("[waitForPageLoad] before: Promise.all");
4104
5189
  await Promise.all(promiseArray);
5190
+ logEvent(`[waitForPageLoad] after: Promise.all took ${Date.now() - _perf_t359}ms`);
4105
5191
  }
4106
5192
  catch (e) {
4107
5193
  if (e.label === "networkidle") {
@@ -4115,9 +5201,15 @@ class StableBrowser {
4115
5201
  }
4116
5202
  }
4117
5203
  finally {
5204
+ const _perf_t360 = Date.now();
5205
+ logEvent("[waitForPageLoad] before: new Promise");
4118
5206
  await new Promise((resolve) => setTimeout(resolve, 500));
5207
+ logEvent(`[waitForPageLoad] after: new Promise took ${Date.now() - _perf_t360}ms`);
4119
5208
  if (options && !options.noSleep) {
5209
+ const _perf_t361 = Date.now();
5210
+ logEvent("[waitForPageLoad] before: new Promise");
4120
5211
  await new Promise((resolve) => setTimeout(resolve, 1500));
5212
+ logEvent(`[waitForPageLoad] after: new Promise took ${Date.now() - _perf_t361}ms`);
4121
5213
  }
4122
5214
  ({ screenshotId, screenshotPath } = await this._screenShot(options, world));
4123
5215
  const endTime = Date.now();
@@ -4155,14 +5247,26 @@ class StableBrowser {
4155
5247
  // throwError: false,
4156
5248
  };
4157
5249
  try {
5250
+ const _perf_t362 = Date.now();
5251
+ logEvent("[closePage] before: _preCommand");
4158
5252
  await _preCommand(state, this);
5253
+ logEvent(`[closePage] after: _preCommand took ${Date.now() - _perf_t362}ms`);
5254
+ const _perf_t363 = Date.now();
5255
+ logEvent("[closePage] before: page.close");
4159
5256
  await this.page.close();
5257
+ logEvent(`[closePage] after: page.close took ${Date.now() - _perf_t363}ms`);
4160
5258
  }
4161
5259
  catch (e) {
5260
+ const _perf_t364 = Date.now();
5261
+ logEvent("[closePage] before: _commandError");
4162
5262
  await _commandError(state, e, this);
5263
+ logEvent(`[closePage] after: _commandError took ${Date.now() - _perf_t364}ms`);
4163
5264
  }
4164
5265
  finally {
5266
+ const _perf_t365 = Date.now();
5267
+ logEvent("[closePage] before: _commandFinally");
4165
5268
  await _commandFinally(state, this);
5269
+ logEvent(`[closePage] after: _commandFinally took ${Date.now() - _perf_t365}ms`);
4166
5270
  }
4167
5271
  }
4168
5272
  async tableCellOperation(headerText, rowText, options, _params, world = null) {
@@ -4189,12 +5293,18 @@ class StableBrowser {
4189
5293
  };
4190
5294
  const timeout = this._getFindElementTimeout(options);
4191
5295
  try {
5296
+ const _perf_t366 = Date.now();
5297
+ logEvent("[tableCellOperation] before: _preCommand");
4192
5298
  await _preCommand(state, this);
5299
+ logEvent(`[tableCellOperation] after: _preCommand took ${Date.now() - _perf_t366}ms`);
4193
5300
  const start = Date.now();
4194
5301
  let cellArea = null;
4195
5302
  while (true) {
4196
5303
  try {
5304
+ const _perf_t367 = Date.now();
5305
+ logEvent("[tableCellOperation] before: _findCellArea");
4197
5306
  cellArea = await _findCellArea(headerText, rowText, this, state);
5307
+ logEvent(`[tableCellOperation] after: _findCellArea took ${Date.now() - _perf_t367}ms`);
4198
5308
  if (cellArea) {
4199
5309
  break;
4200
5310
  }
@@ -4205,7 +5315,10 @@ class StableBrowser {
4205
5315
  if (Date.now() - start > timeout) {
4206
5316
  throw new Error(`Cell not found in table`);
4207
5317
  }
5318
+ const _perf_t368 = Date.now();
5319
+ logEvent("[tableCellOperation] before: new Promise");
4208
5320
  await new Promise((resolve) => setTimeout(resolve, 1000));
5321
+ logEvent(`[tableCellOperation] after: new Promise took ${Date.now() - _perf_t368}ms`);
4209
5322
  }
4210
5323
  switch (operation) {
4211
5324
  case "click":
@@ -4219,48 +5332,75 @@ class StableBrowser {
4219
5332
  if (options.yOffset) {
4220
5333
  yOffset = options.yOffset;
4221
5334
  }
5335
+ const _perf_t369 = Date.now();
5336
+ logEvent("[tableCellOperation] before: page.mouse.click");
4222
5337
  await this.page.mouse.click(cellArea.x + cellArea.width / 2 + xOffset, cellArea.y + cellArea.height / 2 + yOffset);
5338
+ logEvent(`[tableCellOperation] after: page.mouse.click took ${Date.now() - _perf_t369}ms`);
4223
5339
  }
4224
5340
  else {
5341
+ const _perf_t370 = Date.now();
5342
+ logEvent("[tableCellOperation] before: findElementsInArea");
4225
5343
  const results = await findElementsInArea(options.css, cellArea, this, options);
5344
+ logEvent(`[tableCellOperation] after: findElementsInArea took ${Date.now() - _perf_t370}ms`);
4226
5345
  if (results.length === 0) {
4227
5346
  throw new Error(`Element not found in cell area`);
4228
5347
  }
4229
5348
  state.element = results[0];
5349
+ const _perf_t371 = Date.now();
5350
+ logEvent("[tableCellOperation] before: performAction");
4230
5351
  await performAction("click", state.element, options, this, state, _params);
5352
+ logEvent(`[tableCellOperation] after: performAction took ${Date.now() - _perf_t371}ms`);
4231
5353
  }
4232
5354
  break;
4233
5355
  case "hover+click":
4234
5356
  if (!options.css) {
4235
5357
  throw new Error("css is not defined");
4236
5358
  }
5359
+ const _perf_t372 = Date.now();
5360
+ logEvent("[tableCellOperation] before: findElementsInArea");
4237
5361
  const results = await findElementsInArea(options.css, cellArea, this, options);
5362
+ logEvent(`[tableCellOperation] after: findElementsInArea took ${Date.now() - _perf_t372}ms`);
4238
5363
  if (results.length === 0) {
4239
5364
  throw new Error(`Element not found in cell area`);
4240
5365
  }
4241
5366
  state.element = results[0];
5367
+ const _perf_t373 = Date.now();
5368
+ logEvent("[tableCellOperation] before: performAction");
4242
5369
  await performAction("hover+click", state.element, options, this, state, _params);
5370
+ logEvent(`[tableCellOperation] after: performAction took ${Date.now() - _perf_t373}ms`);
4243
5371
  break;
4244
5372
  case "hover":
4245
5373
  if (!options.css) {
4246
5374
  throw new Error("css is not defined");
4247
5375
  }
5376
+ const _perf_t374 = Date.now();
5377
+ logEvent("[tableCellOperation] before: findElementsInArea");
4248
5378
  const result1 = await findElementsInArea(options.css, cellArea, this, options);
5379
+ logEvent(`[tableCellOperation] after: findElementsInArea took ${Date.now() - _perf_t374}ms`);
4249
5380
  if (result1.length === 0) {
4250
5381
  throw new Error(`Element not found in cell area`);
4251
5382
  }
4252
5383
  state.element = result1[0];
5384
+ const _perf_t375 = Date.now();
5385
+ logEvent("[tableCellOperation] before: performAction");
4253
5386
  await performAction("hover", state.element, options, this, state, _params);
5387
+ logEvent(`[tableCellOperation] after: performAction took ${Date.now() - _perf_t375}ms`);
4254
5388
  break;
4255
5389
  default:
4256
5390
  throw new Error("operation is not supported");
4257
5391
  }
4258
5392
  }
4259
5393
  catch (e) {
5394
+ const _perf_t376 = Date.now();
5395
+ logEvent("[tableCellOperation] before: _commandError");
4260
5396
  await _commandError(state, e, this);
5397
+ logEvent(`[tableCellOperation] after: _commandError took ${Date.now() - _perf_t376}ms`);
4261
5398
  }
4262
5399
  finally {
5400
+ const _perf_t377 = Date.now();
5401
+ logEvent("[tableCellOperation] before: _commandFinally");
4263
5402
  await _commandFinally(state, this);
5403
+ logEvent(`[tableCellOperation] after: _commandFinally took ${Date.now() - _perf_t377}ms`);
4264
5404
  }
4265
5405
  }
4266
5406
  saveTestDataAsGlobal(options, world) {
@@ -4291,13 +5431,22 @@ class StableBrowser {
4291
5431
  if (hight <= 0) {
4292
5432
  hight = 1080;
4293
5433
  }
5434
+ const _perf_t378 = Date.now();
5435
+ logEvent("[setViewportSize] before: page.setViewportSize");
4294
5436
  await this.page.setViewportSize({ width: width, height: hight });
5437
+ logEvent(`[setViewportSize] after: page.setViewportSize took ${Date.now() - _perf_t378}ms`);
4295
5438
  }
4296
5439
  catch (e) {
5440
+ const _perf_t379 = Date.now();
5441
+ logEvent("[setViewportSize] before: _commandError");
4297
5442
  await _commandError({ text: "setViewportSize", operation: "setViewportSize", width, hight, info }, e, this);
5443
+ logEvent(`[setViewportSize] after: _commandError took ${Date.now() - _perf_t379}ms`);
4298
5444
  }
4299
5445
  finally {
5446
+ const _perf_t380 = Date.now();
5447
+ logEvent("[setViewportSize] before: new Promise");
4300
5448
  await new Promise((resolve) => setTimeout(resolve, 2000));
5449
+ logEvent(`[setViewportSize] after: new Promise took ${Date.now() - _perf_t380}ms`);
4301
5450
  ({ screenshotId, screenshotPath } = await this._screenShot(options, world));
4302
5451
  const endTime = Date.now();
4303
5452
  _reportToWorld(world, {
@@ -4328,13 +5477,22 @@ class StableBrowser {
4328
5477
  let screenshotPath = null;
4329
5478
  const info = {};
4330
5479
  try {
5480
+ const _perf_t381 = Date.now();
5481
+ logEvent("[reloadPage] before: page.reload");
4331
5482
  await this.page.reload();
5483
+ logEvent(`[reloadPage] after: page.reload took ${Date.now() - _perf_t381}ms`);
4332
5484
  }
4333
5485
  catch (e) {
5486
+ const _perf_t382 = Date.now();
5487
+ logEvent("[reloadPage] before: _commandError");
4334
5488
  await _commandError({ text: "reloadPage", operation: "reloadPage", info }, e, this);
5489
+ logEvent(`[reloadPage] after: _commandError took ${Date.now() - _perf_t382}ms`);
4335
5490
  }
4336
5491
  finally {
5492
+ const _perf_t383 = Date.now();
5493
+ logEvent("[reloadPage] before: new Promise");
4337
5494
  await new Promise((resolve) => setTimeout(resolve, 2000));
5495
+ logEvent(`[reloadPage] after: new Promise took ${Date.now() - _perf_t383}ms`);
4338
5496
  ({ screenshotId, screenshotPath } = await this._screenShot(options, world, info));
4339
5497
  const endTime = Date.now();
4340
5498
  _reportToWorld(world, {
@@ -4359,14 +5517,23 @@ class StableBrowser {
4359
5517
  }
4360
5518
  async scrollIfNeeded(element, info) {
4361
5519
  try {
5520
+ const _perf_t384 = Date.now();
5521
+ logEvent("[scrollIfNeeded] before: element.scrollIntoViewIfNeeded");
4362
5522
  await element.scrollIntoViewIfNeeded({
4363
5523
  timeout: 2000,
4364
5524
  });
5525
+ logEvent(`[scrollIfNeeded] after: element.scrollIntoViewIfNeeded took ${Date.now() - _perf_t384}ms`);
5526
+ const _perf_t385 = Date.now();
5527
+ logEvent("[scrollIfNeeded] before: new Promise");
4365
5528
  await new Promise((resolve) => setTimeout(resolve, 500));
5529
+ logEvent(`[scrollIfNeeded] after: new Promise took ${Date.now() - _perf_t385}ms`);
4366
5530
  if (info) {
5531
+ const _perf_t386 = Date.now();
5532
+ logEvent("[scrollIfNeeded] before: element.boundingBox");
4367
5533
  info.box = await element.boundingBox({
4368
5534
  timeout: 1000,
4369
5535
  });
5536
+ logEvent(`[scrollIfNeeded] after: element.boundingBox took ${Date.now() - _perf_t386}ms`);
4370
5537
  }
4371
5538
  }
4372
5539
  catch (e) {
@@ -4404,9 +5571,15 @@ class StableBrowser {
4404
5571
  envName = this.context.environment.name;
4405
5572
  }
4406
5573
  if (!process.env.TEMP_RUN) {
5574
+ const _perf_t387 = Date.now();
5575
+ logEvent("[beforeScenario] before: getTestData");
4407
5576
  await getTestData(envName, world, undefined, this.featureName, this.scenarioName, this.context);
5577
+ logEvent(`[beforeScenario] after: getTestData took ${Date.now() - _perf_t387}ms`);
4408
5578
  }
5579
+ const _perf_t388 = Date.now();
5580
+ logEvent("[beforeScenario] before: loadBrunoParams");
4409
5581
  await loadBrunoParams(this.context, this.context.environment.name);
5582
+ logEvent(`[beforeScenario] after: loadBrunoParams took ${Date.now() - _perf_t388}ms`);
4410
5583
  if ((process.env.TRACE === "true" || this.configuration.trace === true) && this.context) {
4411
5584
  this.trace = true;
4412
5585
  const traceFolder = path.join(this.context.reportFolder, "trace");
@@ -4414,15 +5587,21 @@ class StableBrowser {
4414
5587
  fs.mkdirSync(traceFolder, { recursive: true });
4415
5588
  }
4416
5589
  this.traceFolder = traceFolder;
5590
+ const _perf_t389 = Date.now();
5591
+ logEvent("[beforeScenario] before: context.playContext.tracing.start");
4417
5592
  await this.context.playContext.tracing.start({ screenshots: true, snapshots: true });
5593
+ logEvent(`[beforeScenario] after: context.playContext.tracing.start took ${Date.now() - _perf_t389}ms`);
4418
5594
  }
4419
5595
  }
4420
5596
  async afterScenario(world, scenario) {
4421
5597
  const id = scenario.testCaseStartedId;
4422
5598
  if (this.trace) {
5599
+ const _perf_t390 = Date.now();
5600
+ logEvent("[afterScenario] before: context.playContext.tracing.stop");
4423
5601
  await this.context.playContext.tracing.stop({
4424
5602
  path: path.join(this.traceFolder, `trace-${id}.zip`),
4425
5603
  });
5604
+ logEvent(`[afterScenario] after: context.playContext.tracing.stop took ${Date.now() - _perf_t390}ms`);
4426
5605
  }
4427
5606
  }
4428
5607
  getGherkinKeyword(step) {
@@ -4446,7 +5625,10 @@ class StableBrowser {
4446
5625
  if (step?.pickleStep && this.trace) {
4447
5626
  const keyword = this.getGherkinKeyword(step.pickleStep);
4448
5627
  this.traceGroupName = `${keyword} ${step.pickleStep.text}`;
5628
+ const _perf_t391 = Date.now();
5629
+ logEvent("[beforeStep] before: context.playContext.tracing.group");
4449
5630
  await this.context.playContext.tracing.group(this.traceGroupName);
5631
+ logEvent(`[beforeStep] after: context.playContext.tracing.group took ${Date.now() - _perf_t391}ms`);
4450
5632
  }
4451
5633
  this.stepTags = [];
4452
5634
  if (!this.beforeScenarioCalled) {
@@ -4476,7 +5658,10 @@ class StableBrowser {
4476
5658
  }
4477
5659
  if (this.context && this.context.browserObject && this.context.browserObject.trace === true) {
4478
5660
  if (this.context.browserObject.context) {
5661
+ const _perf_t392 = Date.now();
5662
+ logEvent("[beforeStep] before: context.browserObject.context.tracing.startChunk");
4479
5663
  await this.context.browserObject.context.tracing.startChunk({ title: this.stepName });
5664
+ logEvent(`[beforeStep] after: context.browserObject.context.tracing.startChunk took ${Date.now() - _perf_t392}ms`);
4480
5665
  }
4481
5666
  }
4482
5667
  if (this.initSnapshotTaken === false) {
@@ -4485,15 +5670,24 @@ class StableBrowser {
4485
5670
  world.attach &&
4486
5671
  !process.env.DISABLE_SNAPSHOT &&
4487
5672
  (!this.fastMode || this.stepTags.includes("fast-mode"))) {
5673
+ const _perf_t393 = Date.now();
5674
+ logEvent("[beforeStep] before: getAriaSnapshot");
4488
5675
  const snapshot = await this.getAriaSnapshot();
5676
+ logEvent(`[beforeStep] after: getAriaSnapshot took ${Date.now() - _perf_t393}ms`);
4489
5677
  if (snapshot) {
5678
+ const _perf_t394 = Date.now();
5679
+ logEvent("[beforeStep] before: world.attach");
4490
5680
  await world.attach(JSON.stringify(snapshot), "application/json+snapshot-before");
5681
+ logEvent(`[beforeStep] after: world.attach took ${Date.now() - _perf_t394}ms`);
4491
5682
  }
4492
5683
  }
4493
5684
  }
4494
5685
  this.context.routeResults = null;
4495
5686
  this.context.loadedRoutes = null;
5687
+ const _perf_t395 = Date.now();
5688
+ logEvent("[beforeStep] before: registerBeforeStepRoutes");
4496
5689
  await registerBeforeStepRoutes(this.context, this.stepName, world);
5690
+ logEvent(`[beforeStep] after: registerBeforeStepRoutes took ${Date.now() - _perf_t395}ms`);
4497
5691
  networkBeforeStep(this.stepName, this.context);
4498
5692
  this.inStepReport = false;
4499
5693
  }