seleniumbase 4.32.2__py3-none-any.whl → 4.32.4__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.32.2"
2
+ __version__ = "4.32.4"
@@ -542,6 +542,7 @@ def uc_open_with_cdp_mode(driver, url=None):
542
542
  driver.cdp_base = loop.run_until_complete(
543
543
  cdp_util.start(host=cdp_host, port=cdp_port)
544
544
  )
545
+
545
546
  page = loop.run_until_complete(driver.cdp_base.get(url))
546
547
  loop.run_until_complete(page.activate())
547
548
  if not safe_url:
@@ -549,7 +550,7 @@ def uc_open_with_cdp_mode(driver, url=None):
549
550
  cdp = types.SimpleNamespace()
550
551
  CDPM = sb_cdp.CDPMethods(loop, page, driver)
551
552
  cdp.get = CDPM.get
552
- cdp.open = CDPM.get
553
+ cdp.open = CDPM.open
553
554
  cdp.reload = CDPM.reload
554
555
  cdp.refresh = CDPM.refresh
555
556
  cdp.add_handler = CDPM.add_handler
@@ -590,6 +591,7 @@ def uc_open_with_cdp_mode(driver, url=None):
590
591
  cdp.medimize = CDPM.medimize
591
592
  cdp.set_window_rect = CDPM.set_window_rect
592
593
  cdp.reset_window_size = CDPM.reset_window_size
594
+ cdp.set_locale = CDPM.set_locale
593
595
  cdp.set_attributes = CDPM.set_attributes
594
596
  cdp.internalize_links = CDPM.internalize_links
595
597
  cdp.get_window = CDPM.get_window
@@ -2179,8 +2181,13 @@ def _set_chrome_options(
2179
2181
  or IS_LINUX # switches to Xvfb (non-headless)
2180
2182
  )
2181
2183
  ):
2184
+ chrome_options.add_argument("--no-pings")
2182
2185
  chrome_options.add_argument("--disable-popup-blocking")
2183
- chrome_options.add_argument("--homepage=chrome://new-tab-page/")
2186
+ chrome_options.add_argument("--homepage=chrome://version/")
2187
+ chrome_options.add_argument("--animation-duration-scale=0")
2188
+ chrome_options.add_argument("--wm-window-animations-disabled")
2189
+ chrome_options.add_argument("--enable-privacy-sandbox-ads-apis")
2190
+ chrome_options.add_argument("--disable-background-timer-throttling")
2184
2191
  # Skip remaining options that trigger anti-bot services
2185
2192
  return chrome_options
2186
2193
  chrome_options.add_argument("--test-type")
@@ -4523,6 +4530,7 @@ def get_local_driver(
4523
4530
  and uc_chrome_version
4524
4531
  and uc_chrome_version >= 117
4525
4532
  and (headless or headless2)
4533
+ and chromium_arg != "decoy"
4526
4534
  ):
