seleniumbase 4.33.6__py3-none-any.whl → 4.33.7__py3-none-any.whl

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,2 +1,2 @@
1
1
  # seleniumbase package
2
- __version__ = "4.33.6"
2
+ __version__ = "4.33.7"
@@ -1413,7 +1413,7 @@ def _uc_gui_handle_captcha_(driver, frame="iframe", ctype=None):
1413
1413
  ctype = "cf_t"
1414
1414
  else:
1415
1415
  return
1416
- if not driver.is_connected():
1416
+ if not driver.is_connected() and not __is_cdp_swap_needed(driver):
1417
1417
  driver.connect()
1418
1418
  time.sleep(2)
1419
1419
  install_pyautogui_if_missing(driver)
@@ -1425,7 +1425,10 @@ def _uc_gui_handle_captcha_(driver, frame="iframe", ctype=None):
1425
1425
  )
1426
1426
  with gui_lock: # Prevent issues with multiple processes
1427
1427
  needs_switch = False
1428
- is_in_frame = js_utils.is_in_frame(driver)
1428
+ if not __is_cdp_swap_needed(driver):
1429
+ is_in_frame = js_utils.is_in_frame(driver)
1430
+ else:
1431
+ is_in_frame = False
1429
1432
  selector = "#challenge-stage"
1430
1433
  if ctype == "g_rc":
1431
1434
  selector = "#recaptcha-token"
@@ -1433,7 +1436,7 @@ def _uc_gui_handle_captcha_(driver, frame="iframe", ctype=None):
1433
1436
  driver.switch_to.parent_frame()
1434
1437
  needs_switch = True
1435
1438
  is_in_frame = js_utils.is_in_frame(driver)
1436
- if not is_in_frame:
1439
+ if not is_in_frame and not __is_cdp_swap_needed(driver):
1437
1440
  # Make sure the window is on top
1438
1441
  page_actions.switch_to_window(
1439
1442
  driver, driver.current_window_handle, 2, uc_lock=False
@@ -1500,17 +1503,18 @@ def _uc_gui_handle_captcha_(driver, frame="iframe", ctype=None):
1500
1503
  and frame == "iframe"
1501
1504
  ):
1502
1505
  frame = 'iframe[title="reCAPTCHA"]'
1503
- if not is_in_frame or needs_switch:
1504
- # Currently not in frame (or nested frame outside CF one)
1505
- try:
1506
- if visible_iframe or ctype == "g_rc":
1507
- driver.switch_to_frame(frame)
1508
- except Exception:
1509
- if visible_iframe or ctype == "g_rc":
1510
- if driver.is_element_present("iframe"):
1511
- driver.switch_to_frame("iframe")
1512
- else:
1513
- return
1506
+ if not __is_cdp_swap_needed(driver):
1507
+ if not is_in_frame or needs_switch:
1508
+ # Currently not in frame (or nested frame outside CF one)
1509
+ try:
1510
+ if visible_iframe or ctype == "g_rc":
1511
+ driver.switch_to_frame(frame)
1512
+ except Exception:
1513
+ if visible_iframe or ctype == "g_rc":
1514
+ if driver.is_element_present("iframe"):
1515
+ driver.switch_to_frame("iframe")
1516
+ else:
1517
+ return
1514
1518
  try:
1515
1519
  selector = "div.cf-turnstile"
1516
1520
  if ctype == "g_rc":
@@ -1526,11 +1530,11 @@ def _uc_gui_handle_captcha_(driver, frame="iframe", ctype=None):
1526
1530
  tab_count += 1
1527
1531
  time.sleep(0.027)
1528
1532
  active_element_css = js_utils.get_active_element_css(driver)
1529
- print(active_element_css)
1530
1533
  if (
1531
1534
  active_element_css.startswith(selector)
1532
1535
  or active_element_css.endswith(" > div" * 2)
1533
1536
  or (special_form and active_element_css.endswith(" div"))
1537
+ or (ctype == "g_rc" and "frame[name" in active_element_css)
1534
1538
  ):
1535
1539
  found_checkbox = True
1536
1540
  sb_config._saved_cf_tab_count = tab_count
@@ -1550,6 +1554,7 @@ def _uc_gui_handle_captcha_(driver, frame="iframe", ctype=None):
1550
1554
  )
1551
1555
  and hasattr(sb_config, "_saved_cf_tab_count")
1552
1556
  and sb_config._saved_cf_tab_count
1557
+ and not __is_cdp_swap_needed(driver)
1553
1558
  ):
1554
1559
  driver.uc_open_with_disconnect(driver.current_url, 3.8)
1555
1560
  with suppress(Exception):
@@ -1764,17 +1769,27 @@ def _add_chrome_proxy_extension(
1764
1769
  ):
1765
1770
  # Single-threaded
1766
1771
  if zip_it:
1767
- proxy_helper.create_proxy_ext(
1768
- proxy_string, proxy_user, proxy_pass, bypass_list
1769
- )
1770
- proxy_zip = proxy_helper.PROXY_ZIP_PATH
1771
- chrome_options.add_extension(proxy_zip)
1772
+ proxy_zip_lock = fasteners.InterProcessLock(PROXY_ZIP_LOCK)
1773
+ with proxy_zip_lock:
1774
+ proxy_helper.create_proxy_ext(
1775
+ proxy_string, proxy_user, proxy_pass, bypass_list
1776
+ )
1777
+ proxy_zip = proxy_helper.PROXY_ZIP_PATH
1778
+ chrome_options.add_extension(proxy_zip)
1772
1779
  else:
1773
- proxy_helper.create_proxy_ext(
1774
- proxy_string, proxy_user, proxy_pass, bypass_list, zip_it=False
1775
- )
1776
- proxy_dir_path = proxy_helper.PROXY_DIR_PATH
1777
- chrome_options = add_chrome_ext_dir(chrome_options, proxy_dir_path)
1780
+ proxy_dir_lock = fasteners.InterProcessLock(PROXY_DIR_LOCK)
1781
+ with proxy_dir_lock:
1782
+ proxy_helper.create_proxy_ext(
1783
+ proxy_string,
1784
+ proxy_user,
1785
+ proxy_pass,
1786
+ bypass_list,
1787
+ zip_it=False,
1788
+ )
1789
+ proxy_dir_path = proxy_helper.PROXY_DIR_PATH
1790
+ chrome_options = add_chrome_ext_dir(
1791
+ chrome_options, proxy_dir_path
1792
+ )
1778
1793
  else:
1779
1794
  # Multi-threaded
1780
1795
  if zip_it:
@@ -1803,7 +1818,7 @@ def _add_chrome_proxy_extension(
1803
1818
  proxy_user,
1804
1819
  proxy_pass,
1805
1820
  bypass_list,
1806
- False,
1821
+ zip_it=False,
1807
1822
  )
