seleniumbase 4.32.1__py3-none-any.whl → 4.32.3__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.1"
2
+ __version__ = "4.32.3"
@@ -549,7 +549,7 @@ def uc_open_with_cdp_mode(driver, url=None):
549
549
  cdp = types.SimpleNamespace()
550
550
  CDPM = sb_cdp.CDPMethods(loop, page, driver)
551
551
  cdp.get = CDPM.get
552
- cdp.open = CDPM.get
552
+ cdp.open = CDPM.open
553
553
  cdp.reload = CDPM.reload
554
554
  cdp.refresh = CDPM.refresh
555
555
  cdp.add_handler = CDPM.add_handler
@@ -590,6 +590,7 @@ def uc_open_with_cdp_mode(driver, url=None):
590
590
  cdp.medimize = CDPM.medimize
591
591
  cdp.set_window_rect = CDPM.set_window_rect
592
592
  cdp.reset_window_size = CDPM.reset_window_size
593
+ cdp.set_locale = CDPM.set_locale
593
594
  cdp.set_attributes = CDPM.set_attributes
594
595
  cdp.internalize_links = CDPM.internalize_links
595
596
  cdp.get_window = CDPM.get_window
@@ -2179,8 +2180,13 @@ def _set_chrome_options(
2179
2180
  or IS_LINUX # switches to Xvfb (non-headless)
2180
2181
  )
2181
2182
  ):
2183
+ chrome_options.add_argument("--no-pings")
2182
2184
  chrome_options.add_argument("--disable-popup-blocking")
2183
- chrome_options.add_argument("--homepage=chrome://new-tab-page/")
2185
+ chrome_options.add_argument("--homepage=chrome://version/")
2186
+ chrome_options.add_argument("--animation-duration-scale=0")
2187
+ chrome_options.add_argument("--wm-window-animations-disabled")
2188
+ chrome_options.add_argument("--enable-privacy-sandbox-ads-apis")
2189
+ chrome_options.add_argument("--disable-background-timer-throttling")
2184
2190
  # Skip remaining options that trigger anti-bot services
2185
2191
  return chrome_options
2186
2192
  chrome_options.add_argument("--test-type")
@@ -4523,6 +4529,7 @@ def get_local_driver(
4523
4529
  and uc_chrome_version
4524
4530
  and uc_chrome_version >= 117
4525
4531
  and (headless or headless2)
4532
+ and chromium_arg != "decoy"
4526
4533
  ):
4527
4534
  from seleniumbase.console_scripts import (
4528
4535
  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.
@@ -4090,6 +4090,90 @@ class BaseCase(unittest.TestCase):
4090
4090
  "Browser: {%s} is not a valid browser option. "
4091
4091
  "Valid options = {%s}" % (browser, valid_browsers)
4092
4092
  )
4093
+ # Fix Chrome-130 issues by creating a user-data-dir in advance
4094
+ if (
4095
+ undetectable
4096
+ and (
4097
+ not user_data_dir
4098
+ or not os.path.exists(user_data_dir)
4099
+ or not any(os.scandir(user_data_dir))
4100
+ )
4101
+ and self.browser == "chrome"
4102
+ and shared_utils.is_chrome_130_or_newer(binary_location)
4103
+ ):
4104
+ import tempfile
4105
+ if not user_data_dir:
4106
+ user_data_dir = os.path.normpath(tempfile.mkdtemp())
4107
+ self.user_data_dir = user_data_dir
4108
+ sb_config.user_data_dir = user_data_dir
4109
+ try:
4110
+ decoy_driver = browser_launcher.get_driver(
4111
+ browser_name=browser_name,
4112
+ headless=False,
4113
+ locale_code=locale_code,
4114
+ use_grid=use_grid,
4115
+ protocol=protocol,
4116
+ servername=servername,
4117
+ port=port,
4118
+ proxy_string=proxy_string,
4119
+ proxy_bypass_list=proxy_bypass_list,
4120
+ proxy_pac_url=proxy_pac_url,
4121
+ multi_proxy=multi_proxy,
4122
+ user_agent=user_agent,
4123
+ cap_file=cap_file,
4124
+ cap_string=cap_string,
4125
+ recorder_ext=recorder_ext,
4126
+ disable_cookies=disable_cookies,
4127
+ disable_js=disable_js,
4128
+ disable_csp=disable_csp,
4129
+ enable_ws=enable_ws,
4130
+ enable_sync=enable_sync,
4131
+ use_auto_ext=use_auto_ext,
4132
+ undetectable=undetectable,
4133
+ uc_cdp_events=uc_cdp_events,
4134
+ uc_subprocess=uc_subprocess,
4135
+ log_cdp_events=log_cdp_events,
4136
+ no_sandbox=no_sandbox,
4137
+ disable_gpu=disable_gpu,
4138
+ headless1=False,
4139
+ headless2=True,
4140
+ incognito=incognito,
4141
+ guest_mode=guest_mode,
4142
+ dark_mode=dark_mode,
4143
+ devtools=devtools,
4144
+ remote_debug=remote_debug,
4145
+ enable_3d_apis=enable_3d_apis,
4146
+ swiftshader=swiftshader,
4147
+ ad_block_on=ad_block_on,
4148
+ host_resolver_rules=host_resolver_rules,
4149
+ block_images=block_images,
4150
+ do_not_track=do_not_track,
4151
+ chromium_arg="decoy",
4152
+ firefox_arg=firefox_arg,
4153
+ firefox_pref=firefox_pref,
4154
+ user_data_dir=user_data_dir,
4155
+ extension_zip=None,
4156
+ extension_dir=None,
4157
+ disable_features=disable_features,
4158
+ binary_location=binary_location,
4159
+ driver_version=driver_version,
4160
+ page_load_strategy=page_load_strategy,
4161
+ use_wire=use_wire,
4162
+ external_pdf=external_pdf,
4163
+ test_id=test_id,
4164
+ mobile_emulator=is_mobile,
4165
+ device_width=d_width,
4166
+ device_height=d_height,
4167
+ device_pixel_ratio=d_p_r,
4168
+ browser=browser_name,
4169
+ )
4170
+ time.sleep(0.2)
4171
+ except Exception:
4172
+ pass
4173
+ finally:
4174
+ with suppress(Exception):
4175
+ decoy_driver.quit()
4176
+ time.sleep(0.1)
4093
4177
  # Launch a web browser