4527
4535
  from seleniumbase.console_scripts import (
4528
4536
  sb_install
@@ -76,13 +76,21 @@ class CDPMethods():
76
76
 
77
77
  def get(self, url):
78
78
  url = shared_utils.fix_url_as_needed(url)
79
- self.page = self.loop.run_until_complete(self.driver.cdp_base.get(url))
79
+ driver = self.driver
80
+ if hasattr(driver, "cdp_base"):
81
+ driver = driver.cdp_base
82
+ self.page = self.loop.run_until_complete(driver.get(url))
80
83
  url_protocol = url.split(":")[0]
81
84
  safe_url = True
82
85
  if url_protocol not in ["about", "data", "chrome"]:
83
86
  safe_url = False
84
87
  if not safe_url:
85
88
  time.sleep(constants.UC.CDP_MODE_OPEN_WAIT)
89
+ self.__slow_mode_pause_if_set()
90
+ self.loop.run_until_complete(self.page.wait())
91
+
92
+ def open(self, url):
93
+ self.get(url)
86
94
 
87
95
  def reload(self, ignore_cache=True, script_to_evaluate_on_load=None):
88
96
  self.loop.run_until_complete(
@@ -111,18 +119,28 @@ class CDPMethods():
111
119
  with the closest text-length to the text being searched for."""
112
120
  self.__add_light_pause()
113
121
  selector = self.__convert_to_css_if_xpath(selector)
122
+ early_failure = False
114
123
  if (":contains(" in selector):
115
124
  tag_name = selector.split(":contains(")[0].split(" ")[-1]
116
125
  text = selector.split(":contains(")[1].split(")")[0][1:-1]
117
126
  with suppress(Exception):
118
127
  self.loop.run_until_complete(
119
- self.page.select(tag_name, timeout=3)
128
+ self.page.select(tag_name, timeout=timeout)
120
129
  )
121
- self.loop.run_until_complete(self.page.find(text, timeout=3))
122
- element = self.find_elements_by_text(text, tag_name=tag_name)[0]
123
- return self.__add_sync_methods(element)
130
+ self.loop.run_until_complete(
131
+ self.page.find(text, timeout=timeout)
132
+ )
133
+ elements = []
134
+ with suppress(Exception):
135
+ elements = self.find_elements_by_text(text, tag_name=tag_name)
136
+ if elements:
137
+ return self.__add_sync_methods(elements[0])
138
+ else:
139
+ early_failure = True
124
140
  failure = False
125
141
  try:
142
+ if early_failure:
143
+ raise Exception("Failed!")
126
144
  element = self.loop.run_until_complete(
127
145
  self.page.find(
128
146
  selector, best_match=best_match, timeout=timeout
@@ -230,9 +248,11 @@ class CDPMethods():
230
248
  )
231
249
 
232
250
  def __click(self, element):
233
- return (
251
+ result = (
234
252
  self.loop.run_until_complete(element.click_async())
235
253
  )
254
+ self.loop.run_until_complete(self.page.wait())
255
+ return result
236
256
 
237
257
  def __flash(self, element):
238
258
  return (
@@ -250,9 +270,11 @@ class CDPMethods():
250
270
  )
251
271
 
252
272
  def __mouse_click(self, element):
253
- return (
273
+ result = (
254
274
  self.loop.run_until_complete(element.mouse_click_async())
255
275
  )
276
+ self.loop.run_until_complete(self.page.wait())
277
+ return result
256
278
 
257
279
  def __mouse_drag(self, element, destination):
258
280
  return (
@@ -353,33 +375,51 @@ class CDPMethods():
353
375
 
354
376
  def tile_windows(self, windows=None, max_columns=0):
355
377
  """Tile windows and return the grid of tiled windows."""
378
+ driver = self.driver
379
+ if hasattr(driver, "cdp_base"):
380
+ driver = driver.cdp_base
356
381
  return self.loop.run_until_complete(
357
- self.driver.cdp_base.tile_windows(windows, max_columns)
382
+ driver.tile_windows(windows, max_columns)
358
383
  )
359
384
 
360
385
  def get_all_cookies(self, *args, **kwargs):
386
+ driver = self.driver
387
+ if hasattr(driver, "cdp_base"):
388
+ driver = driver.cdp_base
361
389
  return self.loop.run_until_complete(
362
- self.driver.cdp_base.cookies.get_all(*args, **kwargs)
390
+ driver.cookies.get_all(*args, **kwargs)
363
391
  )
364
392
 
365
393
  def set_all_cookies(self, *args, **kwargs):
394
+ driver = self.driver
395
+ if hasattr(driver, "cdp_base"):
396
+ driver = driver.cdp_base
366
397
  return self.loop.run_until_complete(
367
- self.driver.cdp_base.cookies.set_all(*args, **kwargs)
398
+ driver.cookies.set_all(*args, **kwargs)
368
399
  )
369
400
 
370
401
  def save_cookies(self, *args, **kwargs):
402
+ driver = self.driver
403
+ if hasattr(driver, "cdp_base"):
404
+ driver = driver.cdp_base
371
405
  return self.loop.run_until_complete(
372
- self.driver.cdp_base.cookies.save(*args, **kwargs)
406
+ driver.cookies.save(*args, **kwargs)
373
407
  )
374
408
 
375
409
  def load_cookies(self, *args, **kwargs):
410
+ driver = self.driver
411
+ if hasattr(driver, "cdp_base"):
412
+ driver = driver.cdp_base
376
413
  return self.loop.run_until_complete(
377
- self.driver.cdp_base.cookies.load(*args, **kwargs)
414
+ driver.cookies.load(*args, **kwargs)
378
415
  )
379
416
 
380
417
  def clear_cookies(self, *args, **kwargs):
418
+ driver = self.driver
419
+ if hasattr(driver, "cdp_base"):
420
+ driver = driver.cdp_base
381
421
  return self.loop.run_until_complete(
382
- self.driver.cdp_base.cookies.clear(*args, **kwargs)
422
+ driver.cookies.clear(*args, **kwargs)
383
423
  )
384
424
 
385
425
  def sleep(self, seconds):
@@ -408,17 +448,20 @@ class CDPMethods():
408
448
  self.__add_light_pause()
409
449
  element.click()
410
450
  self.__slow_mode_pause_if_set()
451
+ self.loop.run_until_complete(self.page.wait())
411
452
 
412
453
  def click_active_element(self):
413
454
  self.loop.run_until_complete(
414
455
  self.page.evaluate("document.activeElement.click()")
415
456
  )
416
457
  self.__slow_mode_pause_if_set()
458
+ self.loop.run_until_complete(self.page.wait())
417
459
 
418
460
  def click_if_visible(self, selector):
419
461
  if self.is_element_visible(selector):
420
462
  self.find_element(selector).click()
421
463
  self.__slow_mode_pause_if_set()
464
+ self.loop.run_until_complete(self.page.wait())
422
465
 
423
466
  def mouse_click(self, selector, timeout=settings.SMALL_TIMEOUT):
424
467
  """(Attempt simulating a mouse click)"""
@@ -427,6 +470,7 @@ class CDPMethods():
427
470
  self.__add_light_pause()
428
471
  element.mouse_click()
429
472
  self.__slow_mode_pause_if_set()
473
+ self.loop.run_until_complete(self.page.wait())
430
474
 
431
475
  def nested_click(self, parent_selector, selector):
432
476
  """
@@ -436,6 +480,7 @@ class CDPMethods():
436
480
  element = self.find_element(parent_selector)
437
481
  element.query_selector(selector).mouse_click()
438
482
  self.__slow_mode_pause_if_set()
483
+ self.loop.run_until_complete(self.page.wait())
439
484
 
440
485
  def get_nested_element(self, parent_selector, selector):
441
486
  """(Can be used to find an element inside an iframe)"""
@@ -483,6 +528,7 @@ class CDPMethods():
483
528
  text = text[:-1] + "\r\n"
484
529
  element.send_keys(text)
485
530
  self.__slow_mode_pause_if_set()
531
+ self.loop.run_until_complete(self.page.wait())
486
532
 
487
533
  def press_keys(self, selector, text, timeout=settings.SMALL_TIMEOUT):
488
534
  """Similar to send_keys(), but presses keys at human speed."""
@@ -499,6 +545,7 @@ class CDPMethods():
499
545
  element.send_keys("\r\n")
500
546
  time.sleep(0.0375)
501
547
  self.__slow_mode_pause_if_set()
548
+ self.loop.run_until_complete(self.page.wait())
502
549
 
503
550
  def type(self, selector, text, timeout=settings.SMALL_TIMEOUT):
504
551
  """Similar to send_keys(), but clears the text field first."""
@@ -510,6 +557,7 @@ class CDPMethods():
510
557
  text = text[:-1] + "\r\n"
511
558
  element.send_keys(text)
512
559
  self.__slow_mode_pause_if_set()
560
+ self.loop.run_until_complete(self.page.wait())
513
561
 
514
562
  def evaluate(self, expression):
515
563
  """Run a JavaScript expression and return the result."""
@@ -760,6 +808,10 @@ class CDPMethods():
760
808
  )
761
809
  )
762
810
 
811
+ def set_locale(self, locale):
812
+ """(Settings will take effect on the next page load)"""
813
+ self.loop.run_until_complete(self.page.set_locale(locale))
814
+
763
815
  def set_attributes(self, selector, attribute, value):