1808
1823
  chrome_options = add_chrome_ext_dir(
1809
1824
  chrome_options, proxy_helper.PROXY_DIR_PATH
@@ -4845,7 +4860,12 @@ def get_local_driver(
4845
4860
  )
4846
4861
  uc_activated = True
4847
4862
  except URLError as e:
4848
- if cert in e.args[0] and IS_MAC:
4863
+ if (
4864
+ IS_MAC
4865
+ and hasattr(e, "args")
4866
+ and isinstance(e.args, (list, tuple))
4867
+ and cert in e.args[0]
4868
+ ):
4849
4869
  mac_certificate_error = True
4850
4870
  else:
4851
4871
  raise
@@ -7,6 +7,7 @@ from contextlib import suppress
7
7
  from seleniumbase import config as sb_config
8
8
  from seleniumbase.config import settings
9
9
  from seleniumbase.fixtures import constants
10
+ from seleniumbase.fixtures import shared_utils
10
11
 
11
12
  python3_11_or_newer = False
12
13
  if sys.version_info >= (3, 11):
@@ -33,6 +34,8 @@ def log_screenshot(test_logpath, driver, screenshot=None, get=False):
33
34
  if screenshot != screenshot_warning:
34
35
  with open(screenshot_path, "wb") as file:
35
36
  file.write(screenshot)
37
+ with suppress(Exception):
38
+ shared_utils.make_writable(screenshot_path)
36
39
  else:
37
40
  print("WARNING: %s" % screenshot_warning)
38
41
  if get:
@@ -282,13 +285,14 @@ def log_test_failure_data(test, test_logpath, driver, browser, url=None):
282
285
  sb_config._report_time = the_time
283
286
  sb_config._report_traceback = traceback_message
284
287
  sb_config._report_exception = exc_message
285
- with suppress(Exception):
286
- if not os.path.exists(test_logpath):
288
+ if not os.path.exists(test_logpath):
289
+ with suppress(Exception):
287
290
  os.makedirs(test_logpath)
288
291
  with suppress(Exception):
289
292
  log_file = codecs.open(basic_file_path, "w+", encoding="utf-8")
290
293
  log_file.writelines("\r\n".join(data_to_save))
291
294
  log_file.close()
295
+ shared_utils.make_writable(basic_file_path)
292
296
 
293
297
 
294
298
  def log_skipped_test_data(test, test_logpath, driver, browser, reason):
@@ -343,6 +347,7 @@ def log_skipped_test_data(test, test_logpath, driver, browser, reason):
343
347
  log_file = codecs.open(file_path, "w+", encoding="utf-8")
344
348
  log_file.writelines("\r\n".join(data_to_save))
345
349
  log_file.close()
350
+ shared_utils.make_writable(file_path)
346
351
 
347
352
 
348
353
  def log_page_source(test_logpath, driver, source=None):
@@ -365,14 +370,15 @@ def log_page_source(test_logpath, driver, source=None):
365
370
  "unresponsive, or closed prematurely!</h4>"
366
371
  )
367
372
  )
368
- with suppress(Exception):
369
- if not os.path.exists(test_logpath):
373
+ if not os.path.exists(test_logpath):
374
+ with suppress(Exception):
370
375
  os.makedirs(test_logpath)
371
376
  html_file_path = os.path.join(test_logpath, html_file_name)
372
377
  with suppress(Exception):
373
378
  html_file = codecs.open(html_file_path, "w+", encoding="utf-8")
374
379
  html_file.write(page_source)
375
380
  html_file.close()
381
+ shared_utils.make_writable(html_file_path)
376
382
 
377
383
 
378
384
  def get_test_id(test):
@@ -2,10 +2,12 @@ import os
2
2
  import re
3
3
  import warnings
4
4
  import zipfile
5
+ from contextlib import suppress
5
6
  from seleniumbase.config import proxy_list
6
7
  from seleniumbase.config import settings
7
8
  from seleniumbase.fixtures import constants
8
9
  from seleniumbase.fixtures import page_utils
10
+ from seleniumbase.fixtures import shared_utils
9
11
 
10
12
  DOWNLOADS_DIR = constants.Files.DOWNLOADS_FOLDER
11
13
  PROXY_ZIP_PATH = os.path.join(DOWNLOADS_DIR, "proxy.zip")
@@ -109,31 +111,35 @@ def create_proxy_ext(
109
111
  """"minimum_chrome_version":"22.0.0"\n"""
110
112
  """}"""
111
113
  )
112
- import threading
113
-
114
- lock = threading.RLock() # Support multi-threaded tests. Eg. "pytest -n=4"
115
- with lock:
116
- abs_path = os.path.abspath(".")
117
- downloads_path = os.path.join(abs_path, DOWNLOADS_DIR)
118
- if not os.path.exists(downloads_path):
119
- os.mkdir(downloads_path)
120
- if zip_it:
121
- zf = zipfile.ZipFile(PROXY_ZIP_PATH, mode="w")
122
- zf.writestr("background.js", background_js)
123
- zf.writestr("manifest.json", manifest_json)
124
- zf.close()
125
- else:
126
- proxy_ext_dir = PROXY_DIR_PATH
127
- if not os.path.exists(proxy_ext_dir):
128
- os.mkdir(proxy_ext_dir)
129
- manifest_file = os.path.join(proxy_ext_dir, "manifest.json")
130
- with open(manifest_file, mode="w") as f:
131
- f.write(manifest_json)
132
- proxy_host = proxy_string.split(":")[0]
133
- proxy_port = proxy_string.split(":")[1]
134
- background_file = os.path.join(proxy_ext_dir, "background.js")
135
- with open(background_file, mode="w") as f:
136
- f.write(background_js)
114
+ abs_path = os.path.abspath(".")
115
+ downloads_path = os.path.join(abs_path, DOWNLOADS_DIR)
116
+ if not os.path.exists(downloads_path):
117
+ os.mkdir(downloads_path)
118
+ if zip_it:
119
+ zf = zipfile.ZipFile(PROXY_ZIP_PATH, mode="w")
120
+ zf.writestr("background.js", background_js)
121
+ zf.writestr("manifest.json", manifest_json)
122
+ zf.close()
123
+ with suppress(Exception):
124
+ shared_utils.make_writable(PROXY_ZIP_PATH)
125
+ else:
126
+ proxy_ext_dir = PROXY_DIR_PATH
127
+ if not os.path.exists(proxy_ext_dir):
128
+ os.mkdir(proxy_ext_dir)
129
+ with suppress(Exception):
130
+ shared_utils.make_writable(proxy_ext_dir)
131
+ manifest_file = os.path.join(proxy_ext_dir, "manifest.json")
132
+ with open(manifest_file, mode="w") as f:
133
+ f.write(manifest_json)
134
+ with suppress(Exception):
135
+ shared_utils.make_writable(manifest_json)
136
+ proxy_host = proxy_string.split(":")[0]
137
+ proxy_port = proxy_string.split(":")[1]
138
+ background_file = os.path.join(proxy_ext_dir, "background.js")
139
+ with open(background_file, mode="w") as f:
140
+ f.write(background_js)
141
+ with suppress(Exception):
142
+ shared_utils.make_writable(background_js)
137
143
 
138
144
 
139
145
  def remove_proxy_zip_if_present():
@@ -141,13 +147,12 @@ def remove_proxy_zip_if_present():
141
147
  Used in the implementation of https://stackoverflow.com/a/35293284
142
148
  for https://stackoverflow.com/questions/12848327/
