seleniumbase 4.34.14__py3-none-any.whl → 4.34.16__py3-none-any.whl

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.
@@ -1,2 +1,2 @@
1
1
  # seleniumbase package
2
- __version__ = "4.34.14"
2
+ __version__ = "4.34.16"
@@ -107,7 +107,7 @@ def make_driver_executable_if_not(driver_path):
107
107
  shared_utils.make_executable(driver_path)
108
108
 
109
109
 
110
- def extend_driver(driver):
110
+ def extend_driver(driver, proxy_auth=False, use_uc=True):
111
111
  # Extend the driver with new methods
112
112
  driver.default_find_element = driver.find_element
113
113
  driver.default_find_elements = driver.find_elements
@@ -235,6 +235,8 @@ def extend_driver(driver):
235
235
  driver.reset_window_size = DM.reset_window_size
236
236
  if hasattr(driver, "proxy"):
237
237
  driver.set_wire_proxy = DM.set_wire_proxy
238
+ if proxy_auth and not use_uc:
239
+ time.sleep(0.11) # Proxy needs moment to load in Manifest V3
238
240
  return driver
239
241
 
240
242
 
@@ -716,6 +718,10 @@ def uc_open_with_cdp_mode(driver, url=None):
716
718
  cdp.is_selected = CDPM.is_selected
717
719
  cdp.is_element_present = CDPM.is_element_present
718
720
  cdp.is_element_visible = CDPM.is_element_visible
721
+ cdp.is_text_visible = CDPM.is_text_visible
722
+ cdp.is_exact_text_visible = CDPM.is_exact_text_visible
723
+ cdp.wait_for_text = CDPM.wait_for_text
724
+ cdp.wait_for_text_not_visible = CDPM.wait_for_text_not_visible
719
725
  cdp.wait_for_element_visible = CDPM.wait_for_element_visible
720
726
  cdp.assert_element = CDPM.assert_element
721
727
  cdp.assert_element_visible = CDPM.assert_element_visible
@@ -729,6 +735,7 @@ def uc_open_with_cdp_mode(driver, url=None):
729
735
  cdp.assert_url_contains = CDPM.assert_url_contains
730
736
  cdp.assert_text = CDPM.assert_text
731
737
  cdp.assert_exact_text = CDPM.assert_exact_text
738
+ cdp.assert_text_not_visible = CDPM.assert_text_not_visible
732
739
  cdp.assert_true = CDPM.assert_true
733
740
  cdp.assert_false = CDPM.assert_false
734
741
  cdp.assert_equal = CDPM.assert_equal
@@ -2278,6 +2285,7 @@ def _set_chrome_options(
2278
2285
  or proxy_string
2279
2286
  ):
2280
2287
  chrome_options.add_argument("--ignore-certificate-errors")
2288
+ chrome_options.add_argument("--ignore-ssl-errors=yes")
2281
2289
  if not enable_ws:
2282
2290
  chrome_options.add_argument("--disable-web-security")