764
816
  """This method uses JavaScript to set/update a common attribute.
765
817
  All matching selectors from querySelectorAll() are used.
@@ -4099,6 +4099,7 @@ class BaseCase(unittest.TestCase):
4099
4099
  or not any(os.scandir(user_data_dir))
4100
4100
  )
4101
4101
  and self.browser == "chrome"
4102
+ and shared_utils.is_chrome_130_or_newer(binary_location)
4102
4103
  ):
4103
4104
  import tempfile
4104
4105
  if not user_data_dir:
@@ -4108,7 +4109,7 @@ class BaseCase(unittest.TestCase):
4108
4109
  try:
4109
4110
  decoy_driver = browser_launcher.get_driver(
4110
4111
  browser_name=browser_name,
4111
- headless=headless,
4112
+ headless=False,
4112
4113
  locale_code=locale_code,
4113
4114
  use_grid=use_grid,
4114
4115
  protocol=protocol,
@@ -4134,7 +4135,7 @@ class BaseCase(unittest.TestCase):
4134
4135
  log_cdp_events=log_cdp_events,
4135
4136
  no_sandbox=no_sandbox,
4136
4137
  disable_gpu=disable_gpu,
4137
- headless1=headless1,
4138
+ headless1=False,
4138
4139
  headless2=True,
4139
4140
  incognito=incognito,
4140
4141
  guest_mode=guest_mode,
@@ -4147,12 +4148,12 @@ class BaseCase(unittest.TestCase):
4147
4148
  host_resolver_rules=host_resolver_rules,
4148
4149
  block_images=block_images,
4149
4150
  do_not_track=do_not_track,
4150
- chromium_arg=chromium_arg,
4151
+ chromium_arg="decoy",
4151
4152
  firefox_arg=firefox_arg,
4152
4153
  firefox_pref=firefox_pref,
4153
4154
  user_data_dir=user_data_dir,
4154
- extension_zip=extension_zip,
4155
- extension_dir=extension_dir,
4155
+ extension_zip=None,
4156
+ extension_dir=None,
4156
4157
  disable_features=disable_features,
4157
4158
  binary_location=binary_location,
4158
4159
  driver_version=driver_version,
@@ -4166,12 +4167,13 @@ class BaseCase(unittest.TestCase):
4166
4167
  device_pixel_ratio=d_p_r,
4167
4168
  browser=browser_name,
4168
4169
  )
4169
- time.sleep(0.555)
4170
+ time.sleep(0.16)
4170
4171
  except Exception:
4171
4172
  pass
4172
4173
  finally:
4173
4174
  with suppress(Exception):
4174
4175
  decoy_driver.quit()
4176
+ time.sleep(0.08)
4175
4177
  # Launch a web browser
4176
4178
  new_driver = browser_launcher.get_driver(
4177
4179
  browser_name=browser_name,
@@ -4513,8 +4515,15 @@ class BaseCase(unittest.TestCase):
4513
4515
  cookies_file.writelines(json_cookies)
4514
4516
  cookies_file.close()
4515
4517
 
4516
- def load_cookies(self, name="cookies.txt"):
4517
- """Loads the page cookies from the "saved_cookies" folder."""
4518
+ def load_cookies(self, name="cookies.txt", expiry=False):
4519
+ """
4520
+ Loads the page cookies from the "saved_cookies" folder.
4521
+ Usage for setting expiry:
4522
+ If expiry == 0 or False: Delete "expiry".
4523
+ If expiry == -1 (or < 0): Do not modify "expiry".
4524
+ If expiry > 0: Set "expiry" to expiry minutes in the future.
4525
+ If expiry == True: Set "expiry" to 24 hours in the future.
4526
+ """
4518
4527
  cookies = self.get_saved_cookies(name)
4519
4528
  self.wait_for_ready_state_complete()
4520
4529
  origin = self.get_origin()
@@ -4523,8 +4532,14 @@ class BaseCase(unittest.TestCase):
4523
4532
  if "domain" in cookie:
4524
4533
  if cookie["domain"] not in origin:
4525
4534
  cookie["domain"] = trim_origin
4526
- if "expiry" in cookie:
4535
+ if "expiry" in cookie and (not expiry or expiry == 0):
4527
4536
  del cookie["expiry"]
4537
+ elif isinstance(expiry, (int, float)) and expiry < 0:
4538
+ pass
4539
+ elif isinstance(expiry, (int, float)) and expiry > 0:
4540
+ cookie["expiry"] = int(time.time()) + int(expiry * 60.0)
4541
+ elif expiry:
4542
+ cookie["expiry"] = int(time.time()) + 86400
4528
4543
  self.driver.add_cookie(cookie)
4529
4544
 
4530
4545
  def delete_all_cookies(self):
@@ -4585,18 +4600,57 @@ class BaseCase(unittest.TestCase):
4585
4600
  def get_cookies(self):
4586
4601
  return self.driver.get_cookies()
4587
4602
 
4588
- def add_cookie(self, cookie_dict):
4603
+ def add_cookie(self, cookie_dict, expiry=False):
4589
4604
  """Usage examples:
4590
4605
  self.add_cookie({'name': 'foo', 'value': 'bar'})
4591
4606
  self.add_cookie({'name': 'foo', 'value': 'bar', 'path': '/'})
4592
4607
  self.add_cookie({'name': 'foo', 'value': 'bar', 'secure': True})
4593
4608
  self.add_cookie({'name': 'foo', 'value': 'bar', 'sameSite': 'Strict'})
4609
+ Usage for setting expiry:
4610
+ If expiry == 0 or False: Delete "expiry".
4611
+ If expiry == -1 (or < 0): Do not modify "expiry".
4612
+ If expiry > 0: Set "expiry" to expiry minutes in the future.
4613
+ If expiry == True: Set "expiry" to 24 hours in the future.
4594
4614
  """
4615
+ cookie = cookie_dict
4616
+ if "domain" in cookie:
4617
+ origin = self.get_origin()
4618
+ trim_origin = origin.split("://")[-1]
4619
+ if cookie["domain"] not in origin:
4620
+ cookie["domain"] = trim_origin
4621
+ if "expiry" in cookie and (not expiry or expiry == 0):
4622
+ del cookie["expiry"]
4623
+ elif isinstance(expiry, (int, float)) and expiry < 0:
4624
+ pass
4625
+ elif isinstance(expiry, (int, float)) and expiry > 0:
4626
+ cookie["expiry"] = int(time.time()) + int(expiry * 60.0)
4627
+ elif expiry:
4628
+ cookie["expiry"] = int(time.time()) + 86400
4595
4629
  self.driver.add_cookie(cookie_dict)
4596
4630
 
4597
- def add_cookies(self, cookies):
4598
- for cookie_dict in cookies:
4599
- self.driver.add_cookie(cookie_dict)
4631
+ def add_cookies(self, cookies, expiry=False):
4632
+ """
4633
+ Usage for setting expiry:
4634
+ If expiry == 0 or False: Delete "expiry".
4635
+ If expiry == -1 (or < 0): Do not modify "expiry".
4636
+ If expiry > 0: Set "expiry" to expiry minutes in the future.
4637
+ If expiry == True: Set "expiry" to 24 hours in the future.
4638
+ """
4639
+ origin = self.get_origin()
4640
+ trim_origin = origin.split("://")[-1]
4641
+ for cookie in cookies:
4642
+ if "domain" in cookie:
4643
+ if cookie["domain"] not in origin:
4644
+ cookie["domain"] = trim_origin
4645
+ if "expiry" in cookie and (not expiry or expiry == 0):
4646
+ del cookie["expiry"]
4647
+ elif isinstance(expiry, (int, float)) and expiry < 0:
4648
+ pass
4649
+ elif isinstance(expiry, (int, float)) and expiry > 0:
4650
+ cookie["expiry"] = int(time.time()) + int(expiry * 60.0)
4651
+ elif expiry:
4652
+ cookie["expiry"] = int(time.time()) + 86400
4653
+ self.driver.add_cookie(cookie)
4600
4654
 
4601
4655
  def __set_esc_skip(self):
4602
4656
  if hasattr(self, "esc_end") and self.esc_end:
@@ -4,6 +4,7 @@ import os
4
4
  import platform
5
5
  import sys
6
6
  import time
7
+ from contextlib import suppress
7
8
  from seleniumbase import config as sb_config
8
9
  from seleniumbase.fixtures import constants
9
10
 
@@ -99,6 +100,23 @@ def is_cdp_swap_needed(driver):
99
100
  )
100
101
 
101
102
 
103
+ def is_chrome_130_or_newer(self, binary_location=None):
104
+ from seleniumbase.core import detect_b_ver
105
+
106
+ """Due to changes in Chrome-130, UC Mode freezes at start-up
107
+ unless the user-data-dir already exists and is populated."""
108
+ with suppress(Exception):
109
+ if not binary_location:
110
+ ver = detect_b_ver.get_browser_version_from_os("google-chrome")
111
+ else:
112
+ ver = detect_b_ver.get_browser_version_from_binary(
113
+ binary_location
114
+ )
115
+ if ver and len(ver) > 3 and int(ver.split(".")[0]) >= 130:
116
+ return True
117
+ return False
118
+
119
+
102
120
  def format_exc(exception, message):
103
121
  """Formats an exception message to make the output cleaner."""
104
122
  from selenium.common.exceptions import ElementNotVisibleException
@@ -233,6 +233,7 @@ def Driver(
233
233
  wire (bool): Shortcut / Duplicate of "use_wire".
234
234
  pls (str): Shortcut / Duplicate of "page_load_strategy".
235
235
  """