143
149
  """
144
- try:
145
- if os.path.exists(PROXY_ZIP_PATH):
150
+ if os.path.exists(PROXY_ZIP_PATH):
151
+ with suppress(Exception):
146
152
  os.remove(PROXY_ZIP_PATH)
147
- if os.path.exists(PROXY_ZIP_LOCK):
153
+ if os.path.exists(PROXY_ZIP_LOCK):
154
+ with suppress(Exception):
148
155
  os.remove(PROXY_ZIP_LOCK)
149
- except Exception:
150
- pass
151
156
 
152
157
 
153
158
  def validate_proxy_string(proxy_string):
@@ -268,6 +268,7 @@ class CDPMethods():
268
268
  if number < 0:
269
269
  number = 0
270
270
  element = elements[number]
271
+ element.scroll_into_view()
271
272
  element.click()
272
273
 
273
274
  def click_nth_visible_element(self, selector, number):
@@ -284,6 +285,7 @@ class CDPMethods():
284
285
  if number < 0:
285
286
  number = 0
286
287
  element = elements[number]
288
+ element.scroll_into_view()
287
289
  element.click()
288
290
 
289
291
  def click_link(self, link_text):
@@ -311,6 +313,13 @@ class CDPMethods():
311
313
  return result
312
314
 
313
315
  def __flash(self, element, *args, **kwargs):
316
+ element.scroll_into_view()
317
+ if len(args) < 3 and "x_offset" not in kwargs:
318
+ x_offset = self.__get_x_scroll_offset()
319
+ kwargs["x_offset"] = x_offset
320
+ if len(args) < 3 and "y_offset" not in kwargs:
321
+ y_offset = self.__get_y_scroll_offset()
322
+ kwargs["y_offset"] = y_offset
314
323
  return (
315
324
  self.loop.run_until_complete(
316
325
  element.flash_async(*args, **kwargs)
@@ -382,9 +391,9 @@ class CDPMethods():
382
391
  )
383
392
 
384
393
  def __scroll_into_view(self, element):
385
- return (
386
- self.loop.run_until_complete(element.scroll_into_view_async())
387
- )
394
+ self.loop.run_until_complete(element.scroll_into_view_async())
395
+ self.__add_light_pause()
396
+ return None
388
397
 
389
398
  def __select_option(self, element):
390
399
  return (
@@ -431,6 +440,18 @@ class CDPMethods():
431
440
  self.loop.run_until_complete(element.get_js_attributes_async())
432
441
  )
433
442
 
443
+ def __get_x_scroll_offset(self):
444
+ x_scroll_offset = self.loop.run_until_complete(
445
+ self.page.evaluate("window.pageXOffset")
446
+ )
447
+ return x_scroll_offset or 0
448
+
449
+ def __get_y_scroll_offset(self):
450
+ y_scroll_offset = self.loop.run_until_complete(
451
+ self.page.evaluate("window.pageYOffset")
452
+ )
453
+ return y_scroll_offset or 0
454
+
434
455
  def tile_windows(self, windows=None, max_columns=0):
435
456
  """Tile windows and return the grid of tiled windows."""
436
457
  driver = self.driver
@@ -504,7 +525,7 @@ class CDPMethods():
504
525
  def click(self, selector, timeout=settings.SMALL_TIMEOUT):
505
526
  self.__slow_mode_pause_if_set()
506
527
  element = self.find_element(selector, timeout=timeout)
507
- self.__add_light_pause()
528
+ element.scroll_into_view()
508
529
  element.click()
509
530
  self.__slow_mode_pause_if_set()
510
531
  self.loop.run_until_complete(self.page.wait())
@@ -518,7 +539,9 @@ class CDPMethods():
518
539
 
519
540
  def click_if_visible(self, selector):
520
541
  if self.is_element_visible(selector):
521
- self.find_element(selector).click()
542
+ element = self.find_element(selector)
543
+ element.scroll_into_view()
544
+ element.click()
522
545
  self.__slow_mode_pause_if_set()
523
546
  self.loop.run_until_complete(self.page.wait())
524
547
 
@@ -545,9 +568,10 @@ class CDPMethods():
545
568
  except Exception:
546
569
  continue
547
570
  if (width != 0 or height != 0):
571
+ element.scroll_into_view()
548
572
  element.click()
549
573
  click_count += 1
550
- time.sleep(0.044)
574
+ time.sleep(0.042)
551
575
  self.__slow_mode_pause_if_set()
552
576
  self.loop.run_until_complete(self.page.wait())
553
577
  except Exception:
@@ -557,7 +581,7 @@ class CDPMethods():
557
581
  """(Attempt simulating a mouse click)"""
558
582
  self.__slow_mode_pause_if_set()
559
583
  element = self.find_element(selector, timeout=timeout)
560
- self.__add_light_pause()
584
+ element.scroll_into_view()
561
585
  element.mouse_click()
562
586
  self.__slow_mode_pause_if_set()
563
587
  self.loop.run_until_complete(self.page.wait())
@@ -579,6 +603,7 @@ class CDPMethods():
579
603
 
580
604
  def select_option_by_text(self, dropdown_selector, option):
581
605
  element = self.find_element(dropdown_selector)
606
+ element.scroll_into_view()
582
607
  options = element.query_selector_all("option")
583
608
  for found_option in options:
584
609
  if found_option.text.strip() == option.strip():
@@ -599,7 +624,10 @@ class CDPMethods():
599
624
  """Paint a quickly-vanishing dot over an element."""
600
625
  selector = self.__convert_to_css_if_xpath(selector)
601
626
  element = self.find_element(selector)
602
- element.flash(duration=duration, color=color)
627
+ element.scroll_into_view()
628
+ x_offset = self.__get_x_scroll_offset()
629
+ y_offset = self.__get_y_scroll_offset()
630
+ element.flash(duration, color, x_offset, y_offset)
603
631
  if pause and isinstance(pause, (int, float)):
604
632
  time.sleep(pause)
605
633
 
@@ -607,17 +635,22 @@ class CDPMethods():
607
635
  """Highlight an element with multi-colors."""
608
636
  selector = self.__convert_to_css_if_xpath(selector)
609
637
  element = self.find_element(selector)
610
- element.flash(0.46, "44CC88")
638
+ element.scroll_into_view()
639
+ x_offset = self.__get_x_scroll_offset()
640
+ y_offset = self.__get_y_scroll_offset()
641
+ element.flash(0.46, "44CC88", x_offset, y_offset)
611
642
  time.sleep(0.15)
612
- element.flash(0.42, "8844CC")
643
+ element.flash(0.42, "8844CC", x_offset, y_offset)
613
644
  time.sleep(0.15)
614
- element.flash(0.38, "CC8844")
645
+ element.flash(0.38, "CC8844", x_offset, y_offset)
615
646
  time.sleep(0.15)
616
- element.flash(0.30, "44CC88")
647
+ element.flash(0.30, "44CC88", x_offset, y_offset)
617
648
  time.sleep(0.30)
618
649
 
619
650
  def focus(self, selector):
620
- self.find_element(selector).focus()
651
+ element = self.find_element(selector)
652
+ element.scroll_into_view()
653
+ element.focus()
621
654
 
622
655
  def highlight_overlay(self, selector):
623
656
  self.find_element(selector).highlight_overlay()
@@ -646,7 +679,7 @@ class CDPMethods():
646
679
  def send_keys(self, selector, text, timeout=settings.SMALL_TIMEOUT):
647
680
  self.__slow_mode_pause_if_set()
648
681
  element = self.select(selector, timeout=timeout)
649
- self.__add_light_pause()
682
+ element.scroll_into_view()
650
683
  if text.endswith("\n") or text.endswith("\r"):
651
684
  text = text[:-1] + "\r\n"
652
685
  element.send_keys(text)
@@ -657,7 +690,7 @@ class CDPMethods():
657
690
  """Similar to send_keys(), but presses keys at human speed."""
658
691
  self.__slow_mode_pause_if_set()
659
692
  element = self.select(selector, timeout=timeout)
660
- self.__add_light_pause()
693
+ element.scroll_into_view()
661
694
  submit = False
662
695
  if text.endswith("\n") or text.endswith("\r"):
663
696
  submit = True
@@ -675,7 +708,7 @@ class CDPMethods():
675
708
  """Similar to send_keys(), but clears the text field first."""
676
709
  self.__slow_mode_pause_if_set()
677
710
  element = self.select(selector, timeout=timeout)
678
- self.__add_light_pause()
711
+ element.scroll_into_view()
679
712
  with suppress(Exception):
680
713
  element.clear_input()
681
714
  if text.endswith("\n") or text.endswith("\r"):
@@ -688,8 +721,8 @@ class CDPMethods():
688
721
  """Similar to send_keys(), but clears the text field first."""
689
722
  self.__slow_mode_pause_if_set()
690
723
  selector = self.__convert_to_css_if_xpath(selector)
691
- self.select(selector, timeout=timeout)
692
- self.__add_light_pause()
724
+ element = self.select(selector, timeout=timeout)
725
+ element.scroll_into_view()
693
726
  press_enter = False
694
727
  if text.endswith("\n"):
695
728
  text = text[:-1]
@@ -1655,17 +1688,24 @@ class CDPMethods():
1655
1688
  raise Exception(error % (expected, actual))
1656
1689
 
1657
1690
  def assert_text(
1658
- self, text, selector="html", timeout=settings.SMALL_TIMEOUT
1691
+ self, text, selector="body", timeout=settings.SMALL_TIMEOUT
1659
1692
  ):
1693
+ start_ms = time.time() * 1000.0
1694
+ stop_ms = start_ms + (timeout * 1000.0)
1660
1695
  text = text.strip()
1661
1696
  element = None
1662
1697
  try:
1663
1698
  element = self.find_element(selector, timeout=timeout)
1664
1699
  except Exception:
1665
1700
  raise Exception("Element {%s} not found!" % selector)
1666
- for i in range(30):
1701
+ for i in range(int(timeout * 10)):
1702
+ with suppress(Exception):
1703
+ element = self.find_element(selector, timeout=0.1)
1667
1704
  if text in element.text_all:
1668
1705
  return True
1706
+ now_ms = time.time() * 1000.0
1707
+ if now_ms >= stop_ms:
1708
+ break
1669
1709
  time.sleep(0.1)
1670
1710
  raise Exception(
1671
1711
  "Text {%s} not found in {%s}! Actual text: {%s}"
@@ -1673,20 +1713,27 @@ class CDPMethods():
1673
1713
  )
1674
1714
 
1675
1715
  def assert_exact_text(
1676
- self, text, selector="html", timeout=settings.SMALL_TIMEOUT
1716
+ self, text, selector="body", timeout=settings.SMALL_TIMEOUT
1677
1717
  ):
1718
+ start_ms = time.time() * 1000.0
1719
+ stop_ms = start_ms + (timeout * 1000.0)
1678
1720
  text = text.strip()
1679
1721
  element = None
1680
1722
  try:
1681
1723
  element = self.select(selector, timeout=timeout)
1682
1724
  except Exception:
1683
1725
  raise Exception("Element {%s} not found!" % selector)
1684
- for i in range(30):
1726
+ for i in range(int(timeout * 10)):
1727
+ with suppress(Exception):
1728
+ element = self.select(selector, timeout=0.1)
1685
1729
  if (
1686
1730
  self.is_element_visible(selector)
1687
1731
  and text.strip() == element.text_all.strip()
1688
1732
  ):
1689
1733
  return True
1734
+ now_ms = time.time() * 1000.0
1735
+ if now_ms >= stop_ms:
1736
+ break
1690
1737
  time.sleep(0.1)
1691
1738
  raise Exception(
1692
1739
  "Expected Text {%s}, is not equal to {%s} in {%s}!"
@@ -1727,26 +1774,31 @@ class CDPMethods():
1727
1774
  with suppress(Exception):
1728
1775
  self.loop.run_until_complete(self.page.evaluate(js_code))
1729
1776
  self.loop.run_until_complete(self.page.wait())
1777
+ self.__add_light_pause()
1730
1778
 
1731
1779
  def scroll_to_top(self):
1732
1780
  js_code = "window.scrollTo(0, 0);"
1733
1781
  with suppress(Exception):
1734
1782
  self.loop.run_until_complete(self.page.evaluate(js_code))
1735
1783
  self.loop.run_until_complete(self.page.wait())
1784
+ self.__add_light_pause()
1736
1785
 
1737
1786
  def scroll_to_bottom(self):
1738
1787
  js_code = "window.scrollTo(0, 10000);"
1739
1788
  with suppress(Exception):
1740
1789
  self.loop.run_until_complete(self.page.evaluate(js_code))
1741
1790
  self.loop.run_until_complete(self.page.wait())
1791
+ self.__add_light_pause()
1742
1792
 
1743
1793
  def scroll_up(self, amount=25):
1744
1794
  self.loop.run_until_complete(self.page.scroll_up(amount))
1745
1795
  self.loop.run_until_complete(self.page.wait())
1796
+ self.__add_light_pause()
1746
1797
 
1747
1798
  def scroll_down(self, amount=25):
1748
1799
  self.loop.run_until_complete(self.page.scroll_down(amount))
1749
1800
  self.loop.run_until_complete(self.page.wait())
1801
+ self.__add_light_pause()
1750
1802
 
1751
1803
  def save_screenshot(self, name, folder=None, selector=None):
1752
1804
  filename = name
@@ -1451,7 +1451,7 @@ class BaseCase(unittest.TestCase):
1451
1451
  return self.__is_shadow_element_enabled(selector)
1452
1452
  return page_actions.is_element_enabled(self.driver, selector, by)
1453
1453
 
1454
- def is_text_visible(self, text, selector="html", by="css selector"):
1454
+ def is_text_visible(self, text, selector="body", by="css selector"):
1455
1455
  """Returns whether the text substring is visible in the element."""
1456
1456
  self.wait_for_ready_state_complete()
1457
1457
  time.sleep(0.01)
@@ -1460,7 +1460,7 @@ class BaseCase(unittest.TestCase):
1460
1460
  return self.__is_shadow_text_visible(text, selector)
1461
1461
  return page_actions.is_text_visible(self.driver, text, selector, by)
1462
1462
 
1463
- def is_exact_text_visible(self, text, selector="html", by="css selector"):
1463
+ def is_exact_text_visible(self, text, selector="body", by="css selector"):
1464
1464
  """Returns whether the text is exactly equal to the element text.