2283
2291
  if (
@@ -3591,6 +3599,7 @@ def get_local_driver(
3591
3599
  Can also be used to spin up additional browsers for the same test."""
3592
3600
  downloads_path = DOWNLOADS_FOLDER
3593
3601
  b_path = binary_location
3602
+ use_uc = is_using_uc(undetectable, browser_name)
3594
3603
  if use_wire:
3595
3604
  pip_find_lock = fasteners.InterProcessLock(
3596
3605
  constants.PipInstall.FINDLOCK
@@ -4064,7 +4073,7 @@ def get_local_driver(
4064
4073
  edge_options.add_argument("--headless=old")
4065
4074
  else:
4066
4075
  edge_options.add_argument("--headless")
4067
- if mobile_emulator and not is_using_uc(undetectable, browser_name):
4076
+ if mobile_emulator and not use_uc:
4068
4077
  emulator_settings = {}
4069
4078
  device_metrics = {}
4070
4079
  if (
@@ -4128,7 +4137,7 @@ def get_local_driver(
4128
4137
  settings.CHROME_START_HEIGHT,
4129
4138
  )
4130
4139
  )
4131
- if user_data_dir and not is_using_uc(undetectable, browser_name):
4140
+ if user_data_dir and not use_uc:
4132
4141
  abs_path = os.path.abspath(user_data_dir)
4133
4142
  edge_options.add_argument("--user-data-dir=%s" % abs_path)
4134
4143
  if extension_zip:
@@ -4163,7 +4172,7 @@ def get_local_driver(
4163
4172
  edge_options.add_argument("--disable-prompt-on-repost")
4164
4173
  if not enable_3d_apis:
4165
4174
  edge_options.add_argument("--disable-3d-apis")
4166
- if headless or headless2 or is_using_uc(undetectable, browser_name):
4175
+ if headless or headless2 or use_uc:
4167
4176
  edge_options.add_argument("--disable-renderer-backgrounding")
4168
4177
  edge_options.add_argument("--disable-backgrounding-occluded-windows")
4169
4178
  edge_options.add_argument("--disable-client-side-phishing-detection")
@@ -4228,6 +4237,7 @@ def get_local_driver(
4228
4237
  edge_options.add_argument("--log-level=3")
4229
4238
  edge_options.add_argument("--no-first-run")
4230
4239
  edge_options.add_argument("--ignore-certificate-errors")
4240
+ edge_options.add_argument("--ignore-ssl-errors=yes")
4231
4241
  if devtools and not headless:
4232
4242
  edge_options.add_argument("--auto-open-devtools-for-tabs")
4233
4243
  edge_options.add_argument("--allow-file-access-from-files")
@@ -4235,10 +4245,7 @@ def get_local_driver(
4235
4245
  edge_options.add_argument("--allow-running-insecure-content")
4236
4246
  if user_agent:
4237
4247
  edge_options.add_argument("--user-agent=%s" % user_agent)
4238
- if (
4239
- IS_LINUX
4240
- or (IS_MAC and not is_using_uc(undetectable, browser_name))
4241
- ):
4248
+ if IS_LINUX or (IS_MAC and not use_uc):
4242
4249
  edge_options.add_argument("--no-sandbox")
4243
4250
  if remote_debug:
4244
4251
  # To access the Debugger, go to: edge://inspect/#devices
@@ -4252,10 +4259,7 @@ def get_local_driver(
4252
4259
  if swiftshader:
4253
4260
  edge_options.add_argument("--use-gl=angle")
4254
4261
  edge_options.add_argument("--use-angle=swiftshader-webgl")
4255
- elif (
4256
- not is_using_uc(undetectable, browser_name)
4257
- and not enable_3d_apis
4258
- ):
4262
+ elif not use_uc and not enable_3d_apis:
4259
4263
  edge_options.add_argument("--disable-gpu")
4260
4264
  if IS_LINUX:
4261
4265
  edge_options.add_argument("--disable-dev-shm-usage")
@@ -4502,14 +4506,14 @@ def get_local_driver(
4502
4506
  and len(saved_mcv.split(".")) == 4
4503
4507
  ):
4504
4508
  driver_version = saved_mcv
4505
- if is_using_uc(undetectable, browser_name):
4509
+ if use_uc:
4506
4510
  use_br_version_for_uc = True
4507
4511
  if (
4508
4512
  (headless or headless2)
4509
4513
  and IS_WINDOWS
4510
4514
  and major_chrome_version
4511
4515
  and int(major_chrome_version) >= 117
4512
- and not is_using_uc(undetectable, browser_name)
4516
+ and not use_uc
4513
4517
  and not (remote_debug or devtools or use_wire)
4514
4518
  and not (proxy_string or multi_proxy or proxy_pac_url)
4515
4519
  and (not chromium_arg or "debug" not in chromium_arg)
@@ -4565,7 +4569,7 @@ def get_local_driver(
4565
4569
  use_version = ch_driver_version
4566
4570
  disable_build_check = True
4567
4571
  uc_driver_version = None
4568
- if is_using_uc(undetectable, browser_name):
4572
+ if use_uc:
4569
4573
  if use_br_version_for_uc or driver_version == "mlatest":
4570
4574
  uc_driver_version = get_uc_driver_version(full=True)
4571
4575
  full_ch_driver_version = uc_driver_version
@@ -4626,7 +4630,6 @@ def get_local_driver(
4626
4630
  "\nWarning: Could not make chromedriver"
4627
4631
  " executable: %s" % e
4628
4632
  )
4629
- use_uc = is_using_uc(undetectable, browser_name)
4630
4633
  make_uc_driver_from_chromedriver = False
4631
4634
  local_ch_exists = (
4632
4635
  LOCAL_CHROMEDRIVER and os.path.exists(LOCAL_CHROMEDRIVER)
@@ -4843,7 +4846,7 @@ def get_local_driver(
4843
4846
  service_args = []
4844
4847
  if disable_build_check:
4845
4848
  service_args = ["--disable-build-check"]
4846
- if is_using_uc(undetectable, browser_name):
4849
+ if use_uc:
4847
4850
  uc_lock = fasteners.InterProcessLock(
4848
4851
  constants.MultiBrowser.DRIVER_FIXING_LOCK
4849
4852
  )
@@ -4872,20 +4875,14 @@ def get_local_driver(
4872
4875
  "\nWarning: Could not make uc_driver"
4873
4876
  " executable: %s" % e
4874
4877
  )
4875
- if (
4876
- not headless
4877
- or not IS_LINUX
4878
- or is_using_uc(undetectable, browser_name)
4879
- ):
4878
+ if not headless or not IS_LINUX or use_uc:
4880
4879
  uc_activated = False
4881
4880
  try:
4882
- if (
4883
- os.path.exists(LOCAL_CHROMEDRIVER)
4884
- or is_using_uc(undetectable, browser_name)
4885
- ):
4881
+ if os.path.exists(LOCAL_CHROMEDRIVER) or use_uc:
4886
4882
  if headless and not IS_LINUX:
4887
4883
  undetectable = False # No support for headless
4888
- if is_using_uc(undetectable, browser_name):
4884
+ use_uc = is_using_uc(undetectable, browser_name)
4885
+ if use_uc:
4889
4886
  from seleniumbase import undetected
4890
4887
  from urllib.error import URLError
4891
4888
  if IS_LINUX:
@@ -5185,7 +5182,7 @@ def get_local_driver(
5185
5182
  driver = webdriver.Chrome(
5186
5183
  service=service, options=chrome_options
5187
5184
  )
5188
- return extend_driver(driver)
5185
+ return extend_driver(driver, proxy_auth, use_uc)
5189
5186
  if not auto_upgrade_chromedriver:
5190
5187
  raise # Not an obvious fix.
5191
5188
  else:
@@ -5436,11 +5433,11 @@ def get_local_driver(
5436
5433
  'Emulation.setDeviceMetricsOverride',
5437
5434
  set_device_metrics_override
5438
5435
  )
5439
- return extend_driver(driver)
5436
+ return extend_driver(driver, proxy_auth, use_uc)
5440
5437
  else: # Running headless on Linux (and not using --uc)
5441
5438
  try:
5442
5439
  driver = webdriver.Chrome(options=chrome_options)
5443
- return extend_driver(driver)
5440
+ return extend_driver(driver, proxy_auth, use_uc)
5444
5441
  except Exception as e:
5445
5442
  if not hasattr(e, "msg"):
5446
5443
  raise
@@ -5462,7 +5459,7 @@ def get_local_driver(
5462
5459
  driver = webdriver.Chrome(
5463
5460
  service=service, options=chrome_options
5464
5461
  )
5465
- return extend_driver(driver)
5462
+ return extend_driver(driver, proxy_auth, use_uc)
5466
5463
  mcv = None # Major Chrome Version
5467
5464
  if "Current browser version is " in e.msg:
5468
5465
  line = e.msg.split("Current browser version is ")[1]
@@ -5505,7 +5502,7 @@ def get_local_driver(
5505
5502
  service=service,
5506
5503
  options=chrome_options,
5507
5504
  )
5508
- return extend_driver(driver)
5505
+ return extend_driver(driver, proxy_auth, use_uc)
5509
5506
  # Use the virtual display on Linux during headless errors
5510
5507
  logging.debug(
5511
5508
  "\nWarning: Chrome failed to launch in"
@@ -5523,9 +5520,9 @@ def get_local_driver(
5523
5520
  driver = webdriver.Chrome(
5524
5521
  service=service, options=chrome_options
5525
5522
  )
5526
- return extend_driver(driver)
5523
+ return extend_driver(driver, proxy_auth, use_uc)
5527
5524
  except Exception as original_exception:
5528
- if is_using_uc(undetectable, browser_name):
5525
+ if use_uc:
5529
5526
  raise
5530
5527
  # Try again if Chrome didn't launch
5531
5528
  with suppress(Exception):
@@ -5533,7 +5530,7 @@ def get_local_driver(
5533
5530
  driver = webdriver.Chrome(
5534
5531
  service=service, options=chrome_options
5535
5532
  )
5536
- return extend_driver(driver)
5533
+ return extend_driver(driver, proxy_auth, use_uc)
5537
5534
  if user_data_dir:
5538
5535
  print("\nUnable to set user_data_dir while starting Chrome!\n")
5539
5536
  raise
@@ -5560,7 +5557,7 @@ def get_local_driver(
5560
5557
  )
5561
5558
  try:
5562
5559
  driver = webdriver.Chrome(service=service)
5563
- return extend_driver(driver)
5560
+ return extend_driver(driver, proxy_auth, use_uc)
5564
5561
  except Exception:
5565
5562
  raise original_exception
5566
5563
  else:
@@ -94,21 +94,23 @@ def create_proxy_ext(
94
94
  manifest_json = (
95
95
  """{\n"""
96
96
  """"version": "1.0.0",\n"""
97
- """"manifest_version": 2,\n"""
97
+ """"manifest_version": 3,\n"""
98
98
  """"name": "Chrome Proxy",\n"""
99
99
  """"permissions": [\n"""
100
100
  """ "proxy",\n"""
101
101
  """ "tabs",\n"""
102
102
  """ "unlimitedStorage",\n"""
103
103
  """ "storage",\n"""
104
- """ "<all_urls>",\n"""
105
104
  """ "webRequest",\n"""
106
- """ "webRequestBlocking"\n"""
105
+ """ "webRequestAuthProvider"\n"""
106
+ """],\n"""
107
+ """"host_permissions": [\n"""
108
+ """ "<all_urls>"\n"""
107
109
  """],\n"""
108
110
  """"background": {\n"""
109
- """ "scripts": ["background.js"]\n"""
111
+ """ "service_worker": "background.js"\n"""
110
112
  """},\n"""
111
- """"minimum_chrome_version":"22.0.0"\n"""
113
+ """"minimum_chrome_version":"88.0.0"\n"""
112
114
  """}"""
113
115
  )
114
116
  abs_path = os.path.abspath(".")
@@ -62,6 +62,7 @@ class CDPMethods():
62
62
  lambda destination: self.__mouse_drag(element, destination)
63
63
  )
64
64
  element.mouse_move = lambda: self.__mouse_move(element)
65
+ element.press_keys = lambda text: self.__press_keys(element, text)
65
66
  element.query_selector = (
66
67
  lambda selector: self.__query_selector(element, selector)
67
68
  )
@@ -211,7 +212,8 @@ class CDPMethods():
211
212
  element = self.__add_sync_methods(element.parent)
212
213
  return self.__add_sync_methods(element)
213
214
  elif (
214
- element.parent.parent
215
+ element.parent
216
+ and element.parent.parent
215
217
  and tag_name in element.parent.parent.tag_name.lower()
216
218
  and text.strip() in element.parent.parent.text
217
219
  ):
@@ -272,7 +274,8 @@ class CDPMethods():
272
274
  if element not in updated_elements:
273
275
  updated_elements.append(element)
274
276
  elif (
275
- element.parent.parent
277
+ element.parent
278
+ and element.parent.parent
276
279
  and tag_name in element.parent.parent.tag_name.lower()
277
280
  and text.strip() in element.parent.parent.text
278
281
  ):
@@ -445,6 +448,23 @@ class CDPMethods():
445
448
  self.loop.run_until_complete(element.mouse_move_async())
446
449
  )
447
450
 
451
+ def __press_keys(self, element, text):
452
+ element.scroll_into_view()
453
+ submit = False
454
+ if text.endswith("\n") or text.endswith("\r"):
455
+ submit = True
456
+ text = text[:-1]
457
+ for key in text:
458
+ element.send_keys(key)
459
+ time.sleep(0.044)
460
+ if submit:
461
+ element.send_keys("\r\n")
462
+ time.sleep(0.044)
463
+ self.__slow_mode_pause_if_set()
464
+ return (
465
+ self.loop.run_until_complete(self.page.wait())
466
+ )
467
+
448
468
  def __query_selector(self, element, selector):
449
469
  selector = self.__convert_to_css_if_xpath(selector)
450
470
  element2 = self.loop.run_until_complete(
@@ -1681,21 +1701,79 @@ class CDPMethods():
1681
1701
  return True
1682
1702
  return False
1683
1703
 
1684
- def wait_for_element_visible(self, selector, timeout=None):
1704
+ def is_text_visible(self, text, selector="body"):
1705
+ selector = self.__convert_to_css_if_xpath(selector)
1706
+ text = text.strip()
1707
+ element = None
1708
+ try:
1709
+ element = self.find_element(selector, timeout=0.1)
1710
+ except Exception:
1711
+ return False
1712
+ with suppress(Exception):
1713
+ if text in element.text_all:
1714
+ return True
1715
+ return False
1716
+
1717
+ def is_exact_text_visible(self, text, selector="body"):
1718
+ selector = self.__convert_to_css_if_xpath(selector)
1719
+ text = text.strip()
1720
+ element = None
1721
+ try:
1722
+ element = self.find_element(selector, timeout=0.1)
1723
+ except Exception:
1724
+ return False
1725
+ with suppress(Exception):
1726
+ if text == element.text_all.strip():
1727
+ return True
1728
+ return False
1729
+
1730
+ def wait_for_text(self, text, selector="body", timeout=None):
1685
1731
  if not timeout:
1686
1732
  timeout = settings.SMALL_TIMEOUT
1733
+ start_ms = time.time() * 1000.0
1734
+ stop_ms = start_ms + (timeout * 1000.0)
1735
+ text = text.strip()
1736
+ element = None
1687
1737
  try:
1688
- self.select(selector, timeout=timeout)
1738
+ element = self.find_element(selector, timeout=timeout)
1689
1739
  except Exception:
1690
- raise Exception("Element {%s} was not found!" % selector)
1691
- for i in range(30):
1692
- if self.is_element_visible(selector):
1693
- return self.select(selector)
1740
+ raise Exception("Element {%s} not found!" % selector)
1741
+ for i in range(int(timeout * 10)):
1742
+ with suppress(Exception):
1743
+ element = self.find_element(selector, timeout=0.1)
1744
+ if text in element.text_all:
1745
+ return True
1746
+ now_ms = time.time() * 1000.0
1747
+ if now_ms >= stop_ms:
1748
+ break
1694
1749
  time.sleep(0.1)
1695
- raise Exception("Element {%s} was not visible!" % selector)
1750
+ raise Exception(
1751
+ "Text {%s} not found in {%s}! Actual text: {%s}"
1752
+ % (text, selector, element.text_all)
1753
+ )
1696
1754
 
1697
- def assert_element(self, selector, timeout=None):
1698
- """Same as assert_element_visible()"""
1755
+ def wait_for_text_not_visible(self, text, selector="body", timeout=None):
1756
+ if not timeout:
1757
+ timeout = settings.SMALL_TIMEOUT
1758
+ text = text.strip()
1759
+ start_ms = time.time() * 1000.0
1760
+ stop_ms = start_ms + (timeout * 1000.0)
1761
+ for i in range(int(timeout * 10)):
1762
+ if not self.is_text_visible(text, selector):
1763
+ return True
1764
+ now_ms = time.time() * 1000.0
1765
+ if now_ms >= stop_ms:
1766
+ break
1767
+ time.sleep(0.1)
1768
+ plural = "s"
1769
+ if timeout == 1:
1770
+ plural = ""
1771
+ raise Exception(
1772
+ "Text {%s} in {%s} was still visible after %s second%s!"
1773
+ % (text, selector, timeout, plural)
1774
+ )
1775
+
1776
+ def wait_for_element_visible(self, selector, timeout=None):
1699
1777
  if not timeout:
1700
1778
  timeout = settings.SMALL_TIMEOUT
1701
1779
  try:
@@ -1704,10 +1782,15 @@ class CDPMethods():
1704
1782
  raise Exception("Element {%s} was not found!" % selector)
1705
1783
  for i in range(30):
1706
1784
  if self.is_element_visible(selector):
1707
- return True
1785
+ return self.select(selector)
1708
1786
  time.sleep(0.1)
1709
1787
  raise Exception("Element {%s} was not visible!" % selector)
1710
1788
 
1789
+ def assert_element(self, selector, timeout=None):
1790
+ """Same as assert_element_visible()"""
1791
+ self.assert_element_visible(selector, timeout=timeout)
1792
+ return True
1793
+
1711
1794
  def assert_element_visible(self, selector, timeout=None):
1712
1795
  """Same as assert_element()"""
1713
1796
  if not timeout:
@@ -1852,29 +1935,9 @@ class CDPMethods():
1852
1935
  raise Exception(error % (expected, actual))
1853
1936
 
1854
1937
  def assert_text(self, text, selector="body", timeout=None):
1855
- if not timeout:
1856
- timeout = settings.SMALL_TIMEOUT
1857
- start_ms = time.time() * 1000.0
1858
- stop_ms = start_ms + (timeout * 1000.0)
1859
- text = text.strip()
1860
- element = None
1861
- try:
1862
- element = self.find_element(selector, timeout=timeout)
1863
- except Exception:
1864
- raise Exception("Element {%s} not found!" % selector)
1865
- for i in range(int(timeout * 10)):
1866
- with suppress(Exception):
1867
- element = self.find_element(selector, timeout=0.1)
1868
- if text in element.text_all:
1869
- return True
1870
- now_ms = time.time() * 1000.0
1871
- if now_ms >= stop_ms:
1872
- break
1873
- time.sleep(0.1)
1874
- raise Exception(
1875
- "Text {%s} not found in {%s}! Actual text: {%s}"
1876
- % (text, selector, element.text_all)
1877
- )
1938
+ """Same as wait_for_text()"""
1939
+ self.wait_for_text(text, selector=selector, timeout=timeout)
1940
+ return True
1878
1941
 
1879
1942
  def assert_exact_text(self, text, selector="body", timeout=None):
1880
1943
  if not timeout:
@@ -1904,6 +1967,13 @@ class CDPMethods():
1904
1967
  % (text, element.text_all, selector)
1905
1968
  )
1906
1969
 
1970
+ def assert_text_not_visible(self, text, selector="body", timeout=None):
1971
+ """Raises an exception if the text is still visible after timeout."""
1972
+ self.wait_for_text_not_visible(
1973
+ text, selector=selector, timeout=timeout
1974
+ )
1975
+ return True
1976
+
1907
1977
  def assert_true(self, expression):
1908
1978
  if not expression:
1909
1979
  raise AssertionError("%s is not true" % expression)
@@ -1454,6 +1454,8 @@ class BaseCase(unittest.TestCase):
1454
1454
 
1455
1455
  def is_text_visible(self, text, selector="body", by="css selector"):
1456
1456
  """Returns whether the text substring is visible in the element."""
1457
+ if self.__is_cdp_swap_needed():
1458
+ return self.cdp.is_text_visible(text, selector)
1457
1459
  self.wait_for_ready_state_complete()
1458
1460
  time.sleep(0.01)
1459
1461
  selector, by = self.__recalculate_selector(selector, by)
@@ -1464,6 +1466,8 @@ class BaseCase(unittest.TestCase):
1464
1466
  def is_exact_text_visible(self, text, selector="body", by="css selector"):
1465
1467
  """Returns whether the text is exactly equal to the element text.
1466
1468
  (Leading and trailing whitespace is ignored in the verification.)"""
1469
+ if self.__is_cdp_swap_needed():
1470
+ return self.cdp.is_exact_text_visible(text, selector)
1467
1471
  self.wait_for_ready_state_complete()
1468
1472
  time.sleep(0.01)
1469
1473
  selector, by = self.__recalculate_selector(selector, by)
@@ -9281,7 +9285,8 @@ class BaseCase(unittest.TestCase):
9281
9285
  "bottom_left", "bottom_center", "bottom_right"]
9282
9286
  max_messages: The limit of concurrent messages to display."""
9283
9287
  self.__check_scope()
9284
- self._check_browser()
9288
+ if not self.__is_cdp_swap_needed():
9289
+ self._check_browser()
9285
9290
  if not theme:
9286
9291
  theme = "default" # "flat"
9287
9292
  if not location:
@@ -9308,7 +9313,8 @@ class BaseCase(unittest.TestCase):
9308
9313
  You can also post messages by using =>
9309
9314
  self.execute_script('Messenger().post("My Message")') """
9310
9315
  self.__check_scope()
9311
- self._check_browser()
9316
+ if not self.__is_cdp_swap_needed():
9317
+ self._check_browser()
9312
9318
  if style not in ["info", "success", "error"]:
9313
9319
  style = "info"
9314
9320
  if not duration:
@@ -10326,6 +10332,10 @@ class BaseCase(unittest.TestCase):
10326
10332
  if self.timeout_multiplier and timeout == settings.LARGE_TIMEOUT:
10327
10333
  timeout = self.__get_new_timeout(timeout)
10328
10334
  selector, by = self.__recalculate_selector(selector, by)
10335
+ if self.__is_cdp_swap_needed():
10336
+ return self.cdp.wait_for_text(
10337
+ text, selector=selector, timeout=timeout
10338
+ )
10329
10339
  return page_actions.wait_for_text_not_visible(
10330
10340
  self.driver, text, selector, by, timeout
10331
10341
  )
@@ -13909,7 +13919,8 @@ class BaseCase(unittest.TestCase):
13909
13919
  js_utils.highlight_element_with_js(self.driver, element, loops, o_bs)
13910
13920
 
13911
13921
  def __highlight_with_jquery(self, selector, loops, o_bs):
13912
- self.wait_for_ready_state_complete()
13922
+ if not self.__is_cdp_swap_needed():
13923
+ self.wait_for_ready_state_complete()
13913
13924
  js_utils.highlight_with_jquery(self.driver, selector, loops, o_bs)
13914
13925
 
13915
13926
  def __highlight_with_js_2(self, message, selector, o_bs):
@@ -585,52 +585,60 @@ def highlight_with_jquery(driver, selector, loops=4, o_bs=""):
585
585
  '0px 0px 6px 6px rgba(128, 128, 128, 0.5)');"""
586
586
  % selector
587
587
  )
588
- safe_execute_script(driver, script)
588
+ with suppress(Exception):
589
+ safe_execute_script(driver, script)
589
590
  for n in range(loops):
590
591
  script = (
591
592
  """jQuery('%s').css('box-shadow',
592
593
  '0px 0px 6px 6px rgba(255, 0, 0, 1)');"""
593
594
  % selector
594
595
  )
595
- execute_script(driver, script)
596
+ with suppress(Exception):
597
+ execute_script(driver, script)
596
598
  time.sleep(0.0181)
597
599
  script = (
598
600
  """jQuery('%s').css('box-shadow',
599
601
  '0px 0px 6px 6px rgba(128, 0, 128, 1)');"""
600
602
  % selector
601
603
  )
602
- execute_script(driver, script)
604
+ with suppress(Exception):
605
+ execute_script(driver, script)
603
606
  time.sleep(0.0181)
604
607
  script = (
605
608
  """jQuery('%s').css('box-shadow',
606
609
  '0px 0px 6px 6px rgba(0, 0, 255, 1)');"""
607
610
  % selector
608
611
  )
609
- execute_script(driver, script)
612
+ with suppress(Exception):
613
+ execute_script(driver, script)
610
614
  time.sleep(0.0181)
611
615
  script = (
612
616
  """jQuery('%s').css('box-shadow',
613
617
  '0px 0px 6px 6px rgba(0, 255, 0, 1)');"""
614
618
  % selector
615
619
  )
616
- execute_script(driver, script)
620
+ with suppress(Exception):
621
+ execute_script(driver, script)
617
622
  time.sleep(0.0181)
618
623
  script = (
619
624
  """jQuery('%s').css('box-shadow',
620
625
  '0px 0px 6px 6px rgba(128, 128, 0, 1)');"""
621
626
  % selector
622
627
  )
623
- execute_script(driver, script)
628
+ with suppress(Exception):
629
+ execute_script(driver, script)
624
630
  time.sleep(0.0181)
625
631
  script = (
626
632
  """jQuery('%s').css('box-shadow',
627
633
  '0px 0px 6px 6px rgba(128, 0, 128, 1)');"""
628
634
  % selector
629
635
  )
630
- execute_script(driver, script)
636
+ with suppress(Exception):
637
+ execute_script(driver, script)
631
638
  time.sleep(0.0181)
632
639
  script = """jQuery('%s').css('box-shadow', '%s');""" % (selector, o_bs)
633
- execute_script(driver, script)
640
+ with suppress(Exception):
641
+ execute_script(driver, script)
634
642
 
635
643
 
636
644
  def add_css_link(driver, css_link):
@@ -924,9 +932,20 @@ def post_message(driver, message, msg_dur=None, style="info"):
924
932
  """hideAfter: %s, hideOnNavigate: true});"""
925
933
  % (message, style, msg_dur)
926
934
  )
