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.
- seleniumbase/__version__.py +1 -1
 - seleniumbase/core/browser_launcher.py +9 -2
 - seleniumbase/core/sb_cdp.py +65 -13
 - seleniumbase/fixtures/base_case.py +148 -56
 - seleniumbase/fixtures/shared_utils.py +18 -0
 - seleniumbase/plugins/driver_manager.py +21 -11
 - seleniumbase/plugins/sb_manager.py +0 -24
 - seleniumbase/undetected/cdp_driver/__init__.py +1 -0
 - seleniumbase/undetected/cdp_driver/_contradict.py +110 -0
 - seleniumbase/undetected/cdp_driver/browser.py +830 -0
 - seleniumbase/undetected/cdp_driver/cdp_util.py +328 -0
 - seleniumbase/undetected/cdp_driver/config.py +328 -0
 - seleniumbase/undetected/cdp_driver/connection.py +630 -0
 - seleniumbase/undetected/cdp_driver/element.py +1150 -0
 - seleniumbase/undetected/cdp_driver/tab.py +1319 -0
 - {seleniumbase-4.32.1.dist-info → seleniumbase-4.32.3.dist-info}/METADATA +1 -1
 - {seleniumbase-4.32.1.dist-info → seleniumbase-4.32.3.dist-info}/RECORD +21 -13
 - {seleniumbase-4.32.1.dist-info → seleniumbase-4.32.3.dist-info}/LICENSE +0 -0
 - {seleniumbase-4.32.1.dist-info → seleniumbase-4.32.3.dist-info}/WHEEL +0 -0
 - {seleniumbase-4.32.1.dist-info → seleniumbase-4.32.3.dist-info}/entry_points.txt +0 -0
 - {seleniumbase-4.32.1.dist-info → seleniumbase-4.32.3.dist-info}/top_level.txt +0 -0
 
    
        seleniumbase/__version__.py
    CHANGED
    
    | 
         @@ -1,2 +1,2 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            # seleniumbase package
         
     | 
| 
       2 
     | 
    
         
            -
            __version__ = "4.32. 
     | 
| 
      
 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. 
     | 
| 
      
 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:// 
     | 
| 
      
 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
         
     | 
    
        seleniumbase/core/sb_cdp.py
    CHANGED
    
    | 
         @@ -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 
     | 
    
         
            -
                     
     | 
| 
      
 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= 
     | 
| 
      
 128 
     | 
    
         
            +
                                self.page.select(tag_name, timeout=timeout)
         
     | 
| 
       120 
129 
     | 
    
         
             
                            )
         
     | 
| 
       121 
     | 
    
         
            -
                            self.loop.run_until_complete( 
     | 
| 
       122 
     | 
    
         
            -
             
     | 
| 
       123 
     | 
    
         
            -
             
     | 
| 
      
 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 
     | 
    
         
            -
                     
     | 
| 
      
 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 
     | 
    
         
            -
                     
     | 
| 
      
 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 
     | 
    
         
            -
                         
     | 
| 
      
 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 
     | 
    
         
            -
                         
     | 
| 
      
 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 
     | 
    
         
            -
                         
     | 
| 
      
 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 
     | 
    
         
            -
                         
     | 
| 
      
 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 
     | 
    
         
            -
                         
     | 
| 
      
 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 
     | 
    
         
            -
                         
     | 
| 
      
 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 
     | 
    
         
            -
                    """ 
     | 
| 
      
 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 " 
     | 
| 
      
 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 
     | 
    
         
            -
                     
     | 
| 
       4512 
     | 
    
         
            -
             
     | 
| 
      
 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  
     | 
| 
      
 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 
     | 
    
         
            -
                     
     | 
| 
       799 
     | 
    
         
            -
                         
     | 
| 
       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= 
     | 
| 
      
 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= 
     | 
| 
       848 
     | 
    
         
            -
                            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. 
     | 
| 
      
 873 
     | 
    
         
            +
                        time.sleep(0.2)
         
     | 
| 
       863 
874 
     | 
    
         
             
                    except Exception:
         
     | 
| 
       864 
875 
     | 
    
         
             
                        pass
         
     | 
| 
       865 
876 
     | 
    
         
             
                    finally:
         
     | 
| 
       866 
     | 
    
         
            -
                         
     | 
| 
      
 877 
     | 
    
         
            +
                        with suppress(Exception):
         
     | 
| 
       867 
878 
     | 
    
         
             
                            decoy_driver.quit()
         
     | 
| 
       868 
     | 
    
         
            -
             
     | 
| 
       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
         
     |