1465
1465
  (Leading and trailing whitespace is ignored in the verification.)"""
1466
1466
  self.wait_for_ready_state_complete()
@@ -1472,7 +1472,7 @@ class BaseCase(unittest.TestCase):
1472
1472
  self.driver, text, selector, by
1473
1473
  )
1474
1474
 
1475
- def is_non_empty_text_visible(self, selector="html", by="css selector"):
1475
+ def is_non_empty_text_visible(self, selector="body", by="css selector"):
1476
1476
  """Returns whether the element has any non-empty text visible.
1477
1477
  Whitespace-only text is considered empty text."""
1478
1478
  self.wait_for_ready_state_complete()
@@ -1842,7 +1842,7 @@ class BaseCase(unittest.TestCase):
1842
1842
  elif self.slow_mode:
1843
1843
  self.__slow_mode_pause_if_active()
1844
1844
 
1845
- def get_text(self, selector="html", by="css selector", timeout=None):
1845
+ def get_text(self, selector="body", by="css selector", timeout=None):
1846
1846
  self.__check_scope()
1847
1847
  if not timeout:
1848
1848
  timeout = settings.LARGE_TIMEOUT
@@ -2105,7 +2105,7 @@ class BaseCase(unittest.TestCase):
2105
2105
  return property_value
2106
2106
 
2107
2107
  def get_text_content(
2108
- self, selector="html", by="css selector", timeout=None
2108
+ self, selector="body", by="css selector", timeout=None
2109
2109
  ):
2110
2110
  """Returns the text that appears in the HTML for an element.
2111
2111
  This is different from "self.get_text(selector, by="css selector")"
@@ -6093,7 +6093,7 @@ class BaseCase(unittest.TestCase):
6093
6093
  if limit > 0 and count >= limit:
6094
6094
  break
6095
6095
 
6096
- def press_up_arrow(self, selector="html", times=1, by="css selector"):
6096
+ def press_up_arrow(self, selector="body", times=1, by="css selector"):
6097
6097
  """Simulates pressing the UP Arrow on the keyboard.
6098
6098
  By default, "html" will be used as the CSS Selector target.
6099
6099
  You can specify how many times in-a-row the action happens."""
@@ -6115,7 +6115,7 @@ class BaseCase(unittest.TestCase):
6115
6115
  if self.slow_mode:
6116
6116
  time.sleep(0.1)
6117
6117
 
6118
- def press_down_arrow(self, selector="html", times=1, by="css selector"):
6118
+ def press_down_arrow(self, selector="body", times=1, by="css selector"):
6119
6119
  """Simulates pressing the DOWN Arrow on the keyboard.
6120
6120
  By default, "html" will be used as the CSS Selector target.
6121
6121
  You can specify how many times in-a-row the action happens."""
@@ -6137,7 +6137,7 @@ class BaseCase(unittest.TestCase):
6137
6137
  if self.slow_mode:
6138
6138
  time.sleep(0.1)
6139
6139
 