935
+ retry = False
927
936
  try:
928
937
  execute_script(driver, messenger_script)
938
+ except TypeError as e:
939
+ if (
940
+ shared_utils.is_cdp_swap_needed(driver)
941
+ and "cannot unpack non-iterable" in str(e)
942
+ ):
943
+ pass
944
+ else:
945
+ retry = True
929
946
  except Exception:
947
+ retry = True
948
+ if retry:
930
949
  activate_messenger(driver)
931
950
  set_messenger_theme(driver)
932
951
  try:
@@ -1273,7 +1292,10 @@ def slow_scroll_to_element(driver, element, *args, **kwargs):
1273
1292
  scroll_position = execute_script(driver, "return window.scrollY;")
1274
1293
  element_location_y = None
1275
1294
  try:
1276
- element_location_y = element.location["y"]
1295
+ if shared_utils.is_cdp_swap_needed(driver):
1296
+ element.get_position().y
1297
+ else:
1298
+ element_location_y = element.location["y"]
1277
1299
  except Exception:
1278
1300
  element.location_once_scrolled_into_view
1279
1301
  return
@@ -265,6 +265,8 @@ class Browser:
265
265
  :param new_window: Open new window
266
266
  :return: Page
267
267
  """
268
+ if url and ":" not in url:
269
+ url = "https://" + url
268
270
  if new_tab or new_window:
269
271
  # Create new target using the browser session.
270
272
  target_id = await self.connection.send(
@@ -4,6 +4,7 @@ import asyncio
4
4
  import fasteners
5
5
  import logging
6
6
  import os
7
+ import sys
7
8
  import time
8
9
  import types
9
10
  import typing
@@ -11,6 +12,7 @@ from contextlib import suppress
11
12
  from seleniumbase import config as sb_config
12
13
  from seleniumbase.config import settings
13
14
  from seleniumbase.core import detect_b_ver
15
+ from seleniumbase.core import proxy_helper
14
16
  from seleniumbase.fixtures import constants
15
17
  from seleniumbase.fixtures import shared_utils
16
18
  from typing import Optional, List, Union, Callable
@@ -23,6 +25,7 @@ import mycdp as cdp
23
25
 
24
26
  logger = logging.getLogger(__name__)
25
27
  IS_LINUX = shared_utils.is_linux()
28
+ PROXY_DIR_LOCK = proxy_helper.PROXY_DIR_LOCK
26
29
  T = typing.TypeVar("T")
27
30
 
28
31
 
@@ -139,6 +142,85 @@ def __activate_virtual_display_as_needed(
139
142
  __activate_standard_virtual_display()
140
143
 
141
144
 
145
+ def __set_proxy_filenames():
146
+ DOWNLOADS_DIR = constants.Files.DOWNLOADS_FOLDER
147
+ for num in range(1000):
148
+ PROXY_DIR_PATH = os.path.join(DOWNLOADS_DIR, "proxy_ext_dir_%s" % num)
149
+ if os.path.exists(PROXY_DIR_PATH):
150
+ continue
151
+ proxy_helper.PROXY_DIR_PATH = PROXY_DIR_PATH
152
+ return
153
+ # Exceeded upper bound. Use Defaults:
154
+ PROXY_DIR_PATH = os.path.join(DOWNLOADS_DIR, "proxy_ext_dir")
155
+ proxy_helper.PROXY_DIR_PATH = PROXY_DIR_PATH
156
+
157
+
158
+ def __add_chrome_ext_dir(extension_dir, dir_path):
159
+ # Add dir_path to the existing extension_dir
160
+ option_exists = False
161
+ if extension_dir:
162
+ option_exists = True
163
+ extension_dir = "%s,%s" % (
164
+ extension_dir, os.path.realpath(dir_path)
165
+ )
166
+ if not option_exists:
167
+ extension_dir = os.path.realpath(dir_path)
168
+ return extension_dir
169
+
170
+
171
+ def __add_chrome_proxy_extension(
172
+ extension_dir,
173
+ proxy_string,
174
+ proxy_user,
175
+ proxy_pass,
176
+ proxy_bypass_list=None,
177
+ multi_proxy=False,
178
+ ):
179
+ """Implementation of https://stackoverflow.com/a/35293284/7058266
180
+ for https://stackoverflow.com/q/12848327/7058266
181
+ (Run Selenium on a proxy server that requires authentication.)"""
182
+ args = " ".join(sys.argv)
183
+ bypass_list = proxy_bypass_list
184
+ if (
185
+ not ("-n" in sys.argv or " -n=" in args or args == "-c")
186
+ and not multi_proxy
187
+ ):
188
+ # Single-threaded
189
+ proxy_dir_lock = fasteners.InterProcessLock(PROXY_DIR_LOCK)
190
+ with proxy_dir_lock:
191
+ proxy_helper.create_proxy_ext(
192
+ proxy_string,
193
+ proxy_user,
194
+ proxy_pass,
195
+ bypass_list,
196
+ zip_it=False,
197
+ )
198
+ proxy_dir_path = proxy_helper.PROXY_DIR_PATH
199
+ extension_dir = __add_chrome_ext_dir(
200
+ extension_dir, proxy_dir_path
201
+ )
202
+ else:
203
+ # Multi-threaded
204
+ proxy_dir_lock = fasteners.InterProcessLock(PROXY_DIR_LOCK)
205
+ with proxy_dir_lock:
206
+ with suppress(Exception):
207
+ shared_utils.make_writable(PROXY_DIR_LOCK)
208
+ if multi_proxy:
209
+ __set_proxy_filenames()
210
+ if not os.path.exists(proxy_helper.PROXY_DIR_PATH):
211
+ proxy_helper.create_proxy_ext(
212
+ proxy_string,
213
+ proxy_user,
214
+ proxy_pass,
215
+ bypass_list,
216
+ zip_it=False,
217
+ )
218
+ extension_dir = __add_chrome_ext_dir(
219
+ extension_dir, proxy_helper.PROXY_DIR_PATH
220
+ )
221
+ return extension_dir
222
+
223
+
142
224
  async def start(
143
225
  config: Optional[Config] = None,
144
226
  *,
@@ -156,6 +238,8 @@ async def start(
156
238
  xvfb: Optional[int] = None, # Use a special virtual display on Linux
157
239
  headed: Optional[bool] = None, # Override default Xvfb mode on Linux
158
240
  expert: Optional[bool] = None, # Open up closed Shadow-root elements
241
+ proxy: Optional[str] = None, # "host:port" or "user:pass@host:port"
242
+ extension_dir: Optional[str] = None, # Chrome extension directory
159
243
  **kwargs: Optional[dict],
160
244
  ) -> Browser:
161
245
  """