236
+ from contextlib import suppress
236
237
  from seleniumbase import config as sb_config
237
238
  from seleniumbase.config import settings
238
239
  from seleniumbase.fixtures import constants
@@ -800,6 +801,7 @@ def Driver(
800
801
  or not any(os.scandir(user_data_dir))
801
802
  )
802
803
  and browser == "chrome"
804
+ and shared_utils.is_chrome_130_or_newer(binary_location)
803
805
  ):
804
806
  import tempfile
805
807
  import time
@@ -849,12 +851,12 @@ def Driver(
849
851
  host_resolver_rules=host_resolver_rules,
850
852
  block_images=block_images,
851
853
  do_not_track=do_not_track,
852
- chromium_arg=chromium_arg,
854
+ chromium_arg="decoy",
853
855
  firefox_arg=firefox_arg,
854
856
  firefox_pref=firefox_pref,
855
857
  user_data_dir=user_data_dir,
856
- extension_zip=extension_zip,
857
- extension_dir=extension_dir,
858
+ extension_zip=None,
859
+ extension_dir=None,
858
860
  disable_features=disable_features,
859
861
  binary_location=binary_location,
860
862
  driver_version=driver_version,
@@ -868,14 +870,13 @@ def Driver(
868
870
  device_pixel_ratio=d_p_r,
869
871
  browser=browser_name,
870
872
  )
871
- time.sleep(0.555)
873
+ time.sleep(0.16)
872
874
  except Exception:
873
875
  pass
874
876
  finally:
875
- try:
877
+ with suppress(Exception):
876
878
  decoy_driver.quit()
877
- except Exception:
878
- pass
879
+ time.sleep(0.08)
879
880
 
880
881
  driver = browser_launcher.get_driver(
881
882
  browser_name=browser_name,
@@ -1,4 +1,3 @@
1
- #!/usr/bin/env python3
2
1
  import logging
3
2
  import os
4
3
  import re
@@ -433,10 +432,15 @@ class Chrome(selenium.webdriver.chrome.webdriver.WebDriver):
433
432
  time.sleep(timeout)
434
433
  with suppress(Exception):
435
434
  self.service.start()
436
- time.sleep(0.012)
437
435
  with suppress(Exception):
438
436
  self.start_session()
439
- time.sleep(0.012)
437
+ with suppress(Exception):
438
+ if self.current_url.startswith("chrome-extension://"):
439
+ self.close()
440
+ self.service.stop()
441
+ self.service.start()
442
+ self.start_session()
443
+ self._is_connected = True
440
444
 
441
445
  def disconnect(self):
442
446
  """Stops the chromedriver service that runs in the background.
@@ -445,7 +449,6 @@ class Chrome(selenium.webdriver.chrome.webdriver.WebDriver):
445
449
  with suppress(Exception):
446
450
  self.service.stop()
447
451
  self._is_connected = False
448
- time.sleep(0.012)
449
452
 
450
453
  def connect(self):
451
454
  """Starts the chromedriver service that runs in the background
@@ -453,11 +456,15 @@ class Chrome(selenium.webdriver.chrome.webdriver.WebDriver):
453
456
  if hasattr(self, "service"):
454
457
  with suppress(Exception):
455
458
  self.service.start()
456
- time.sleep(0.012)
457
459
  with suppress(Exception):
458
460
  self.start_session()
461
+ with suppress(Exception):
462
+ if self.current_url.startswith("chrome-extension://"):
463
+ self.close()
464
+ self.service.stop()
465
+ self.service.start()
466
+ self.start_session()
459
467
  self._is_connected = True
460
- time.sleep(0.012)
461
468
 
462
469
  def start_session(self, capabilities=None):
463
470
  if not capabilities:
@@ -1,4 +1,3 @@
1
- #!/usr/bin/env python3
2
1
  import fasteners
3
2
  import json
4
3
  import logging
@@ -5,6 +5,7 @@ import logging
5
5
  import time
6
6
  import types
7
7
  import typing
8
+ from seleniumbase.fixtures import shared_utils
8
9
  from typing import Optional, List, Union, Callable
9
10
  from .element import Element
10
11
  from .browser import Browser
@@ -92,30 +93,40 @@ async def start(
92
93
 
93
94
  async def start_async(*args, **kwargs) -> Browser:
94
95
  headless = False
95
- if "headless" in kwargs:
96
- headless = kwargs["headless"]
97
- decoy_args = kwargs
98
- decoy_args["headless"] = True
99
- driver = await start(**decoy_args)
100
- kwargs["headless"] = headless
101
- kwargs["user_data_dir"] = driver.config.user_data_dir
102
- driver.stop() # Due to Chrome-130, must stop & start
103
- time.sleep(0.15)
96
+ binary_location = None
97
+ if "browser_executable_path" in kwargs:
98
+ binary_location = kwargs["browser_executable_path"]
99
+ if shared_utils.is_chrome_130_or_newer(binary_location):
100
+ if "headless" in kwargs:
101
+ headless = kwargs["headless"]
102
+ decoy_args = kwargs
103
+ decoy_args["headless"] = True
104
+ driver = await start(**decoy_args)
105
+ kwargs["headless"] = headless
106
+ kwargs["user_data_dir"] = driver.config.user_data_dir
107
+ time.sleep(0.2)
108
+ driver.stop() # Due to Chrome-130, must stop & start
109
+ time.sleep(0.1)
104
110
  return await start(*args, **kwargs)
105
111
 
106
112
 
107
113
  def start_sync(*args, **kwargs) -> Browser:
108
114
  loop = asyncio.get_event_loop()
109
115
  headless = False
110
- if "headless" in kwargs:
111
- headless = kwargs["headless"]
112
- decoy_args = kwargs
113
- decoy_args["headless"] = True
114
- driver = loop.run_until_complete(start(**decoy_args))
115
- kwargs["headless"] = headless
116
- kwargs["user_data_dir"] = driver.config.user_data_dir
117
- driver.stop() # Due to Chrome-130, must stop & start
118
- time.sleep(0.15)
116
+ binary_location = None
117
+ if "browser_executable_path" in kwargs:
118
+ binary_location = kwargs["browser_executable_path"]
119
+ if shared_utils.is_chrome_130_or_newer(binary_location):
120
+ if "headless" in kwargs:
121
+ headless = kwargs["headless"]
122
+ decoy_args = kwargs
123
+ decoy_args["headless"] = True
124
+ driver = loop.run_until_complete(start(**decoy_args))
125
+ kwargs["headless"] = headless
126
+ kwargs["user_data_dir"] = driver.config.user_data_dir
127
+ time.sleep(0.2)
128
+ driver.stop() # Due to Chrome-130, must stop & start
129
+ time.sleep(0.1)
119
130
  return loop.run_until_complete(start(*args, **kwargs))
120
131
 
121
132
 
@@ -5,6 +5,7 @@ import secrets
5
5
  import sys
6
6
  import tempfile
7
7
  import zipfile
8
+ from seleniumbase.config import settings
8
9
  from typing import Union, List, Optional
9
10
 
10
11
  __all__ = [
@@ -101,13 +102,23 @@ class Config:
101
102
  # Other keyword args will be accessible by attribute
102
103
  self.__dict__.update(kwargs)
103
104
  super().__init__()
105
+ start_width = settings.CHROME_START_WIDTH
106
+ start_height = settings.CHROME_START_HEIGHT
107
+ start_x = settings.WINDOW_START_X
108
+ start_y = settings.WINDOW_START_Y
104
109
  self._default_browser_args = [
110
+ "--window-size=%s,%s" % (start_width, start_height),
111
+ "--window-position=%s,%s" % (start_x, start_y),
105
112
  "--remote-allow-origins=*",
106
113
  "--no-first-run",
107
114
  "--no-service-autorun",
115
+ "--disable-auto-reload",
108
116
  "--no-default-browser-check",
109
117
  "--homepage=about:blank",
110
118
  "--no-pings",
119
+ "--wm-window-animations-disabled",
120
+ "--animation-duration-scale=0",
121
+ "--enable-privacy-sandbox-ads-apis",
111
122
  "--safebrowsing-disable-download-protection",
112
123
  '--simulate-outdated-no-au="Tue, 31 Dec 2099 23:59:59 GMT"',
113
124
  "--password-store=basic",
@@ -118,10 +129,12 @@ class Config:
118
129
  "--disable-prompt-on-repost",
119
130
  "--disable-password-generation",
120
131
  "--disable-ipc-flooding-protection",
132
+ "--disable-background-timer-throttling",
121
133
  "--disable-search-engine-choice-screen",
122
134
  "--disable-backgrounding-occluded-windows",
123
135
  "--disable-client-side-phishing-detection",
124
136
  "--disable-top-sites",
137
+ "--disable-translate",
125
138
  "--disable-renderer-backgrounding",
126
139
  "--disable-background-networking",
127
140
  "--disable-dev-shm-usage",
@@ -9,6 +9,7 @@ import sys
9
9
  import types
10
10
  from asyncio import iscoroutine, iscoroutinefunction
11
11
  from typing import (
12
+ Optional,
12
13
  Generator,
13
14
  Union,
14
15
  Awaitable,
@@ -291,7 +292,14 @@ class Connection(metaclass=CantTouchThis):
291
292
  if self.listener and self.listener.running:
292
293
  self.listener.cancel()
293
294
  self.enabled_domains.clear()
294
- await self.websocket.close()
295
+ await asyncio.sleep(0.015)
296
+ try:
297
+ await self.websocket.close()
298
+ except Exception:
299
+ logger.debug(
300
+ "\n❌ Error closing websocket connection to %s",
301
+ self.websocket_url
302
+ )
295
303
  logger.debug(
296
304
  "\n❌ Closed websocket connection to %s", self.websocket_url
297
305
  )
@@ -336,6 +344,10 @@ class Connection(metaclass=CantTouchThis):
336
344
  # No listener created yet.
337
345
  pass
338
346
 
347
+ async def set_locale(self, locale: Optional[str] = None):
348
+ """Sets the Language Locale code via set_user_agent_override."""
349
+ await self.send(cdp.network.set_user_agent_override("", locale))
350
+
339
351
  def __getattr__(self, item):
340
352
  """:meta private:"""
341
353
  try:
@@ -535,6 +547,7 @@ class Listener:
535
547
  self.idle.set()
536
548
  # Pause for a moment.
537
549
  # await asyncio.sleep(self.time_before_considered_idle / 10)
550
+ await asyncio.sleep(0.015)
538
551
  continue
539
552
  except (Exception,) as e:
540
553
  logger.debug(
@@ -323,7 +323,7 @@ class Tab(Connection):
323
323
 
324
324
  async def get(
325
325
  self,
326
- url="chrome://welcome",
326
+ url="about:blank",
327
327
  new_tab: bool = False,
328
328
  new_window: bool = False,
329
329
  ):
@@ -1,4 +1,3 @@
1
- #!/usr/bin/env python3
2
1
  import os
3
2
  import sys
4
3
  import atexit
@@ -1,4 +1,3 @@
1
- #!/usr/bin/env python3
2
1
  import json
3
2
  import os
4
3
  from contextlib import suppress
@@ -59,7 +58,9 @@ class ChromeOptions(ChromiumOptions):
59
58
  json.load(f), undot_prefs
60
59
  )
61
60
  with suppress(Exception):
62
- with open(prefs_file, encoding="utf-8", mode="w") as f:
61
+ with open(
62
+ prefs_file, encoding="utf-8", mode="w", errors="ignore"
63
+ ) as f:
63
64
  json.dump(undot_prefs, f)
64
65
  # Remove experimental_options to avoid errors
65
66
  del self._experimental_options["prefs"]
@@ -1,4 +1,3 @@
1
- #!/usr/bin/env python3
2
1
  import io
3
2
  import logging
4
3
  import os
@@ -1,4 +1,3 @@
1
- #!/usr/bin/env python3
2
1
  import asyncio
3
2
  import json
4
3
  import logging
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: seleniumbase
3
- Version: 4.32.2
3
+ Version: 4.32.4
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
@@ -79,8 +79,8 @@ Requires-Dist: parse-type>=0.6.4
79
79
  Requires-Dist: colorama>=0.4.6
80
80
  Requires-Dist: pyyaml>=6.0.2
81
81
  Requires-Dist: pygments>=2.18.0
82
- Requires-Dist: tabcompleter>=1.3.3
83
- Requires-Dist: pdbp>=1.5.4
82
+ Requires-Dist: tabcompleter>=1.4.0
83
+ Requires-Dist: pdbp>=1.6.0
84
84
  Requires-Dist: idna==3.10
85
85
  Requires-Dist: chardet==5.2.0
86
86
  Requires-Dist: charset-normalizer==3.4.0
@@ -236,6 +236,8 @@ Requires-Dist: zstandard==0.23.0; extra == "selenium-wire"
236
236
 
237
237
  👤 Note that <span translate="no">SeleniumBase</span> <a translate="no" href="https://github.com/seleniumbase/SeleniumBase/blob/master/help_docs/uc_mode.md"><b>UC Mode</b> (Stealth Mode) has its own ReadMe</a>.
238
238
 
239
+ 🐙 Also note that Seleniumbase <a href="https://github.com/seleniumbase/SeleniumBase/blob/master/examples/cdp_mode/ReadMe.md"><b>CDP Mode</b> has its own separate ReadMe</a>.
240
+
239
241
  ℹ️ Scripts can be called via <code translate="no"><b>python</b></code>, although some <a href="https://github.com/seleniumbase/SeleniumBase/blob/master/help_docs/syntax_formats.md">Syntax Formats</a> expect <a href="https://docs.pytest.org/en/latest/how-to/usage.html" translate="no"><b>pytest</b></a> (a Python unit-testing framework included with SeleniumBase that can discover, collect, and run tests automatically).
240
242
 
241
243
  <p align="left">📗 Here's <a href="https://github.com/seleniumbase/SeleniumBase/blob/master/examples/my_first_test.py">my_first_test.py</a>, which tests login, shopping, and checkout:</p>
@@ -489,48 +491,49 @@ pip install -e .
489
491
  🔵 **Type ``seleniumbase`` or ``sbase`` to verify that SeleniumBase was installed successfully:**
490
492
 
491
493
  ```bash
492
- ______ __ _ ____
493
- / ____/__ / /__ ____ (_)_ ______ ___ / _ \____ ________
494
- \__ \/ _ \/ / _ \/ __ \/ / / / / __ `__ \ / /_) / __ \/ ___/ _ \
495
- ___/ / __/ / __/ / / / / /_/ / / / / / // /_) / (_/ /__ / __/
496
- /____/\___/_/\___/_/ /_/_/\__,_/_/ /_/ /_//_____/\__,_/____/\___/
497
- ------------------------------------------------------------------
498
-
499
- * USAGE: "seleniumbase [COMMAND] [PARAMETERS]"
500
- * OR: "sbase [COMMAND] [PARAMETERS]"
501
-
502
- COMMANDS:
503
- get / install [DRIVER] [OPTIONS]
504
- methods (List common Python methods)
505
- options (List common pytest options)
506
- behave-options (List common behave options)
507
- gui / commander [OPTIONAL PATH or TEST FILE]
508
- behave-gui (SBase Commander for Behave)
509
- caseplans [OPTIONAL PATH or TEST FILE]
510
- mkdir [DIRECTORY] [OPTIONS]
511
- mkfile [FILE.py] [OPTIONS]
512
- mkrec / codegen [FILE.py] [OPTIONS]
513
- recorder (Open Recorder Desktop App.)
514
- record (If args: mkrec. Else: App.)
515
- mkpres [FILE.py] [LANG]
516
- mkchart [FILE.py] [LANG]
517
- print [FILE] [OPTIONS]
518
- translate [SB_FILE.py] [LANG] [ACTION]
519
- convert [WEBDRIVER_UNITTEST_FILE.py]
520
- extract-objects [SB_FILE.py]
521
- inject-objects [SB_FILE.py] [OPTIONS]
522
- objectify [SB_FILE.py] [OPTIONS]
523
- revert-objects [SB_FILE.py] [OPTIONS]
524
- encrypt / obfuscate
525
- decrypt / unobfuscate
526
- download server (Get Selenium Grid JAR file)
527
- grid-hub [start|stop] [OPTIONS]
528
- grid-node [start|stop] --hub=[HOST/IP]
529
- * (EXAMPLE: "sbase get chromedriver latest") *
530
-
531
- Type "sbase help [COMMAND]" for specific command info.
532
- For info on all commands, type: "seleniumbase --help".
533
- Use "pytest" for running tests.
494
+ ___ _ _ ___
495
+ / __| ___| |___ _ _ (_)_ _ _ __ | _ ) __ _ ______
496
+ \__ \/ -_) / -_) ' \| | \| | ' \ | _ \/ _` (_-< -_)
497
+ |___/\___|_\___|_||_|_|\_,_|_|_|_\|___/\__,_/__|___|
498
+ ----------------------------------------------------
499
+
500
+ ╭──────────────────────────────────────────────────╮
501
+ * USAGE: "seleniumbase [COMMAND] [PARAMETERS]"
502
+ * OR: "sbase [COMMAND] [PARAMETERS]"
503
+ │ │
504
+ COMMANDS: PARAMETERS / DESCRIPTIONS: │
505
+ get / install [DRIVER_NAME] [OPTIONS]
506
+ methods (List common Python methods)
507
+ options (List common pytest options)
508
+ behave-options (List common behave options)
509
+ gui / commander [OPTIONAL PATH or TEST FILE]
510
+ behave-gui (SBase Commander for Behave)
511
+ caseplans [OPTIONAL PATH or TEST FILE]
512
+ mkdir [DIRECTORY] [OPTIONS]
513
+ mkfile [FILE.py] [OPTIONS]
514
+ mkrec / codegen [FILE.py] [OPTIONS]
515
+ recorder (Open Recorder Desktop App.)
516
+ record (If args: mkrec. Else: App.)
517
+ mkpres [FILE.py] [LANG]
518
+ mkchart [FILE.py] [LANG]
519
+ print [FILE] [OPTIONS]
520
+ translate [SB_FILE.py] [LANG] [ACTION]
521
+ convert [WEBDRIVER_UNITTEST_FILE.py]
522
+ extract-objects [SB_FILE.py]
523
+ inject-objects [SB_FILE.py] [OPTIONS]
524
+ objectify [SB_FILE.py] [OPTIONS]
525
+ revert-objects [SB_FILE.py] [OPTIONS]
526
+ encrypt / obfuscate
527
+ decrypt / unobfuscate
528
+ │ proxy (Start a basic proxy server)
529
+ │ download server (Get Selenium Grid JAR file) │
530
+ grid-hub [start|stop] [OPTIONS]
531
+ │ grid-node [start|stop] --hub=[HOST/IP]
532
+ │ │
533
+ * EXAMPLE => "sbase get chromedriver stable" │
534
+ │ * For command info => "sbase help [COMMAND]"
535
+ * For info on all commands => "sbase --help" │
536
+ ╰──────────────────────────────────────────────────╯
534
537
  ```
535
538
 
536
539
  <h3>🔵 Downloading webdrivers:</h3>
@@ -1549,7 +1552,6 @@ pytest --reruns=1 --reruns-delay=1
1549
1552
  <span><a href="https://github.com/seleniumbase/SeleniumBase"><img src="https://seleniumbase.github.io/img/social/share_github.svg" title="SeleniumBase on GitHub" alt="SeleniumBase on GitHub" width="64" /></a></span>
1550
1553
  <span><a href="https://discord.gg/EdhQTn3EyE"><img src="https://seleniumbase.github.io/other/discord_icon.png" title="SeleniumBase on Discord" alt="SeleniumBase on Discord" width="66" /></a></span>
1551
1554
  <span><a href="https://www.facebook.com/SeleniumBase"><img src="https://seleniumbase.io/img/social/share_facebook.svg" title="SeleniumBase on Facebook" alt="SeleniumBase on Facebook" width="62" /></a></span>
1552
- <span><a href="https://gitter.im/seleniumbase/SeleniumBase" target="_blank"><img src="https://seleniumbase.github.io/img/social/share_gitter.svg" title="SeleniumBase on Gitter" alt="SeleniumBase on Gitter" width="48" /></a></span>
1553
1555
  </div></p>
1554
1556
 
1555
1557
  <p><div><b><a href="https://github.com/mdmintz">https://github.com/mdmintz</a></b></div></p>
@@ -3,7 +3,7 @@ sbase/__main__.py,sha256=G0bVB1-DM4PGwQ1KyOupaWCs4ePbChZNNWuX2htim5U,647
3
3
  sbase/steps.py,sha256=bKT_u5bJkKzYWEuAXi9NVVRYYxQRCM1_YJUrNFFRVPY,42865
4
4
  seleniumbase/__init__.py,sha256=OtJh8nGKL4xtZpw8KPqmn7Q6R-86t4cWUDyVF5MbMTo,2398
5
5
  seleniumbase/__main__.py,sha256=dn1p6dgCchmcH1zzTzzQvFwwdQQqnTGH6ULV9m4hv24,654
6
- seleniumbase/__version__.py,sha256=_OJ7bnRLvS-HypA_uNARmZTW3eyhe3wvPfDLthLYGzc,46
6
+ seleniumbase/__version__.py,sha256=vFbcqGUbMcYFZy91jca1HA1X3Ls9oEd6VKZaewExcIA,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=1oAA4wFzVboNhIFDwJLD3jgy9RuoavywKQG7R67bNZE,10908
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=pZ1obi3Wiy41YIa8qqnld_UmlCP0rUfpuGf7CXySq_k,214484
39
+ seleniumbase/core/browser_launcher.py,sha256=xKKxAx2swUnFBpPcny-hk7KlaAnzCmCdw-tokh5ef04,214921
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
@@ -50,7 +50,7 @@ seleniumbase/core/proxy_helper.py,sha256=cXhu8ErK9Vjdm82RMaQj7hEq_yUWizSp6LyiD50
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=QUGB_2IHtH_AbTUVzV0JgdCJindP_ENya-ziZ6uB0Do,32684
53
+ seleniumbase/core/sb_cdp.py,sha256=OolOBITtEmAtdA6nCpal7tnrWHHUHY6DXkzCFD1T4o4,34546
54
54
  seleniumbase/core/sb_driver.py,sha256=-k4vHwMnuiBIkdVInTtJA-IDLrgQfyMhNxSHMIsjepw,11623
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=BK_qE0wtz4IGTSd-6ZlqgJM8FHCk613XJoyAzl29jXY,712137
68
+ seleniumbase/fixtures/base_case.py,sha256=oAnwLUFtg4inRq4I2xJEqAzkwyI2PHeNWm-UPnQXVks,714722
69
69
  seleniumbase/fixtures/constants.py,sha256=XYYMpB-ZDI756LvfhSK9RxdqQ_qO9fJVXgBqBYlQNkk,13609
70
70
  seleniumbase/fixtures/css_to_xpath.py,sha256=9ouDB1xl4MJ2os6JOgTIAyHKOQfuxtxvXC3O5hSnEKA,1954
71
71
  seleniumbase/fixtures/errors.py,sha256=KyxuEVx_e3MPhVrJfNIa_3ltMpbCFxfy_jxK8RFNTns,555
72
72
  seleniumbase/fixtures/js_utils.py,sha256=5o4CTLcCyd717lJ_atOYcC6kPRiZFx-LJIlixRrP_cE,51061
73
73
  seleniumbase/fixtures/page_actions.py,sha256=fOCb2NB2PpEaE8gpAVu-73VjwLzfwP1R9HsRkix_z6s,66634
74
74
  seleniumbase/fixtures/page_utils.py,sha256=5m7iXpikLs80TJoRO6_gEfXE1AKeQgcH1aFbR8o1C9A,12034
75
- seleniumbase/fixtures/shared_utils.py,sha256=-EgvsCjZlJtFj_Qdc6r1JfsWwZYfOdWhdVrYKnbjz4c,6625
75
+ seleniumbase/fixtures/shared_utils.py,sha256=QdoepYzSpt0J_iKQhhJCENY9ry0hB2juXKkEVI3TSTg,7263
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
@@ -86,7 +86,7 @@ seleniumbase/plugins/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hS
86
86
  seleniumbase/plugins/base_plugin.py,sha256=FemdftNhOaTfQIw5bWcJQPPPGQ3P0_sMEI_YYDuzZgU,14972
87
87
  seleniumbase/plugins/basic_test_info.py,sha256=8ov6n417gPbqqvrlT4zrch7l2XcRt-GF2ny6rR9AMWk,2108
88
88
  seleniumbase/plugins/db_reporting_plugin.py,sha256=En09qUCoojrk9-vbcnsoHdSELoGmag2GDIyu3jTiJas,7331
89
- seleniumbase/plugins/driver_manager.py,sha256=gYe-aqNHF8Ap7LV_StjeSccGdv2ayV96HPAHnVnTqQw,37718
89
+ seleniumbase/plugins/driver_manager.py,sha256=05WK2mJMJJ2SDXgEv1WQJad5MqWCV4qIv5FnKhb985Y,37798
90
90
  seleniumbase/plugins/page_source.py,sha256=loTnXxOj4kxEukuTZEiGyvKBhY3KDVDMnNlHHheTBDE,1889
91
91
  seleniumbase/plugins/pytest_plugin.py,sha256=Up96HY6q3hcPo4LQoEcKqt1hm2OmY5GZz_nMXTqDSXQ,97185
92
92
  seleniumbase/plugins/s3_logging_plugin.py,sha256=WDfertQgGOW_SRJpFMaekYD6vBVW9VO62POtXXy2HCM,2319
@@ -106,21 +106,21 @@ seleniumbase/translate/portuguese.py,sha256=x3P4qxp56UiI41GoaL7JbUvFRYsgXU1EKjTg
106
106
  seleniumbase/translate/russian.py,sha256=TyN9n0b4GRWDEYnHRGw1rfNAscdDmP3F3Y3aySM3C7s,27978
107
107
  seleniumbase/translate/spanish.py,sha256=hh3xgW1Pq122SHYVvJAxFaXhFrjniOVncVbJbfWqOUM,25528
108
108
  seleniumbase/translate/translator.py,sha256=wPhZH6e5NhmebYL1kP2eGxUcVy1gfTb6XCH8ATEPpxE,49238
109
- seleniumbase/undetected/__init__.py,sha256=CkVcuzZwwGU6YqEwlsV5yLIr2CWjQo9f_AOHBIfJ6Rs,22135
110
- seleniumbase/undetected/cdp.py,sha256=EralLQm8diG5i6EoHFXHIQEc7Uf7PWtzyPH_upS5RIs,4047
111
- seleniumbase/undetected/dprocess.py,sha256=VLwyLWXSg-6GkeKpAQcTXLRmuBb0oEdku3_qgMifuwY,1705
112
- seleniumbase/undetected/options.py,sha256=jc6Km-gZePOemnolD7UF7dDXpxmRtAE2XDraLUdaIFE,2968
113
- seleniumbase/undetected/patcher.py,sha256=GqNqUwqDDFZg-Y3O6JOyFoOGhHN0r5PV46Mc9b9_BP0,10849
114
- seleniumbase/undetected/reactor.py,sha256=UT1pEnGaTPZT7-0-xKROk9_eWDZueGzSUrCksc22nyA,2883
109
+ seleniumbase/undetected/__init__.py,sha256=8zwqLzRffTOm7nFp6ldldthHVuYB2OnU6ZGV4JOpoio,22491
110
+ seleniumbase/undetected/cdp.py,sha256=RLpwZnhUvmK9tgXcZIBBQedwk2q7Jj_EXZkmzI8WUqk,4023
111
+ seleniumbase/undetected/dprocess.py,sha256=83EV8ZHJWHG1TSUv9JNClBhdgiBXlkCc6mJ--HsoP3k,1681
112
+ seleniumbase/undetected/options.py,sha256=BoNuwhrG7oOvuLvTwkvsWCF36pMkS1tHCG-XpP4_EkI,3001
113
+ seleniumbase/undetected/patcher.py,sha256=n9WfKznr4cQvaE5Gcx7iyK27zMWIc8KdI69_m817CSQ,10825
114
+ seleniumbase/undetected/reactor.py,sha256=NropaXcO54pzmDq6quR27qPJxab6636H7LRAaq-o0ng,2859
115
115
  seleniumbase/undetected/webelement.py,sha256=_s6evgUkdWJpwOnzX4qR9i796PoVbz3txlzHlOBJ4BE,1370
116
116
  seleniumbase/undetected/cdp_driver/__init__.py,sha256=c0TjMwPfVFyoqYOJ7PQ-Jln_L_dpN3ebHyaD-juQoM0,64
117
117
  seleniumbase/undetected/cdp_driver/_contradict.py,sha256=6thDYeoEGiC7Q3tXLgoD_AhxecCFnATzBSjNympyRHA,3184
118
118
  seleniumbase/undetected/cdp_driver/browser.py,sha256=2suM75F3TV-svgBXdRZoxfqErr6_USa8_jOLwHSLlIk,30025
119
- seleniumbase/undetected/cdp_driver/cdp_util.py,sha256=uVltb2ic7tcH-L9CyvRl5-FrA2DnqpCba33UnbXdnHE,10551
120
- seleniumbase/undetected/cdp_driver/config.py,sha256=vRbP9zHgOIf_9_Pbzn9jwzU6RYgU1HbDE0mUzSgwAlE,11457
121
- seleniumbase/undetected/cdp_driver/connection.py,sha256=oaZOQJ29xPw6xrQChDfCrFIPF-JDFtUj6iDjmUQ90hk,22740
119
+ seleniumbase/undetected/cdp_driver/cdp_util.py,sha256=y60sU5rIguohZDl1tgCpuDhu3Wo6TcgvZIbqXdHIv8E,11111
120
+ seleniumbase/undetected/cdp_driver/config.py,sha256=Rjvde7V-XJ0ihZdTmOmHEVWSuDWm3SprQ3njg8SN3Go,12087
121
+ seleniumbase/undetected/cdp_driver/connection.py,sha256=HnwXlD4rawGzCyiGR3Shr4iaK7KTncvSqs3CXxCZM_8,23266
122
122
  seleniumbase/undetected/cdp_driver/element.py,sha256=9oD9GxguctunrlHV3lWXlZgb9cNEjD5x03Oy84OqyVA,39631
123
- seleniumbase/undetected/cdp_driver/tab.py,sha256=KoJfNeTwLU6mVrUNw0z7F3mffBzYwR9yUtp9Lg3WwTQ,50531
123
+ seleniumbase/undetected/cdp_driver/tab.py,sha256=wUNF8GHrbhaUqg57A9ZTYHKhNPjZIcOHwrz3pj1SAg0,50526
124
124
  seleniumbase/utilities/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
125
125
  seleniumbase/utilities/selenium_grid/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
126
126
  seleniumbase/utilities/selenium_grid/download_selenium_server.py,sha256=ZdoInIbhtmdKCIPxxtJHhd2sqotqcNXWMYbwWrkh9O0,1727
@@ -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.32.2.dist-info/LICENSE,sha256=odSYtWibXBnQ1gBg6CnDZ82n8kLF_if5-2nbqnEyD8k,1085
139
- seleniumbase-4.32.2.dist-info/METADATA,sha256=rBE_z59ub2owwmxy4NZqFwetegP3ZCATfLxn2U4X5bQ,85653
140
- seleniumbase-4.32.2.dist-info/WHEEL,sha256=OVMc5UfuAQiSplgO0_WdW7vXVGAt9Hdd6qtN4HotdyA,91
141
- seleniumbase-4.32.2.dist-info/entry_points.txt,sha256=CNrh2EKNaHYEhO6pP1RJyVLB99LkDDYX7TnUK8xfjqk,623
142
- seleniumbase-4.32.2.dist-info/top_level.txt,sha256=4N97aBOQ8ETCnDnokBsWb07lJfTaq3C1ZzYRxvLMxqU,19
143
- seleniumbase-4.32.2.dist-info/RECORD,,
138
+ seleniumbase-4.32.4.dist-info/LICENSE,sha256=odSYtWibXBnQ1gBg6CnDZ82n8kLF_if5-2nbqnEyD8k,1085
139
+ seleniumbase-4.32.4.dist-info/METADATA,sha256=P-aaLSxLcDhNervTnQwolcdOOYQTBgbvIwi7_LGKsgg,86271
140
+ seleniumbase-4.32.4.dist-info/WHEEL,sha256=OVMc5UfuAQiSplgO0_WdW7vXVGAt9Hdd6qtN4HotdyA,91
141
+ seleniumbase-4.32.4.dist-info/entry_points.txt,sha256=CNrh2EKNaHYEhO6pP1RJyVLB99LkDDYX7TnUK8xfjqk,623
142
+ seleniumbase-4.32.4.dist-info/top_level.txt,sha256=4N97aBOQ8ETCnDnokBsWb07lJfTaq3C1ZzYRxvLMxqU,19
143
+ seleniumbase-4.32.4.dist-info/RECORD,,