6140
- def press_left_arrow(self, selector="html", times=1, by="css selector"):
6140
+ def press_left_arrow(self, selector="body", times=1, by="css selector"):
6141
6141
  """Simulates pressing the LEFT Arrow on the keyboard.
6142
6142
  By default, "html" will be used as the CSS Selector target.
6143
6143
  You can specify how many times in-a-row the action happens."""
@@ -6159,7 +6159,7 @@ class BaseCase(unittest.TestCase):
6159
6159
  if self.slow_mode:
6160
6160
  time.sleep(0.1)
6161
6161
 
6162
- def press_right_arrow(self, selector="html", times=1, by="css selector"):
6162
+ def press_right_arrow(self, selector="body", times=1, by="css selector"):
6163
6163
  """Simulates pressing the RIGHT Arrow on the keyboard.
6164
6164
  By default, "html" will be used as the CSS Selector target.
6165
6165
  You can specify how many times in-a-row the action happens."""
@@ -9730,7 +9730,7 @@ class BaseCase(unittest.TestCase):
9730
9730
  ############
9731
9731
 
9732
9732
  def wait_for_text_visible(
9733
- self, text, selector="html", by="css selector", timeout=None
9733
+ self, text, selector="body", by="css selector", timeout=None
9734
9734
  ):
9735
9735
  self.__check_scope()
9736
9736
  if not timeout:
@@ -9748,7 +9748,7 @@ class BaseCase(unittest.TestCase):
9748
9748
  )
9749
9749
 
9750
9750
  def wait_for_exact_text_visible(
9751
- self, text, selector="html", by="css selector", timeout=None
9751
+ self, text, selector="body", by="css selector", timeout=None
9752
9752
  ):
9753
9753
  self.__check_scope()
9754
9754
  if not timeout:
@@ -9765,7 +9765,7 @@ class BaseCase(unittest.TestCase):
9765
9765
  )
9766
9766
 
9767
9767
  def wait_for_non_empty_text_visible(
9768
- self, selector="html", by="css selector", timeout=None
9768
+ self, selector="body", by="css selector", timeout=None
9769
9769
  ):
9770
9770
  """Searches for any text in the element of the given selector.
9771
9771
  Returns the element if it has visible text within the timeout.
@@ -9786,7 +9786,7 @@ class BaseCase(unittest.TestCase):
9786
9786
  )
9787
9787
 
9788
9788
  def wait_for_text(
9789
- self, text, selector="html", by="css selector", timeout=None
9789
+ self, text, selector="body", by="css selector", timeout=None
9790
9790
  ):
9791
9791
  """The shorter version of wait_for_text_visible()"""
9792
9792
  self.__check_scope()
@@ -9799,7 +9799,7 @@ class BaseCase(unittest.TestCase):
9799
9799
  )
9800
9800
 
9801
9801
  def wait_for_exact_text(
9802
- self, text, selector="html", by="css selector", timeout=None
9802
+ self, text, selector="body", by="css selector", timeout=None
9803
9803
  ):
9804
9804
  """The shorter version of wait_for_exact_text_visible()"""
9805
9805
  self.__check_scope()
@@ -9812,7 +9812,7 @@ class BaseCase(unittest.TestCase):
9812
9812
  )
9813
9813
 
9814
9814
  def wait_for_non_empty_text(
9815
- self, selector="html", by="css selector", timeout=None
9815
+ self, selector="body", by="css selector", timeout=None
9816
9816
  ):
9817
9817
  """The shorter version of wait_for_non_empty_text_visible()"""
9818
9818
  self.__check_scope()
@@ -9825,7 +9825,7 @@ class BaseCase(unittest.TestCase):
9825
9825
  )
9826
9826
 
9827
9827
  def find_text(
9828
- self, text, selector="html", by="css selector", timeout=None
9828
+ self, text, selector="body", by="css selector", timeout=None
9829
9829
  ):
9830
9830
  """Same as wait_for_text_visible() - returns the element"""
9831
9831
  self.__check_scope()
@@ -9838,7 +9838,7 @@ class BaseCase(unittest.TestCase):
9838
9838
  )
9839
9839
 
9840
9840
  def find_exact_text(
9841
- self, text, selector="html", by="css selector", timeout=None
9841
+ self, text, selector="body", by="css selector", timeout=None
9842
9842
  ):
9843
9843
  """Same as wait_for_exact_text_visible() - returns the element"""
9844
9844
  self.__check_scope()
@@ -9851,7 +9851,7 @@ class BaseCase(unittest.TestCase):
9851
9851
  )
9852
9852
 
9853
9853
  def find_non_empty_text(
9854
- self, selector="html", by="css selector", timeout=None
9854
+ self, selector="body", by="css selector", timeout=None
9855
9855
  ):
9856
9856
  """Same as wait_for_non_empty_text_visible() - returns the element"""
9857
9857
  self.__check_scope()
@@ -9864,7 +9864,7 @@ class BaseCase(unittest.TestCase):
9864
9864
  )
9865
9865
 
9866
9866
  def assert_text_visible(
9867
- self, text, selector="html", by="css selector", timeout=None
9867
+ self, text, selector="body", by="css selector", timeout=None
9868
9868
  ):
9869
9869
  """Same as assert_text()"""
9870
9870
  self.__check_scope()
@@ -9875,7 +9875,7 @@ class BaseCase(unittest.TestCase):
9875
9875
  return self.assert_text(text, selector, by=by, timeout=timeout)
9876
9876
 
9877
9877
  def assert_text(
9878
- self, text, selector="html", by="css selector", timeout=None
9878
+ self, text, selector="body", by="css selector", timeout=None
9879
9879
  ):
9880
9880
  """Similar to wait_for_text_visible()
9881
9881
  Raises an exception if the element or the text is not found.
@@ -9945,7 +9945,7 @@ class BaseCase(unittest.TestCase):
9945
9945
  return True
9946
9946
 
9947
9947
  def assert_exact_text(
9948
- self, text, selector="html", by="css selector", timeout=None
9948
+ self, text, selector="body", by="css selector", timeout=None
9949
9949
  ):
9950
9950
  """Similar to assert_text(), but the text must be exact,
9951
9951
  rather than exist as a subset of the full text.
@@ -9992,7 +9992,7 @@ class BaseCase(unittest.TestCase):
9992
9992
  return True
9993
9993
 
9994
9994
  def assert_non_empty_text(
9995
- self, selector="html", by="css selector", timeout=None
9995
+ self, selector="body", by="css selector", timeout=None
9996
9996
  ):
9997
9997
  """Assert that the element has any non-empty text visible.
9998
9998
  Raises an exception if the element has no text within the timeout.
@@ -10279,7 +10279,7 @@ class BaseCase(unittest.TestCase):
10279
10279
  ############
10280
10280
 
10281
10281
  def wait_for_text_not_visible(
10282
- self, text, selector="html", by="css selector", timeout=None
10282
+ self, text, selector="body", by="css selector", timeout=None
10283
10283
  ):
10284
10284
  self.__check_scope()
10285
10285
  if not timeout:
@@ -10292,7 +10292,7 @@ class BaseCase(unittest.TestCase):
10292
10292
  )
10293
10293
 
10294
10294
  def wait_for_exact_text_not_visible(
10295
- self, text, selector="html", by="css selector", timeout=None
10295
+ self, text, selector="body", by="css selector", timeout=None
10296
10296
  ):
10297
10297
  self.__check_scope()
10298
10298
  if not timeout:
@@ -10305,7 +10305,7 @@ class BaseCase(unittest.TestCase):
10305
10305
  )
10306
10306
 
10307
10307
  def assert_text_not_visible(
10308
- self, text, selector="html", by="css selector", timeout=None
10308
+ self, text, selector="body", by="css selector", timeout=None
10309
10309
  ):
10310
10310
  """Similar to wait_for_text_not_visible()
10311
10311
  Raises an exception if the text is still visible after timeout.
@@ -10326,7 +10326,7 @@ class BaseCase(unittest.TestCase):
10326
10326
  return True
10327
10327
 
10328
10328
  def assert_exact_text_not_visible(
10329
- self, text, selector="html", by="css selector", timeout=None
10329
+ self, text, selector="body", by="css selector", timeout=None
10330
10330
  ):
10331
10331
  """Similar to wait_for_exact_text_not_visible()