@@ -200,6 +284,18 @@ async def start(
200
284
  if IS_LINUX and not headless and not headed and not xvfb:
201
285
  xvfb = True # The default setting on Linux
202
286
  __activate_virtual_display_as_needed(headless, headed, xvfb, xvfb_metrics)
287
+ if proxy and "@" in str(proxy):
288
+ user_with_pass = proxy.split("@")[0]
289
+ if ":" in user_with_pass:
290
+ proxy_user = user_with_pass.split(":")[0]
291
+ proxy_pass = user_with_pass.split(":")[1]
292
+ proxy_string = proxy.split("@")[1]
293
+ extension_dir = __add_chrome_proxy_extension(
294
+ extension_dir,
295
+ proxy_string,
296
+ proxy_user,
297
+ proxy_pass,
298
+ )
203
299
  if not config:
204
300
  config = Config(
205
301
  user_data_dir,
@@ -213,13 +309,19 @@ async def start(
213
309
  host=host,
214
310
  port=port,
215
311
  expert=expert,
312
+ proxy=proxy,
313
+ extension_dir=extension_dir,
216
314
  **kwargs,
217
315
  )
316
+ driver = None
218
317
  try:
219
- return await Browser.create(config)
318
+ driver = await Browser.create(config)
220
319
  except Exception:
221
320
  time.sleep(0.15)
222
- return await Browser.create(config)
321
+ driver = await Browser.create(config)
322
+ if proxy and "@" in str(proxy):
323
+ time.sleep(0.11)
324
+ return driver
223
325
 
224
326
 
225
327
  async def start_async(*args, **kwargs) -> Browser:
@@ -40,6 +40,8 @@ class Config:
40
40
  host: str = AUTO,
41
41
  port: int = AUTO,
42
42
  expert: bool = AUTO,
43
+ proxy: Optional[str] = None,
44
+ extension_dir: Optional[str] = None,
43
45
  **kwargs: dict,
44
46
  ):
45
47
  """
@@ -91,6 +93,8 @@ class Config:
91
93
  self.host = host
92
94
  self.port = port
93
95
  self.expert = expert
96
+ self.proxy = proxy
97
+ self.extension_dir = extension_dir
94
98
  self._extensions = []
95
99
  # When using posix-ish operating system and running as root,
96
100
  # you must use no_sandbox=True
@@ -195,6 +199,12 @@ class Config:
195
199
  "--disable-web-security",
196
200
  "--disable-site-isolation-trials",
197
201
  ]
202
+ if self.proxy:
203
+ args.append("--proxy-server=%s" % self.proxy.split("@")[-1])
204
+ args.append("--ignore-certificate-errors")
205
+ args.append("--ignore-ssl-errors=yes")
206
+ if self.extension_dir:
207
+ args.append("--load-extension=%s" % self.extension_dir)
198
208
  if self._browser_args:
199
209
  args.extend([arg for arg in self._browser_args if arg not in args])
200
210
  if self.headless:
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.2
2
2
  Name: seleniumbase
3
- Version: 4.34.14
3
+ Version: 4.34.16
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
@@ -68,7 +68,7 @@ Requires-Dist: attrs>=25.1.0
68
68
  Requires-Dist: certifi>=2025.1.31
69
69
  Requires-Dist: exceptiongroup>=1.2.2
70
70
  Requires-Dist: websockets~=13.1; python_version < "3.9"
71
- Requires-Dist: websockets>=14.2; python_version >= "3.9"
71
+ Requires-Dist: websockets>=15.0; python_version >= "3.9"
72
72
  Requires-Dist: filelock~=3.16.1; python_version < "3.9"
73
73
  Requires-Dist: filelock>=3.17.0; python_version >= "3.9"
74
74
  Requires-Dist: fasteners>=0.19
@@ -99,8 +99,8 @@ Requires-Dist: sniffio==1.3.1
99
99
  Requires-Dist: h11==0.14.0
100
100
  Requires-Dist: outcome==1.3.0.post0
101
101
  Requires-Dist: trio==0.27.0; python_version < "3.9"
102
- Requires-Dist: trio==0.28.0; python_version >= "3.9"
103
- Requires-Dist: trio-websocket==0.11.1
102
+ Requires-Dist: trio==0.29.0; python_version >= "3.9"
103
+ Requires-Dist: trio-websocket==0.12.1
104
104
  Requires-Dist: wsproto==1.2.0
105
105
  Requires-Dist: websocket-client==1.8.0
106
106
  Requires-Dist: selenium==4.27.1; python_version < "3.9"
@@ -137,7 +137,7 @@ Requires-Dist: pytest-cov>=5.0.0; python_version < "3.9" and extra == "coverage"
137
137
  Requires-Dist: pytest-cov>=6.0.0; python_version >= "3.9" and extra == "coverage"
138
138
  Provides-Extra: flake8
139
139
  Requires-Dist: flake8==5.0.4; python_version < "3.9" and extra == "flake8"
140
- Requires-Dist: flake8==7.1.1; python_version >= "3.9" and extra == "flake8"
140
+ Requires-Dist: flake8==7.1.2; python_version >= "3.9" and extra == "flake8"
141
141
  Requires-Dist: mccabe==0.7.0; extra == "flake8"
142
142
  Requires-Dist: pyflakes==2.5.0; python_version < "3.9" and extra == "flake8"
143
143
  Requires-Dist: pyflakes==3.2.0; python_version >= "3.9" and extra == "flake8"
@@ -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=UxABS3j4kMHoxFb6GTOAJ94dTcWKwEv0oOyYZkzPXQQ,47
6
+ seleniumbase/__version__.py,sha256=yo5-NDclqDbu-vlvPFL7dji8w3SHeRhS6yV5yaJdYxU,47
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=qQF85LoohJBfrPK5ZcPi50v-pWtOrC9qcN1B3Ki_3tY,59401
@@ -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=xkEcsdyz0E3acWgz_UYvrx6qMWUZT_IimhiJ885FVUw,235625
39
+ seleniumbase/core/browser_launcher.py,sha256=zRDRfNGsCHKn5w1R_78l5SnbieQ3bm74NMmJs4O-sQ8,235755
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
@@ -46,11 +46,11 @@ seleniumbase/core/encoded_images.py,sha256=rDKJ4cNJSuKiRcFViYU7bjyTS9_moI57gUPRX
46
46
  seleniumbase/core/jqc_helper.py,sha256=2DDQr9Q2jSSZqFzX588jLlUM9oJvyrRWq2aORSIPUdI,10322
47
47
  seleniumbase/core/log_helper.py,sha256=SW8wx2f2HfU3ERbANjxEC-jDbjy_IzaNYRKPlayfRRI,23442
48
48
  seleniumbase/core/mysql.py,sha256=8Fzj3p5dhtDWfMpFqFYxpSwa9s1UltiHsWJ56_aPOqk,3993
49
- seleniumbase/core/proxy_helper.py,sha256=kZnfkflB3XhuL2h-3inmx3UOLS8VAZ385BGCc4H8TvU,8267
49
+ seleniumbase/core/proxy_helper.py,sha256=4VkpMwavz0fx8wcOqJ_jyBT0HIXwcxmAcpd1gjJizdc,8332
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=r9sv8WjwLhS_AFLn4QGLvbK4osfaC6ncRJRj0asrBvI,76754
53
+ seleniumbase/core/sb_cdp.py,sha256=5OLmRH5JSJYwqDomY2O9cx_0lNlAwNYjJbUTGmFUZPQ,79126
54
54
  seleniumbase/core/sb_driver.py,sha256=yvTDRblBzG6bDX7XcLiAA6QcBelSJj_HHL_04lcfeeE,13760
55
55
  seleniumbase/core/session_helper.py,sha256=s9zD3PVZEWVzG2h81cCUskbNWLfdjC_LwwQjKptHCak,558
56
56
  seleniumbase/core/settings_parser.py,sha256=gqVohHVlE_5L5Cqe2L24uYrRzvoK-saX8E_Df7_-_3I,7609
@@ -65,11 +65,11 @@ seleniumbase/extensions/disable_csp.zip,sha256=5RvomXnm2PdivUVcxTV6jfvD8WhTEsQYH
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=0bW99a1g8YH5YCXLnsJvZ5uSXvLOmY6QutDEpxDjX9U,721561
68
+ seleniumbase/fixtures/base_case.py,sha256=AJ33rXML0feRLo6WdCcQhxmBwEtQdn_gXuOy_iFPInY,722065
69
69
  seleniumbase/fixtures/constants.py,sha256=WMrItuNyKq3XVJ64NluLIRc4gJCxDw8K8qXED0b9S2w,13752
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=asZJ0LDFv2BPQOzUVKK_9ie8ToGcmFousDnGdb3Vabg,51534
72
+ seleniumbase/fixtures/js_utils.py,sha256=QxHC0Wz_rDQ5dB6B1CK_UFs9zzryuElr-fj7MUtf_lA,52204
73
73
  seleniumbase/fixtures/page_actions.py,sha256=LPcFSkUvBkxLrOt4laQHHN-NLmqInT41E2vlPiOlLFY,66753
74
74
  seleniumbase/fixtures/page_utils.py,sha256=H1iV8f9vDyEy87DBntyiBXC_tg8HskcebUOAJVn0hxE,12160
75
75
  seleniumbase/fixtures/shared_utils.py,sha256=G6CsE-Adt-GfuZF-71jXWKSIQW7YZPx8FIM24pVd_yI,8368
@@ -115,9 +115,9 @@ seleniumbase/undetected/reactor.py,sha256=NropaXcO54pzmDq6quR27qPJxab6636H7LRAaq
115
115
  seleniumbase/undetected/webelement.py,sha256=OOpUYbEiOG52KsYYyuDW9tYLdA2SMnukvwQHUdPVn9E,1389
116
116
  seleniumbase/undetected/cdp_driver/__init__.py,sha256=c0TjMwPfVFyoqYOJ7PQ-Jln_L_dpN3ebHyaD-juQoM0,64
117
117
  seleniumbase/undetected/cdp_driver/_contradict.py,sha256=lP4b0h5quAy573ETn_TBbYV889cL1AuPLVInpJ0ZkiU,3183
118
- seleniumbase/undetected/cdp_driver/browser.py,sha256=vwccwrAZDssRmVnf-NVXYvs5Dvv8DtGzeiDHSY3RTfM,30189
119
- seleniumbase/undetected/cdp_driver/cdp_util.py,sha256=B5myq2zi-Gdq_vfZGPOG-LTSwbhK4n2h6SY2Z9dmIzQ,17784
120
- seleniumbase/undetected/cdp_driver/config.py,sha256=oHFJ3UH0OmLmEGgG5S6SZwbyBs9ZYMsbUJ02QCA7iZc,12044
118
+ seleniumbase/undetected/cdp_driver/browser.py,sha256=ruPunmJKwE67Veh1MjSkZAF5W38FMwc32lHgy1YULho,30261
119
+ seleniumbase/undetected/cdp_driver/cdp_util.py,sha256=zlYc_oTqtCSjV_T7lzPbFyJlj_78NHMxKkrpleXcfpQ,21374
120
+ seleniumbase/undetected/cdp_driver/config.py,sha256=t8KV1Vqa5SQRBq3-gjkHHmj9h85AplAM01asO3AWufs,12507
121
121
  seleniumbase/undetected/cdp_driver/connection.py,sha256=sOTUGjbUqKA2hPvDcRCdqw1VQjVGJs7mbgVvzS7ldtE,23360
122
122
  seleniumbase/undetected/cdp_driver/element.py,sha256=FIC6v7OmumLCT-_vIc3H4oju_oBbaLpWJUJIKm2c_q4,40467
123
123
  seleniumbase/undetected/cdp_driver/tab.py,sha256=rcASsWY_mC7L0wXpFSWM5mtojzA47qG9BWEMXe7ZGF8,50906
@@ -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.34.14.dist-info/LICENSE,sha256=BRblZsX7HyPUjQmYTiyWr_e9tzWvmR3R4SFclM2R3W0,1085
139
- seleniumbase-4.34.14.dist-info/METADATA,sha256=u2jHtXFZv3QOcz_K67gNWrepuM0THRJz_JlaY-B0BoE,86522
140
- seleniumbase-4.34.14.dist-info/WHEEL,sha256=In9FTNxeP60KnTkGw7wk6mJPYd_dQSjEZmXdBdMCI-8,91
141
- seleniumbase-4.34.14.dist-info/entry_points.txt,sha256=CNrh2EKNaHYEhO6pP1RJyVLB99LkDDYX7TnUK8xfjqk,623
142
- seleniumbase-4.34.14.dist-info/top_level.txt,sha256=4N97aBOQ8ETCnDnokBsWb07lJfTaq3C1ZzYRxvLMxqU,19
143
- seleniumbase-4.34.14.dist-info/RECORD,,
138
+ seleniumbase-4.34.16.dist-info/LICENSE,sha256=BRblZsX7HyPUjQmYTiyWr_e9tzWvmR3R4SFclM2R3W0,1085
139
+ seleniumbase-4.34.16.dist-info/METADATA,sha256=qF4wtXCAPxi0YzvlBRfk_z-drHDdQH4wTTkhCcWHO3g,86522
140
+ seleniumbase-4.34.16.dist-info/WHEEL,sha256=In9FTNxeP60KnTkGw7wk6mJPYd_dQSjEZmXdBdMCI-8,91
141
+ seleniumbase-4.34.16.dist-info/entry_points.txt,sha256=CNrh2EKNaHYEhO6pP1RJyVLB99LkDDYX7TnUK8xfjqk,623
142
+ seleniumbase-4.34.16.dist-info/top_level.txt,sha256=4N97aBOQ8ETCnDnokBsWb07lJfTaq3C1ZzYRxvLMxqU,19
143
+ seleniumbase-4.34.16.dist-info/RECORD,,