4094
4178
  new_driver = browser_launcher.get_driver(
4095
4179
  browser_name=browser_name,
@@ -4431,13 +4515,31 @@ class BaseCase(unittest.TestCase):
4431
4515
  cookies_file.writelines(json_cookies)
4432
4516
  cookies_file.close()
4433
4517
 
4434
- def load_cookies(self, name="cookies.txt"):
4435
- """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
+ """
4436
4527
  cookies = self.get_saved_cookies(name)
4437
4528
  self.wait_for_ready_state_complete()
4529
+ origin = self.get_origin()
4530
+ trim_origin = origin.split("://")[-1]
4438
4531
  for cookie in cookies:
4439
- if "expiry" in cookie:
4532
+ if "domain" in cookie:
4533
+ if cookie["domain"] not in origin:
4534
+ cookie["domain"] = trim_origin
4535
+ if "expiry" in cookie and (not expiry or expiry == 0):
4440
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
4441
4543
  self.driver.add_cookie(cookie)
4442
4544
 
4443
4545
  def delete_all_cookies(self):
@@ -4498,18 +4600,57 @@ class BaseCase(unittest.TestCase):
4498
4600
  def get_cookies(self):
4499
4601
  return self.driver.get_cookies()
4500
4602
 
4501
- def add_cookie(self, cookie_dict):
4603
+ def add_cookie(self, cookie_dict, expiry=False):
4502
4604
  """Usage examples:
4503
4605
  self.add_cookie({'name': 'foo', 'value': 'bar'})
4504
4606
  self.add_cookie({'name': 'foo', 'value': 'bar', 'path': '/'})
4505
4607
  self.add_cookie({'name': 'foo', 'value': 'bar', 'secure': True})
4506
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.
4507
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
4508
4629
  self.driver.add_cookie(cookie_dict)
4509
4630
 
4510
- def add_cookies(self, cookies):
4511
- for cookie_dict in cookies:
4512
- 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)
4513
4654
 
4514
4655
  def __set_esc_skip(self):
4515
4656
  if hasattr(self, "esc_end") and self.esc_end:
@@ -4656,30 +4797,6 @@ class BaseCase(unittest.TestCase):
4656
4797
  if hasattr(self.driver, "_is_using_uc") and self.driver._is_using_uc:
4657
4798
  self.driver.uc_open_with_cdp_mode(url)
4658
4799
  else:
4659
- # Fix Chrome-130 issues by creating a user-data-dir in advance
4660
- if (
4661
- (
4662
- not self.user_data_dir
4663
- or not os.path.exists(self.user_data_dir)
4664
- )
4665
- and self.browser == "chrome"
4666
- ):
4667
- import tempfile
4668
- user_data_dir = os.path.normpath(tempfile.mkdtemp())
4669
- self.user_data_dir = user_data_dir
4670
- sb_config.user_data_dir = user_data_dir
4671
- try:
4672
- driver = self.get_new_driver(
4673
- user_data_dir=user_data_dir,
4674
- undetectable=True,
4675
- headless2=True,
4676
- )
4677
- time.sleep(0.555)
4678
- except Exception:
4679
- pass
4680
- finally:
4681
- with suppress(Exception):
4682
- driver.quit()
4683
4800
  self.get_new_driver(undetectable=True)
4684
4801
  self.driver.uc_open_with_cdp_mode(url)
4685
4802
  self.cdp = self.driver.cdp
@@ -14941,31 +15058,6 @@ class BaseCase(unittest.TestCase):
14941
15058
  self.__js_start_time = int(time.time() * 1000.0)
14942
15059
  else:
14943
15060
  # Launch WebDriver for both pytest and pynose
14944
-
14945
- # Fix Chrome-130 issues by creating a user-data-dir in advance
14946
- if (
14947
- self.undetectable
14948
- and (
14949
- not self.user_data_dir
14950
- or not os.path.exists(self.user_data_dir)
14951
- )
14952
- and self.browser == "chrome"
14953
- ):
14954
- import tempfile
14955
- user_data_dir = os.path.normpath(tempfile.mkdtemp())
14956
- self.user_data_dir = user_data_dir
14957
- sb_config.user_data_dir = user_data_dir
14958
- try:
14959
- driver = self.get_new_driver(
14960
- user_data_dir=user_data_dir,
14961
- headless2=True,
14962
- )
14963
- time.sleep(0.555)
14964
- except Exception:
14965
- pass
14966
- finally:
14967
- with suppress(Exception):
14968
- driver.quit()
14969
15061
  self.driver = self.get_new_driver(
14970
15062
  browser=self.browser,
14971
15063
  headless=self.headless,
@@ -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
@@ -792,12 +793,22 @@ def Driver(
792
793
  from seleniumbase.core import browser_launcher
793
794
 
794
795
  # Fix Chrome-130 issues by creating a user-data-dir in advance
795
- if undetectable and not user_data_dir and browser == "chrome":
796
+ if (
797
+ undetectable
798
+ and (
799
+ not user_data_dir
800
+ or not os.path.exists(user_data_dir)
801
+ or not any(os.scandir(user_data_dir))
802
+ )
803
+ and browser == "chrome"
804
+ and shared_utils.is_chrome_130_or_newer(binary_location)
805
+ ):
796
806
  import tempfile
797
807
  import time
798
- user_data_dir = (
799
- os.path.normpath(tempfile.mkdtemp())
800
- )
808
+ if not user_data_dir:
809
+ user_data_dir = (
810
+ os.path.normpath(tempfile.mkdtemp())
811
+ )
801
812
  try:
802
813
  decoy_driver = browser_launcher.get_driver(
803
814
  browser_name=browser_name,
@@ -840,12 +851,12 @@ def Driver(
840
851
  host_resolver_rules=host_resolver_rules,
841
852
  block_images=block_images,
842
853
  do_not_track=do_not_track,
843
- chromium_arg=chromium_arg,
854
+ chromium_arg="decoy",
844
855
  firefox_arg=firefox_arg,
845
856
  firefox_pref=firefox_pref,
846
857
  user_data_dir=user_data_dir,
847
- extension_zip=extension_zip,
848
- extension_dir=extension_dir,
858
+ extension_zip=None,
859
+ extension_dir=None,
849
860
  disable_features=disable_features,
850
861
  binary_location=binary_location,
851
862
  driver_version=driver_version,
@@ -859,14 +870,13 @@ def Driver(
859
870
  device_pixel_ratio=d_p_r,
860
871
  browser=browser_name,
861
872
  )
862
- time.sleep(0.555)
873
+ time.sleep(0.2)
863
874
  except Exception:
864
875
  pass
865
876
  finally:
866
- try:
877
+ with suppress(Exception):
867
878
  decoy_driver.quit()
868
- except Exception:
869
- pass
879
+ time.sleep(0.1)
870
880
 
871
881
  driver = browser_launcher.get_driver(
872
882
  browser_name=browser_name,
@@ -1212,30 +1212,6 @@ def SB(
1212
1212
  if not sb_config.multi_proxy:
1213
1213
  proxy_helper.remove_proxy_zip_if_present()
1214
1214
  start_time = time.time()
1215
- saved_headless2 = headless2
1216
-
1217
- # Fix Chrome-130 issues by creating a user-data-dir in advance
1218
- if undetectable and not user_data_dir and browser == "chrome":
1219
- import tempfile
1220
- user_data_dir = (
1221
- os.path.normpath(tempfile.mkdtemp())
1222
- )
1223
- sb.user_data_dir = user_data_dir
1224
- sb_config.user_data_dir = user_data_dir
1225
- try:
1226
- decoy = sb
1227
- decoy.headless2 = True
1228
- decoy.setUp()
1229
- decoy.sleep(0.555)
1230
- except Exception:
1231
- pass
1232
- finally:
1233
- try:
1234
- decoy.tearDown()
1235
- except Exception:
1236
- pass
1237
- sb.headless2 = saved_headless2
1238
-
1239
1215
  sb.setUp()
1240
1216
  test_passed = True # This can change later
1241
1217
  teardown_exception = None
@@ -0,0 +1 @@
1
+ from seleniumbase.undetected.cdp_driver import cdp_util # noqa