10332
10332
  Raises an exception if the exact text is still visible after timeout.
@@ -11083,7 +11083,7 @@ class BaseCase(unittest.TestCase):
11083
11083
  return False
11084
11084
 
11085
11085
  def deferred_assert_text(
11086
- self, text, selector="html", by="css selector", timeout=None, fs=False
11086
+ self, text, selector="body", by="css selector", timeout=None, fs=False
11087
11087
  ):
11088
11088
  """A non-terminating assertion for text from an element on a page.
11089
11089
  Failures will be saved until the process_deferred_asserts()
@@ -11119,7 +11119,7 @@ class BaseCase(unittest.TestCase):
11119
11119
  return False
11120
11120
 
11121
11121
  def deferred_assert_exact_text(
11122
- self, text, selector="html", by="css selector", timeout=None, fs=False
11122
+ self, text, selector="body", by="css selector", timeout=None, fs=False
11123
11123
  ):
11124
11124
  """A non-terminating assertion for exact text from an element.
11125
11125
  Failures will be saved until the process_deferred_asserts()
@@ -11158,7 +11158,7 @@ class BaseCase(unittest.TestCase):
11158
11158
 
11159
11159
  def deferred_assert_non_empty_text(
11160
11160
  self,
11161
- selector="html",
11161
+ selector="body",
11162
11162
  by="css selector",
11163
11163
  timeout=None,
11164
11164
  fs=False,
@@ -11278,7 +11278,7 @@ class BaseCase(unittest.TestCase):
11278
11278
  )
11279
11279
 
11280
11280
  def delayed_assert_text(
11281
- self, text, selector="html", by="css selector", timeout=None, fs=False
11281
+ self, text, selector="body", by="css selector", timeout=None, fs=False
11282
11282
  ):
11283
11283
  """Same as self.deferred_assert_text()"""
11284
11284
  return self.deferred_assert_text(
@@ -11286,7 +11286,7 @@ class BaseCase(unittest.TestCase):
11286
11286
  )
11287
11287
 
11288
11288
  def delayed_assert_exact_text(
11289
- self, text, selector="html", by="css selector", timeout=None, fs=False
11289
+ self, text, selector="body", by="css selector", timeout=None, fs=False
11290
11290
  ):
11291
11291
  """Same as self.deferred_assert_exact_text()"""
11292
11292
  return self.deferred_assert_exact_text(
@@ -11295,7 +11295,7 @@ class BaseCase(unittest.TestCase):
11295
11295
 
11296
11296
  def delayed_assert_non_empty_text(
11297
11297
  self,
11298
- selector="html",
11298
+ selector="body",
11299
11299
  by="css selector",
11300
11300
  timeout=None,
11301
11301
  fs=False,
@@ -1188,6 +1188,8 @@ def highlight_with_jquery_2(driver, message, selector, o_bs, msg_dur):
1188
1188
  def get_active_element_css(driver):
1189
1189
  from seleniumbase.js_code import active_css_js
1190
1190
 
1191
+ if shared_utils.is_cdp_swap_needed(driver):
1192
+ return driver.cdp.get_active_element_css()
1191
1193
  return execute_script(driver, active_css_js.get_active_element_css)
1192
1194
 
1193
1195
 
@@ -1,6 +1,7 @@
1
1
  """Shared utility methods"""
2
2
  import colorama
3
3
  import os
4
+ import pathlib
4
5
  import platform
5
6
  import sys
6
7
  import time
@@ -128,6 +129,16 @@ def is_chrome_130_or_newer(self, binary_location=None):
128
129
  return False
129
130
 
130
131
 
132
+ def make_dir_files_writable(dir_path):
133
+ # Make all files in the given directory writable.
134
+ for file_path in pathlib.Path(dir_path).glob("*"):
135
+ if file_path.is_file():
136
+ mode = os.stat(file_path).st_mode
137
+ mode |= (mode & 0o444) >> 1 # copy R bits to W
138
+ with suppress(Exception):
139
+ os.chmod(file_path, mode)
140
+
141
+
131
142
  def make_writable(file_path):
132
143
  # Set permissions to: "If you can read it, you can write it."
133
144
  mode = os.stat(file_path).st_mode
@@ -2143,6 +2143,9 @@ def _perform_pytest_unconfigure_(config):
2143
2143
  log_helper.archive_logs_if_set(
2144
2144
  constants.Logs.LATEST + "/", sb_config.archive_logs
2145
2145
  )
2146
+ if os.path.exists("./assets/"): # Used by pytest-html reports
2147
+ with suppress(Exception):
2148
+ shared_utils.make_dir_files_writable("./assets/")
2146
2149
  log_helper.clear_empty_logs()
2147
2150
  # Dashboard post-processing: Disable time-based refresh and stamp complete
2148
2151
  if not hasattr(sb_config, "dashboard") or not sb_config.dashboard:
@@ -2207,8 +2210,12 @@ def _perform_pytest_unconfigure_(config):
2207
2210
  )
2208
2211
  with open(html_report_path, "w", encoding="utf-8") as f:
2209
2212
  f.write(the_html_r) # Finalize the HTML report
2213
+ with suppress(Exception):
2214
+ shared_utils.make_writable(html_report_path)
2210
2215
  with open(html_report_path_copy, "w", encoding="utf-8") as f:
2211
- f.write(the_html_r) # Finalize the HTML report
2216
+ f.write(the_html_r) # Finalize the HTML report copy
2217
+ with suppress(Exception):
2218
+ shared_utils.make_writable(html_report_path_copy)
2212
2219
  assets_style = "./assets/style.css"
2213
2220
  if os.path.exists(assets_style):
2214
2221
  html_style = None
@@ -2223,6 +2230,8 @@ def _perform_pytest_unconfigure_(config):
2223
2230
  )
2224
2231
  with open(assets_style, "w", encoding="utf-8") as f:
2225
2232
  f.write(html_style)
2233
+ with suppress(Exception):
2234
+ shared_utils.make_writable(assets_style)
2226
2235
  # Done with "pytest_unconfigure" unless using the Dashboard
2227
2236
  return
2228
2237
  stamp = ""
@@ -2304,6 +2313,8 @@ def _perform_pytest_unconfigure_(config):
2304
2313
  )
2305
2314
  with open(dashboard_path, "w", encoding="utf-8") as f:
2306
2315
  f.write(the_html_d) # Finalize the dashboard
2316
+ with suppress(Exception):
2317
+ shared_utils.make_writable(dashboard_path)
2307
2318
  assets_style = "./assets/style.css"
2308
2319
  if os.path.exists(assets_style):
2309
2320
  html_style = None
@@ -2318,6 +2329,8 @@ def _perform_pytest_unconfigure_(config):
2318
2329
  )
2319
2330
  with open(assets_style, "w", encoding="utf-8") as f:
2320
2331
  f.write(html_style)
2332
+ with suppress(Exception):
2333
+ shared_utils.make_writable(assets_style)
2321
2334
  # Part 2: Appending a pytest html report with dashboard data
2322
2335
  html_report_path = None
2323
2336
  if sb_config._html_report_name:
@@ -2398,8 +2411,12 @@ def _perform_pytest_unconfigure_(config):
2398
2411
  )
2399
2412
  with open(html_report_path, "w", encoding="utf-8") as f:
2400
2413
  f.write(the_html_r) # Finalize the HTML report
2414
+ with suppress(Exception):
2415
+ shared_utils.make_writable(html_report_path)
2401
2416
  with open(html_report_path_copy, "w", encoding="utf-8") as f:
2402
- f.write(the_html_r) # Finalize the HTML report
2417
+ f.write(the_html_r) # Finalize the HTML report copy
2418
+ with suppress(Exception):
2419
+ shared_utils.make_writable(html_report_path_copy)
2403
2420
  except KeyboardInterrupt:
2404
2421
  pass
2405
2422
  except Exception:
@@ -883,6 +883,8 @@ class Element:
883
883
  self,
884
884
  duration: typing.Union[float, int] = 0.5,
885
885
  color: typing.Optional[str] = "EE4488",
886
+ x_offset: typing.Union[float, int] = 0,
887
+ y_offset: typing.Union[float, int] = 0,
886
888
  ):
887
889
  """
888
890
  Displays for a short time a red dot on the element.
@@ -910,8 +912,8 @@ class Element:
910
912
  "width:8px;height:8px;border-radius:50%;background:#{};"
911
913
  "animation:show-pointer-ani {:.2f}s ease 1;"
912
914
  ).format(
913
- pos.center[0] - 4, # -4 to account for drawn circle itself (w,h)
914
- pos.center[1] - 4,
915
+ pos.center[0] + x_offset - 4, # -4 to account for the circle
916
+ pos.center[1] + y_offset - 4, # -4 to account for the circle
915
917
  color,
916
918
  duration,
917
919
  )
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: seleniumbase
3
- Version: 4.33.6
3
+ Version: 4.33.7
4
4
  Summary: A complete web automation framework for end-to-end testing.
5
5
  Home-page: https://github.com/seleniumbase/SeleniumBase
6
6
  Author: Michael Mintz
@@ -3,7 +3,7 @@ sbase/__main__.py,sha256=G0bVB1-DM4PGwQ1KyOupaWCs4ePbChZNNWuX2htim5U,647
3
3
  sbase/steps.py,sha256=_WvAjydKqZfTdnZW9LPKkRty-g-lfdUPmLqnZj6ulcs,43013
4
4
  seleniumbase/__init__.py,sha256=OtJh8nGKL4xtZpw8KPqmn7Q6R-86t4cWUDyVF5MbMTo,2398
5
5
  seleniumbase/__main__.py,sha256=dn1p6dgCchmcH1zzTzzQvFwwdQQqnTGH6ULV9m4hv24,654
6
- seleniumbase/__version__.py,sha256=tGf6JE86qsdvGT3Hg89rYziT4htXliGRqhNNRUHlu7Y,46
6
+ seleniumbase/__version__.py,sha256=nUNoxjUDcXHP7bgCzQttf4Edyro2DVTDgt8rIwb4KXs,46
7
7
  seleniumbase/behave/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
8
8
  seleniumbase/behave/behave_helper.py,sha256=elkl8P9eLulRAioLstE9baYNM9N_PHBmAOcajX-pH_Y,24198
9
9
  seleniumbase/behave/behave_sb.py,sha256=-hza7Nx2U41mSObYiPMi48v3JlPh3sJO3yzP0kqZ1Gk,59174
@@ -36,7 +36,7 @@ seleniumbase/console_scripts/sb_print.py,sha256=tNy-bMDgwHJO3bZxMpmo9weSE8uhbH0C
36
36
  seleniumbase/console_scripts/sb_recorder.py,sha256=fnHb5-kh11Hit-E9Ha-e4QXzqLcZvtij6mb5qNd4B1Q,11032
37
37
  seleniumbase/core/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
38
38
  seleniumbase/core/application_manager.py,sha256=e_0sjtI8cjY5BNyZj1QBR0j6_oCScxGmSXYEpcYwuZE,576
39
- seleniumbase/core/browser_launcher.py,sha256=D_bfBkZsBAq5-XlI49CCdazydYHccuFJy0tPPAE3lOE,223704
39
+ seleniumbase/core/browser_launcher.py,sha256=0J5J7kXG30aptlPQ3JdFcu8-U4lC_Y6U_47kkHbyKoo,224666
40
40
  seleniumbase/core/capabilities_parser.py,sha256=meIS2uHapTCq2ldfNAToC7r0cKmZDRXuYNKExM1GHDY,6038
41
41
  seleniumbase/core/colored_traceback.py,sha256=DrRWfg7XEnKcgY59Xj7Jdk09H-XqHYBSUpB-DiZt6iY,2020
42
42
  seleniumbase/core/create_db_tables.sql,sha256=VWPtrdiW_HQ6yETHjqTu-VIrTwvd8I8o1NfBeaVSHpU,972
@@ -44,13 +44,13 @@ seleniumbase/core/detect_b_ver.py,sha256=RxeGRMbBUTMrXh5KsS1P1SH7eEKYbzL1vQw1gTd
44
44
  seleniumbase/core/download_helper.py,sha256=qSR54kQISucF4RQaLCOuuerSu6DR41juGi_30HVvWYY,2943
45
45
  seleniumbase/core/encoded_images.py,sha256=rDKJ4cNJSuKiRcFViYU7bjyTS9_moI57gUPRXVg3u2k,14209
46
46
  seleniumbase/core/jqc_helper.py,sha256=2DDQr9Q2jSSZqFzX588jLlUM9oJvyrRWq2aORSIPUdI,10322
47
- seleniumbase/core/log_helper.py,sha256=mtZLuvpy3lZpXqQ1ekng11_P5sBkyiI7eXhJGm9j15I,22693
47
+ seleniumbase/core/log_helper.py,sha256=N0YbsRy8sEoGQu4BjiAJHC5mK_ydl0YLgRp6jAcwwos,22987
48
48
  seleniumbase/core/mysql.py,sha256=8Fzj3p5dhtDWfMpFqFYxpSwa9s1UltiHsWJ56_aPOqk,3993
49
- seleniumbase/core/proxy_helper.py,sha256=cXhu8ErK9Vjdm82RMaQj7hEq_yUWizSp6LyiD50Ieu4,8020
49
+ seleniumbase/core/proxy_helper.py,sha256=kZnfkflB3XhuL2h-3inmx3UOLS8VAZ385BGCc4H8TvU,8267
50
50
  seleniumbase/core/recorder_helper.py,sha256=fNGjbapXmEsht54x1o6Igk198QdnPxDDnjUOzQxNhNQ,25055
51
51
  seleniumbase/core/report_helper.py,sha256=AIl6Qava2yW1uSzbLpJBlPlYDz0KE-rVhogh8hsGWBo,12201
52
52
  seleniumbase/core/s3_manager.py,sha256=bkeI8I4y19ebWuQG1oEZV5qJbotC6eN8vin31OCNWJk,3521
53
- seleniumbase/core/sb_cdp.py,sha256=wieKEfVZjbzX0AivHabtHPwsfmJLvg8Ks3RMO7Qa9KE,68274
53
+ seleniumbase/core/sb_cdp.py,sha256=Z2do1FqwfFAK-xgrZ6f_-wTMf3DSbI-ShHRZ34nFy5w,70437
54
54
  seleniumbase/core/sb_driver.py,sha256=NGa4adi8OAi2WFtFkEguXg3JCd1p-JuZweIpGNifEfU,13488
55
55
  seleniumbase/core/session_helper.py,sha256=s9zD3PVZEWVzG2h81cCUskbNWLfdjC_LwwQjKptHCak,558
56
56
  seleniumbase/core/settings_parser.py,sha256=KokVXpCiGZhJ-D4Bo-hizPz5r-iefzWoiTANu9zNaq4,7504
@@ -65,14 +65,14 @@ seleniumbase/extensions/disable_csp.zip,sha256=YMifIIgEBiLrEFrS1sfW4Exh4br1V4oK1
65
65
  seleniumbase/extensions/recorder.zip,sha256=OOyzF-Ize2cSRu1CqhzSAq5vusI9hqLLd2OIApUHesI,11918
66
66
  seleniumbase/extensions/sbase_ext.zip,sha256=3s1N8zrVaMz8RQEOIoBzC3KDjtmHwVZRvVsX25Odr_s,8175
67
67
  seleniumbase/fixtures/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
68
- seleniumbase/fixtures/base_case.py,sha256=HyRCsvOPN3E3tBOOonK0698IRWd-XaxNEMcciLnj8OI,718550
68
+ seleniumbase/fixtures/base_case.py,sha256=6MVQDcQ8woA3sis2hH6epDaVNjefsd2m1xzjJn9mugs,718550
69
69
  seleniumbase/fixtures/constants.py,sha256=e1LppavlrAcI4XBJMq7u5j8SffaQ7SPQps1y0YvZYfY,13649
70
70
  seleniumbase/fixtures/css_to_xpath.py,sha256=9ouDB1xl4MJ2os6JOgTIAyHKOQfuxtxvXC3O5hSnEKA,1954
71
71
  seleniumbase/fixtures/errors.py,sha256=KyxuEVx_e3MPhVrJfNIa_3ltMpbCFxfy_jxK8RFNTns,555
72
- seleniumbase/fixtures/js_utils.py,sha256=t-hqdd75O6Kfe6y5U8986gvZGATpPfDiDnIqeZZodgw,51435
72
+ seleniumbase/fixtures/js_utils.py,sha256=asZJ0LDFv2BPQOzUVKK_9ie8ToGcmFousDnGdb3Vabg,51534
73
73
  seleniumbase/fixtures/page_actions.py,sha256=dbp63c-7asYZyd8aOu57Y3dxQQozp_VJsP5h74s1kBA,66552
74
74
  seleniumbase/fixtures/page_utils.py,sha256=5m7iXpikLs80TJoRO6_gEfXE1AKeQgcH1aFbR8o1C9A,12034
75
- seleniumbase/fixtures/shared_utils.py,sha256=uDwq23NWl3iL6uID16sv93bY8CjaMfItXBjLwjRr2tw,7985
75
+ seleniumbase/fixtures/shared_utils.py,sha256=G6CsE-Adt-GfuZF-71jXWKSIQW7YZPx8FIM24pVd_yI,8368
76
76
  seleniumbase/fixtures/unittest_helper.py,sha256=sfZ92rZeBAn_sF_yQ3I6_I7h3lyU5-cV_UMegBNoEm8,1294
77
77
  seleniumbase/fixtures/words.py,sha256=FOA4mAYvl3EPVpBTvgvK6YwCL8BdlRCmed685kEe7Vg,7827
78
78
  seleniumbase/fixtures/xpath_to_css.py,sha256=lML56k656fElXJ4NJF07r35FjctrbgQkXUotNk7A-as,8876
@@ -88,7 +88,7 @@ seleniumbase/plugins/basic_test_info.py,sha256=8ov6n417gPbqqvrlT4zrch7l2XcRt-GF2
88
88
  seleniumbase/plugins/db_reporting_plugin.py,sha256=En09qUCoojrk9-vbcnsoHdSELoGmag2GDIyu3jTiJas,7331
89
89
  seleniumbase/plugins/driver_manager.py,sha256=s20s0pJYaNrG0WNwyIC04oUMRVFjtm6V_nS1-EvFm7g,34492
90
90
  seleniumbase/plugins/page_source.py,sha256=loTnXxOj4kxEukuTZEiGyvKBhY3KDVDMnNlHHheTBDE,1889
91
- seleniumbase/plugins/pytest_plugin.py,sha256=v95Ovdwd1-Kqhf05BkDtC_YfF7_cF5v9WDnpsxT7frg,104506
91
+ seleniumbase/plugins/pytest_plugin.py,sha256=JjpglUqHkfl6rzdg1SkJ7PMtNRpceOgLNbUi2DyKpJI,105416
92
92
  seleniumbase/plugins/s3_logging_plugin.py,sha256=WDfertQgGOW_SRJpFMaekYD6vBVW9VO62POtXXy2HCM,2319
93
93
  seleniumbase/plugins/sb_manager.py,sha256=qCf6RAkAfziLTGgiJvB3V416RxWoTbRLm9wc-KsB8g8,54419
94
94
  seleniumbase/plugins/screen_shots.py,sha256=1hrXw-hzuZ1BR6Yh7AyWX2ABnvnP73-RCbwdz958gj4,1127
@@ -119,7 +119,7 @@ seleniumbase/undetected/cdp_driver/browser.py,sha256=n8GYspU7b0pfBT4AqhqY6IdGVOZ
119
119
  seleniumbase/undetected/cdp_driver/cdp_util.py,sha256=YhtD2Tm6PLIy9VKbgk8lHdGniS3mObyX4yAC1aG0TgQ,16733
120
120
  seleniumbase/undetected/cdp_driver/config.py,sha256=Rjvde7V-XJ0ihZdTmOmHEVWSuDWm3SprQ3njg8SN3Go,12087
121
121
  seleniumbase/undetected/cdp_driver/connection.py,sha256=sOTUGjbUqKA2hPvDcRCdqw1VQjVGJs7mbgVvzS7ldtE,23360
122
- seleniumbase/undetected/cdp_driver/element.py,sha256=wEHtuF9oiny7cb4QMMjdtD5Yf1z3WOs2_NHEWcscusM,40289
122
+ seleniumbase/undetected/cdp_driver/element.py,sha256=610eW609khWp2hFn9gKUx4DDxeJdPZ5jb0Vxe1W-9PY,40426
123
123
  seleniumbase/undetected/cdp_driver/tab.py,sha256=cmSUg9fRnIVYgeqs-t8Tcg1FrSVIrM5IBQmCMzvl4OQ,50678
124
124
  seleniumbase/utilities/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
125
125
  seleniumbase/utilities/selenium_grid/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
@@ -135,9 +135,9 @@ seleniumbase/utilities/selenium_grid/start-grid-hub.bat,sha256=Ftq-GrAKRYH2ssDPr
135
135
  seleniumbase/utilities/selenium_grid/start-grid-hub.sh,sha256=KADv0RUHONLL2_I443QFK8PryBpDmKn5Gy0s4o0vDSM,106
136
136
  seleniumbase/utilities/selenium_ide/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
137
137
  seleniumbase/utilities/selenium_ide/convert_ide.py,sha256=pZFnqEJQEKZPyNFjkLD29s2HPQgCrWW9XJWpCPhWOoM,31691
138
- seleniumbase-4.33.6.dist-info/LICENSE,sha256=odSYtWibXBnQ1gBg6CnDZ82n8kLF_if5-2nbqnEyD8k,1085
139
- seleniumbase-4.33.6.dist-info/METADATA,sha256=U6U9MYVrwKt5UAQvZLghzL2kEkNnTEadmP6TZZrMzvI,86528
140
- seleniumbase-4.33.6.dist-info/WHEEL,sha256=PZUExdf71Ui_so67QXpySuHtCi3-J3wvF4ORK6k_S8U,91
141
- seleniumbase-4.33.6.dist-info/entry_points.txt,sha256=CNrh2EKNaHYEhO6pP1RJyVLB99LkDDYX7TnUK8xfjqk,623
142
- seleniumbase-4.33.6.dist-info/top_level.txt,sha256=4N97aBOQ8ETCnDnokBsWb07lJfTaq3C1ZzYRxvLMxqU,19
143
- seleniumbase-4.33.6.dist-info/RECORD,,
138
+ seleniumbase-4.33.7.dist-info/LICENSE,sha256=odSYtWibXBnQ1gBg6CnDZ82n8kLF_if5-2nbqnEyD8k,1085
139
+ seleniumbase-4.33.7.dist-info/METADATA,sha256=iP-VXv10VT9xAD7UJPlD8tTJi7J88s6D3GCy1gvec6E,86528
140
+ seleniumbase-4.33.7.dist-info/WHEEL,sha256=PZUExdf71Ui_so67QXpySuHtCi3-J3wvF4ORK6k_S8U,91
141
+ seleniumbase-4.33.7.dist-info/entry_points.txt,sha256=CNrh2EKNaHYEhO6pP1RJyVLB99LkDDYX7TnUK8xfjqk,623
142
+ seleniumbase-4.33.7.dist-info/top_level.txt,sha256=4N97aBOQ8ETCnDnokBsWb07lJfTaq3C1ZzYRxvLMxqU,19
143
+ seleniumbase-4.33.7.dist-info/RECORD,,