seleniumbase 4.32.2__py3-none-any.whl → 4.32.4__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.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,,