seleniumbase 4.24.11__py3-none-any.whl → 4.33.15__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.
- sbase/__init__.py +1 -0
 - sbase/steps.py +7 -0
 - seleniumbase/__init__.py +16 -7
 - seleniumbase/__version__.py +1 -1
 - seleniumbase/behave/behave_sb.py +97 -32
 - seleniumbase/common/decorators.py +16 -7
 - seleniumbase/config/proxy_list.py +3 -3
 - seleniumbase/config/settings.py +4 -0
 - seleniumbase/console_scripts/logo_helper.py +47 -8
 - seleniumbase/console_scripts/run.py +345 -335
 - seleniumbase/console_scripts/sb_behave_gui.py +5 -12
 - seleniumbase/console_scripts/sb_caseplans.py +6 -13
 - seleniumbase/console_scripts/sb_commander.py +5 -12
 - seleniumbase/console_scripts/sb_install.py +62 -54
 - seleniumbase/console_scripts/sb_mkchart.py +13 -20
 - seleniumbase/console_scripts/sb_mkdir.py +11 -17
 - seleniumbase/console_scripts/sb_mkfile.py +69 -43
 - seleniumbase/console_scripts/sb_mkpres.py +13 -20
 - seleniumbase/console_scripts/sb_mkrec.py +88 -21
 - seleniumbase/console_scripts/sb_objectify.py +30 -30
 - seleniumbase/console_scripts/sb_print.py +5 -12
 - seleniumbase/console_scripts/sb_recorder.py +16 -11
 - seleniumbase/core/browser_launcher.py +1658 -221
 - seleniumbase/core/log_helper.py +42 -27
 - seleniumbase/core/mysql.py +1 -4
 - seleniumbase/core/proxy_helper.py +35 -30
 - seleniumbase/core/recorder_helper.py +24 -5
 - seleniumbase/core/sb_cdp.py +1951 -0
 - seleniumbase/core/sb_driver.py +162 -8
 - seleniumbase/core/settings_parser.py +6 -0
 - seleniumbase/core/style_sheet.py +10 -0
 - seleniumbase/extensions/recorder.zip +0 -0
 - seleniumbase/fixtures/base_case.py +1225 -614
 - seleniumbase/fixtures/constants.py +10 -1
 - seleniumbase/fixtures/js_utils.py +171 -144
 - seleniumbase/fixtures/page_actions.py +177 -13
 - seleniumbase/fixtures/page_utils.py +25 -53
 - seleniumbase/fixtures/shared_utils.py +97 -11
 - seleniumbase/js_code/active_css_js.py +1 -1
 - seleniumbase/js_code/recorder_js.py +1 -1
 - seleniumbase/plugins/base_plugin.py +2 -3
 - seleniumbase/plugins/driver_manager.py +340 -65
 - seleniumbase/plugins/pytest_plugin.py +276 -47
 - seleniumbase/plugins/sb_manager.py +412 -99
 - seleniumbase/plugins/selenium_plugin.py +122 -17
 - seleniumbase/translate/translator.py +0 -7
 - seleniumbase/undetected/__init__.py +59 -52
 - seleniumbase/undetected/cdp.py +0 -1
 - seleniumbase/undetected/cdp_driver/__init__.py +1 -0
 - seleniumbase/undetected/cdp_driver/_contradict.py +110 -0
 - seleniumbase/undetected/cdp_driver/browser.py +829 -0
 - seleniumbase/undetected/cdp_driver/cdp_util.py +458 -0
 - seleniumbase/undetected/cdp_driver/config.py +334 -0
 - seleniumbase/undetected/cdp_driver/connection.py +639 -0
 - seleniumbase/undetected/cdp_driver/element.py +1168 -0
 - seleniumbase/undetected/cdp_driver/tab.py +1323 -0
 - seleniumbase/undetected/dprocess.py +4 -7
 - seleniumbase/undetected/options.py +6 -8
 - seleniumbase/undetected/patcher.py +11 -13
 - seleniumbase/undetected/reactor.py +0 -1
 - seleniumbase/undetected/webelement.py +16 -3
 - {seleniumbase-4.24.11.dist-info → seleniumbase-4.33.15.dist-info}/LICENSE +1 -1
 - {seleniumbase-4.24.11.dist-info → seleniumbase-4.33.15.dist-info}/METADATA +299 -252
 - {seleniumbase-4.24.11.dist-info → seleniumbase-4.33.15.dist-info}/RECORD +67 -69
 - {seleniumbase-4.24.11.dist-info → seleniumbase-4.33.15.dist-info}/WHEEL +1 -1
 - sbase/ReadMe.txt +0 -2
 - seleniumbase/ReadMe.md +0 -25
 - seleniumbase/common/ReadMe.md +0 -71
 - seleniumbase/console_scripts/ReadMe.md +0 -731
 - seleniumbase/drivers/ReadMe.md +0 -27
 - seleniumbase/extensions/ReadMe.md +0 -12
 - seleniumbase/masterqa/ReadMe.md +0 -61
 - seleniumbase/resources/ReadMe.md +0 -31
 - seleniumbase/resources/favicon.ico +0 -0
 - seleniumbase/utilities/selenium_grid/ReadMe.md +0 -84
 - seleniumbase/utilities/selenium_ide/ReadMe.md +0 -111
 - {seleniumbase-4.24.11.dist-info → seleniumbase-4.33.15.dist-info}/entry_points.txt +0 -0
 - {seleniumbase-4.24.11.dist-info → seleniumbase-4.33.15.dist-info}/top_level.txt +0 -0
 
| 
         @@ -1,5 +1,6 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            """Selenium Plugin for SeleniumBase tests that run with pynose / nosetests"""
         
     | 
| 
       2 
2 
     | 
    
         
             
            import sys
         
     | 
| 
      
 3 
     | 
    
         
            +
            from contextlib import suppress
         
     | 
| 
       3 
4 
     | 
    
         
             
            from nose.plugins import Plugin
         
     | 
| 
       4 
5 
     | 
    
         
             
            from seleniumbase import config as sb_config
         
     | 
| 
       5 
6 
     | 
    
         
             
            from seleniumbase.config import settings
         
     | 
| 
         @@ -40,11 +41,14 @@ class SeleniumBrowser(Plugin): 
     | 
|
| 
       40 
41 
     | 
    
         
             
                --binary-location=PATH  (Set path of the Chromium browser binary to use.)
         
     | 
| 
       41 
42 
     | 
    
         
             
                --driver-version=VER  (Set the chromedriver or uc_driver version to use.)
         
     | 
| 
       42 
43 
     | 
    
         
             
                --sjw  (Skip JS Waits for readyState to be "complete" or Angular to load.)
         
     | 
| 
      
 44 
     | 
    
         
            +
                --wfa  (Wait for AngularJS to be done loading after specific web actions.)
         
     | 
| 
       43 
45 
     | 
    
         
             
                --pls=PLS  (Set pageLoadStrategy on Chrome: "normal", "eager", or "none".)
         
     | 
| 
       44 
     | 
    
         
            -
                --headless  ( 
     | 
| 
       45 
     | 
    
         
            -
                -- 
     | 
| 
      
 46 
     | 
    
         
            +
                --headless  (The default headless mode. Linux uses this mode by default.)
         
     | 
| 
      
 47 
     | 
    
         
            +
                --headless1  (Use Chrome's old headless mode. Fast, but has limitations.)
         
     | 
| 
      
 48 
     | 
    
         
            +
                --headless2  (Use Chrome's new headless mode, which supports extensions.)
         
     | 
| 
       46 
49 
     | 
    
         
             
                --headed  (Run tests in headed/GUI mode on Linux OS, where not default.)
         
     | 
| 
       47 
50 
     | 
    
         
             
                --xvfb  (Run tests using the Xvfb virtual display server on Linux OS.)
         
     | 
| 
      
 51 
     | 
    
         
            +
                --xvfb-metrics=STRING  (Set Xvfb display size on Linux: "Width,Height".)
         
     | 
| 
       48 
52 
     | 
    
         
             
                --locale=LOCALE_CODE  (Set the Language Locale Code for the web browser.)
         
     | 
| 
       49 
53 
     | 
    
         
             
                --interval=SECONDS  (The autoplay interval for presentations & tour steps)
         
     | 
| 
       50 
54 
     | 
    
         
             
                --start-page=URL  (The starting URL for the web browser when tests begin.)
         
     | 
| 
         @@ -60,10 +64,12 @@ class SeleniumBrowser(Plugin): 
     | 
|
| 
       60 
64 
     | 
    
         
             
                --block-images  (Block images from loading during tests.)
         
     | 
| 
       61 
65 
     | 
    
         
             
                --do-not-track  (Indicate to websites that you don't want to be tracked.)
         
     | 
| 
       62 
66 
     | 
    
         
             
                --verify-delay=SECONDS  (The delay before MasterQA verification checks.)
         
     | 
| 
      
 67 
     | 
    
         
            +
                --ee / --esc-end  (Lets the user end the current test via the ESC key.)
         
     | 
| 
       63 
68 
     | 
    
         
             
                --recorder  (Enables the Recorder for turning browser actions into code.)
         
     | 
| 
       64 
69 
     | 
    
         
             
                --rec-behave  (Same as Recorder Mode, but also generates behave-gherkin.)
         
     | 
| 
       65 
70 
     | 
    
         
             
                --rec-sleep  (If the Recorder is enabled, also records self.sleep calls.)
         
     | 
| 
       66 
71 
     | 
    
         
             
                --rec-print  (If the Recorder is enabled, prints output after tests end.)
         
     | 
| 
      
 72 
     | 
    
         
            +
                --disable-cookies  (Disable Cookies on websites. Pages might break!)
         
     | 
| 
       67 
73 
     | 
    
         
             
                --disable-js  (Disable JavaScript on websites. Pages might break!)
         
     | 
| 
       68 
74 
     | 
    
         
             
                --disable-csp  (Disable the Content Security Policy of websites.)
         
     | 
| 
       69 
75 
     | 
    
         
             
                --disable-ws  (Disable Web Security on Chromium-based browsers.)
         
     | 
| 
         @@ -80,6 +86,7 @@ class SeleniumBrowser(Plugin): 
     | 
|
| 
       80 
86 
     | 
    
         
             
                --dark  (Enable Chrome's Dark mode.)
         
     | 
| 
       81 
87 
     | 
    
         
             
                --devtools  (Open Chrome's DevTools when the browser opens.)
         
     | 
| 
       82 
88 
     | 
    
         
             
                --disable-beforeunload  (Disable the "beforeunload" event on Chrome.)
         
     | 
| 
      
 89 
     | 
    
         
            +
                --window-position=X,Y  (Set the browser's starting window position.)
         
     | 
| 
       83 
90 
     | 
    
         
             
                --window-size=WIDTH,HEIGHT  (Set the browser's starting window size.)
         
     | 
| 
       84 
91 
     | 
    
         
             
                --maximize  (Start tests with the browser window maximized.)
         
     | 
| 
       85 
92 
     | 
    
         
             
                --screenshot  (Save a screenshot at the end of each test.)
         
     | 
| 
         @@ -177,6 +184,17 @@ class SeleniumBrowser(Plugin): 
     | 
|
| 
       177 
184 
     | 
    
         
             
                                and wait_for_angularjs(), which are part of many
         
     | 
| 
       178 
185 
     | 
    
         
             
                                SeleniumBase methods for improving reliability.""",
         
     | 
| 
       179 
186 
     | 
    
         
             
                    )
         
     | 
| 
      
 187 
     | 
    
         
            +
                    parser.addoption(
         
     | 
| 
      
 188 
     | 
    
         
            +
                        "--wfa",
         
     | 
| 
      
 189 
     | 
    
         
            +
                        "--wait_for_angularjs",
         
     | 
| 
      
 190 
     | 
    
         
            +
                        "--wait-for-angularjs",
         
     | 
| 
      
 191 
     | 
    
         
            +
                        action="store_true",
         
     | 
| 
      
 192 
     | 
    
         
            +
                        dest="wait_for_angularjs",
         
     | 
| 
      
 193 
     | 
    
         
            +
                        default=False,
         
     | 
| 
      
 194 
     | 
    
         
            +
                        help="""Add waiting for AngularJS. (The default setting
         
     | 
| 
      
 195 
     | 
    
         
            +
                                was changed to no longer wait for AngularJS to
         
     | 
| 
      
 196 
     | 
    
         
            +
                                finish loading as an extra JavaScript call.)""",
         
     | 
| 
      
 197 
     | 
    
         
            +
                    )
         
     | 
| 
       180 
198 
     | 
    
         
             
                    parser.addoption(
         
     | 
| 
       181 
199 
     | 
    
         
             
                        "--protocol",
         
     | 
| 
       182 
200 
     | 
    
         
             
                        action="store",
         
     | 
| 
         @@ -421,6 +439,15 @@ class SeleniumBrowser(Plugin): 
     | 
|
| 
       421 
439 
     | 
    
         
             
                            UNLESS using a virtual display with Xvfb.
         
     | 
| 
       422 
440 
     | 
    
         
             
                            Default: False on Mac/Windows. True on Linux.""",
         
     | 
| 
       423 
441 
     | 
    
         
             
                    )
         
     | 
| 
      
 442 
     | 
    
         
            +
                    parser.addoption(
         
     | 
| 
      
 443 
     | 
    
         
            +
                        "--headless1",
         
     | 
| 
      
 444 
     | 
    
         
            +
                        action="store_true",
         
     | 
| 
      
 445 
     | 
    
         
            +
                        dest="headless1",
         
     | 
| 
      
 446 
     | 
    
         
            +
                        default=False,
         
     | 
| 
      
 447 
     | 
    
         
            +
                        help="""This option activates the old headless mode,
         
     | 
| 
      
 448 
     | 
    
         
            +
                                which is faster, but has limitations.
         
     | 
| 
      
 449 
     | 
    
         
            +
                                (May be phased out by Chrome in the future.)""",
         
     | 
| 
      
 450 
     | 
    
         
            +
                    )
         
     | 
| 
       424 
451 
     | 
    
         
             
                    parser.addoption(
         
     | 
| 
       425 
452 
     | 
    
         
             
                        "--headless2",
         
     | 
| 
       426 
453 
     | 
    
         
             
                        action="store_true",
         
     | 
| 
         @@ -452,6 +479,17 @@ class SeleniumBrowser(Plugin): 
     | 
|
| 
       452 
479 
     | 
    
         
             
                                will no longer be enabled by default on Linux.
         
     | 
| 
       453 
480 
     | 
    
         
             
                                Default: False. (Linux-ONLY!)""",
         
     | 
| 
       454 
481 
     | 
    
         
             
                    )
         
     | 
| 
      
 482 
     | 
    
         
            +
                    parser.addoption(
         
     | 
| 
      
 483 
     | 
    
         
            +
                        "--xvfb-metrics",
         
     | 
| 
      
 484 
     | 
    
         
            +
                        "--xvfb_metrics",
         
     | 
| 
      
 485 
     | 
    
         
            +
                        action="store",
         
     | 
| 
      
 486 
     | 
    
         
            +
                        dest="xvfb_metrics",
         
     | 
| 
      
 487 
     | 
    
         
            +
                        default=None,
         
     | 
| 
      
 488 
     | 
    
         
            +
                        help="""Customize the Xvfb metrics (Width,Height) on Linux.
         
     | 
| 
      
 489 
     | 
    
         
            +
                                Format: A comma-separated string with the 2 values.
         
     | 
| 
      
 490 
     | 
    
         
            +
                                Examples: "1920,1080" or "1366,768" or "1024,768".
         
     | 
| 
      
 491 
     | 
    
         
            +
                                Default: None. (None: "1366,768". Min: "1024,768".)""",
         
     | 
| 
      
 492 
     | 
    
         
            +
                    )
         
     | 
| 
       455 
493 
     | 
    
         
             
                    parser.addoption(
         
     | 
| 
       456 
494 
     | 
    
         
             
                        "--locale_code",
         
     | 
| 
       457 
495 
     | 
    
         
             
                        "--locale-code",
         
     | 
| 
         @@ -613,6 +651,16 @@ class SeleniumBrowser(Plugin): 
     | 
|
| 
       613 
651 
     | 
    
         
             
                        help="""Setting this overrides the default wait time
         
     | 
| 
       614 
652 
     | 
    
         
             
                                before each MasterQA verification pop-up.""",
         
     | 
| 
       615 
653 
     | 
    
         
             
                    )
         
     | 
| 
      
 654 
     | 
    
         
            +
                    parser.addoption(
         
     | 
| 
      
 655 
     | 
    
         
            +
                        "--esc-end",
         
     | 
| 
      
 656 
     | 
    
         
            +
                        "--esc_end",
         
     | 
| 
      
 657 
     | 
    
         
            +
                        "--ee",
         
     | 
| 
      
 658 
     | 
    
         
            +
                        action="store_true",
         
     | 
| 
      
 659 
     | 
    
         
            +
                        dest="esc_end",
         
     | 
| 
      
 660 
     | 
    
         
            +
                        default=False,
         
     | 
| 
      
 661 
     | 
    
         
            +
                        help="""End the current test early via the ESC key.
         
     | 
| 
      
 662 
     | 
    
         
            +
                                The test will be marked as skipped.""",
         
     | 
| 
      
 663 
     | 
    
         
            +
                    )
         
     | 
| 
       616 
664 
     | 
    
         
             
                    parser.addoption(
         
     | 
| 
       617 
665 
     | 
    
         
             
                        "--recorder",
         
     | 
| 
       618 
666 
     | 
    
         
             
                        "--record",
         
     | 
| 
         @@ -663,6 +711,15 @@ class SeleniumBrowser(Plugin): 
     | 
|
| 
       663 
711 
     | 
    
         
             
                        help="""The option to disable JavaScript on web pages.
         
     | 
| 
       664 
712 
     | 
    
         
             
                                Warning: Most web pages will stop working!""",
         
     | 
| 
       665 
713 
     | 
    
         
             
                    )
         
     | 
| 
      
 714 
     | 
    
         
            +
                    parser.addoption(
         
     | 
| 
      
 715 
     | 
    
         
            +
                        "--disable_cookies",
         
     | 
| 
      
 716 
     | 
    
         
            +
                        "--disable-cookies",
         
     | 
| 
      
 717 
     | 
    
         
            +
                        action="store_true",
         
     | 
| 
      
 718 
     | 
    
         
            +
                        dest="disable_cookies",
         
     | 
| 
      
 719 
     | 
    
         
            +
                        default=False,
         
     | 
| 
      
 720 
     | 
    
         
            +
                        help="""The option to disable Cookies on web pages.
         
     | 
| 
      
 721 
     | 
    
         
            +
                                Warning: Several pages may stop working!""",
         
     | 
| 
      
 722 
     | 
    
         
            +
                    )
         
     | 
| 
       666 
723 
     | 
    
         
             
                    parser.addoption(
         
     | 
| 
       667 
724 
     | 
    
         
             
                        "--disable_csp",
         
     | 
| 
       668 
725 
     | 
    
         
             
                        "--disable-csp",
         
     | 
| 
         @@ -682,6 +739,7 @@ class SeleniumBrowser(Plugin): 
     | 
|
| 
       682 
739 
     | 
    
         
             
                    parser.addoption(
         
     | 
| 
       683 
740 
     | 
    
         
             
                        "--disable_ws",
         
     | 
| 
       684 
741 
     | 
    
         
             
                        "--disable-ws",
         
     | 
| 
      
 742 
     | 
    
         
            +
                        "--dws",
         
     | 
| 
       685 
743 
     | 
    
         
             
                        "--disable-web-security",
         
     | 
| 
       686 
744 
     | 
    
         
             
                        action="store_true",
         
     | 
| 
       687 
745 
     | 
    
         
             
                        dest="disable_ws",
         
     | 
| 
         @@ -863,6 +921,17 @@ class SeleniumBrowser(Plugin): 
     | 
|
| 
       863 
921 
     | 
    
         
             
                                on Chromium browsers (Chrome or Edge).
         
     | 
| 
       864 
922 
     | 
    
         
             
                                This is already the default Firefox option.""",
         
     | 
| 
       865 
923 
     | 
    
         
             
                    )
         
     | 
| 
      
 924 
     | 
    
         
            +
                    parser.addoption(
         
     | 
| 
      
 925 
     | 
    
         
            +
                        "--window-position",
         
     | 
| 
      
 926 
     | 
    
         
            +
                        "--window_position",
         
     | 
| 
      
 927 
     | 
    
         
            +
                        action="store",
         
     | 
| 
      
 928 
     | 
    
         
            +
                        dest="window_position",
         
     | 
| 
      
 929 
     | 
    
         
            +
                        default=None,
         
     | 
| 
      
 930 
     | 
    
         
            +
                        help="""The option to set the starting window x,y position.
         
     | 
| 
      
 931 
     | 
    
         
            +
                                Format: A comma-separated string with the 2 values.
         
     | 
| 
      
 932 
     | 
    
         
            +
                                Example: "55,66"
         
     | 
| 
      
 933 
     | 
    
         
            +
                                Default: None. (Will use default values if None)""",
         
     | 
| 
      
 934 
     | 
    
         
            +
                    )
         
     | 
| 
       866 
935 
     | 
    
         
             
                    parser.addoption(
         
     | 
| 
       867 
936 
     | 
    
         
             
                        "--window-size",
         
     | 
| 
       868 
937 
     | 
    
         
             
                        "--window_size",
         
     | 
| 
         @@ -961,6 +1030,7 @@ class SeleniumBrowser(Plugin): 
     | 
|
| 
       961 
1030 
     | 
    
         
             
                    browser = self.options.browser
         
     | 
| 
       962 
1031 
     | 
    
         
             
                    test.test.browser = browser
         
     | 
| 
       963 
1032 
     | 
    
         
             
                    test.test.headless = None
         
     | 
| 
      
 1033 
     | 
    
         
            +
                    test.test.headless1 = None
         
     | 
| 
       964 
1034 
     | 
    
         
             
                    test.test.headless2 = None
         
     | 
| 
       965 
1035 
     | 
    
         
             
                    # As a shortcut, you can use "--edge" instead of "--browser=edge", etc,
         
     | 
| 
       966 
1036 
     | 
    
         
             
                    # but you can only specify one default browser. (Default: chrome)
         
     | 
| 
         @@ -1037,6 +1107,29 @@ class SeleniumBrowser(Plugin): 
     | 
|
| 
       1037 
1107 
     | 
    
         
             
                            '\n  (Your browser choice was: "%s")\n' % browser
         
     | 
| 
       1038 
1108 
     | 
    
         
             
                        )
         
     | 
| 
       1039 
1109 
     | 
    
         
             
                        raise Exception(message)
         
     | 
| 
      
 1110 
     | 
    
         
            +
                    window_position = self.options.window_position
         
     | 
| 
      
 1111 
     | 
    
         
            +
                    if window_position:
         
     | 
| 
      
 1112 
     | 
    
         
            +
                        if window_position.count(",") != 1:
         
     | 
| 
      
 1113 
     | 
    
         
            +
                            message = (
         
     | 
| 
      
 1114 
     | 
    
         
            +
                                '\n\n  window_position expects an "x,y" string!'
         
     | 
| 
      
 1115 
     | 
    
         
            +
                                '\n  (Your input was: "%s")\n' % window_position
         
     | 
| 
      
 1116 
     | 
    
         
            +
                            )
         
     | 
| 
      
 1117 
     | 
    
         
            +
                            raise Exception(message)
         
     | 
| 
      
 1118 
     | 
    
         
            +
                        window_position = window_position.replace(" ", "")
         
     | 
| 
      
 1119 
     | 
    
         
            +
                        win_x = None
         
     | 
| 
      
 1120 
     | 
    
         
            +
                        win_y = None
         
     | 
| 
      
 1121 
     | 
    
         
            +
                        try:
         
     | 
| 
      
 1122 
     | 
    
         
            +
                            win_x = int(window_position.split(",")[0])
         
     | 
| 
      
 1123 
     | 
    
         
            +
                            win_y = int(window_position.split(",")[1])
         
     | 
| 
      
 1124 
     | 
    
         
            +
                        except Exception:
         
     | 
| 
      
 1125 
     | 
    
         
            +
                            message = (
         
     | 
| 
      
 1126 
     | 
    
         
            +
                                '\n\n  Expecting integer values for "x,y"!'
         
     | 
| 
      
 1127 
     | 
    
         
            +
                                '\n  (window_position input was: "%s")\n'
         
     | 
| 
      
 1128 
     | 
    
         
            +
                                % window_position
         
     | 
| 
      
 1129 
     | 
    
         
            +
                            )
         
     | 
| 
      
 1130 
     | 
    
         
            +
                            raise Exception(message)
         
     | 
| 
      
 1131 
     | 
    
         
            +
                        settings.WINDOW_START_X = win_x
         
     | 
| 
      
 1132 
     | 
    
         
            +
                        settings.WINDOW_START_Y = win_y
         
     | 
| 
       1040 
1133 
     | 
    
         
             
                    window_size = self.options.window_size
         
     | 
| 
       1041 
1134 
     | 
    
         
             
                    if window_size:
         
     | 
| 
       1042 
1135 
     | 
    
         
             
                        if window_size.count(",") != 1:
         
     | 
| 
         @@ -1076,9 +1169,13 @@ class SeleniumBrowser(Plugin): 
     | 
|
| 
       1076 
1169 
     | 
    
         
             
                    test.test.cap_file = self.options.cap_file
         
     | 
| 
       1077 
1170 
     | 
    
         
             
                    test.test.cap_string = self.options.cap_string
         
     | 
| 
       1078 
1171 
     | 
    
         
             
                    test.test.headless = self.options.headless
         
     | 
| 
      
 1172 
     | 
    
         
            +
                    test.test.headless1 = self.options.headless1
         
     | 
| 
      
 1173 
     | 
    
         
            +
                    if test.test.headless1:
         
     | 
| 
      
 1174 
     | 
    
         
            +
                        test.test.headless = True
         
     | 
| 
       1079 
1175 
     | 
    
         
             
                    test.test.headless2 = self.options.headless2
         
     | 
| 
       1080 
1176 
     | 
    
         
             
                    if test.test.headless and test.test.browser == "safari":
         
     | 
| 
       1081 
1177 
     | 
    
         
             
                        test.test.headless = False  # Safari doesn't use headless
         
     | 
| 
      
 1178 
     | 
    
         
            +
                        test.test.headless1 = False
         
     | 
| 
       1082 
1179 
     | 
    
         
             
                    if test.test.headless2 and test.test.browser == "firefox":
         
     | 
| 
       1083 
1180 
     | 
    
         
             
                        test.test.headless2 = False  # Only for Chromium browsers
         
     | 
| 
       1084 
1181 
     | 
    
         
             
                        test.test.headless = True  # Firefox has regular headless
         
     | 
| 
         @@ -1089,11 +1186,14 @@ class SeleniumBrowser(Plugin): 
     | 
|
| 
       1089 
1186 
     | 
    
         
             
                        self.options.headless2 = False
         
     | 
| 
       1090 
1187 
     | 
    
         
             
                    test.test.headed = self.options.headed
         
     | 
| 
       1091 
1188 
     | 
    
         
             
                    test.test.xvfb = self.options.xvfb
         
     | 
| 
      
 1189 
     | 
    
         
            +
                    test.test.xvfb_metrics = self.options.xvfb_metrics
         
     | 
| 
       1092 
1190 
     | 
    
         
             
                    test.test.locale_code = self.options.locale_code
         
     | 
| 
       1093 
1191 
     | 
    
         
             
                    test.test.interval = self.options.interval
         
     | 
| 
       1094 
1192 
     | 
    
         
             
                    test.test.start_page = self.options.start_page
         
     | 
| 
       1095 
1193 
     | 
    
         
             
                    if self.options.skip_js_waits:
         
     | 
| 
       1096 
1194 
     | 
    
         
             
                        settings.SKIP_JS_WAITS = True
         
     | 
| 
      
 1195 
     | 
    
         
            +
                    if self.options.wait_for_angularjs:
         
     | 
| 
      
 1196 
     | 
    
         
            +
                        settings.WAIT_FOR_ANGULARJS = True
         
     | 
| 
       1097 
1197 
     | 
    
         
             
                    test.test.protocol = self.options.protocol
         
     | 
| 
       1098 
1198 
     | 
    
         
             
                    test.test.servername = self.options.servername
         
     | 
| 
       1099 
1199 
     | 
    
         
             
                    test.test.port = self.options.port
         
     | 
| 
         @@ -1126,6 +1226,7 @@ class SeleniumBrowser(Plugin): 
     | 
|
| 
       1126 
1226 
     | 
    
         
             
                    test.test.block_images = self.options.block_images
         
     | 
| 
       1127 
1227 
     | 
    
         
             
                    test.test.do_not_track = self.options.do_not_track
         
     | 
| 
       1128 
1228 
     | 
    
         
             
                    test.test.verify_delay = self.options.verify_delay  # MasterQA
         
     | 
| 
      
 1229 
     | 
    
         
            +
                    test.test.esc_end = self.options.esc_end
         
     | 
| 
       1129 
1230 
     | 
    
         
             
                    test.test.recorder_mode = self.options.recorder_mode
         
     | 
| 
       1130 
1231 
     | 
    
         
             
                    test.test.recorder_ext = self.options.recorder_mode  # Again
         
     | 
| 
       1131 
1232 
     | 
    
         
             
                    test.test.rec_behave = self.options.rec_behave
         
     | 
| 
         @@ -1140,6 +1241,7 @@ class SeleniumBrowser(Plugin): 
     | 
|
| 
       1140 
1241 
     | 
    
         
             
                    elif self.options.record_sleep:
         
     | 
| 
       1141 
1242 
     | 
    
         
             
                        test.test.recorder_mode = True
         
     | 
| 
       1142 
1243 
     | 
    
         
             
                        test.test.recorder_ext = True
         
     | 
| 
      
 1244 
     | 
    
         
            +
                    test.test.disable_cookies = self.options.disable_cookies
         
     | 
| 
       1143 
1245 
     | 
    
         
             
                    test.test.disable_js = self.options.disable_js
         
     | 
| 
       1144 
1246 
     | 
    
         
             
                    test.test.disable_csp = self.options.disable_csp
         
     | 
| 
       1145 
1247 
     | 
    
         
             
                    test.test.disable_ws = self.options.disable_ws
         
     | 
| 
         @@ -1166,6 +1268,7 @@ class SeleniumBrowser(Plugin): 
     | 
|
| 
       1166 
1268 
     | 
    
         
             
                    test.test.dark_mode = self.options.dark_mode
         
     | 
| 
       1167 
1269 
     | 
    
         
             
                    test.test.devtools = self.options.devtools
         
     | 
| 
       1168 
1270 
     | 
    
         
             
                    test.test._disable_beforeunload = self.options._disable_beforeunload
         
     | 
| 
      
 1271 
     | 
    
         
            +
                    test.test.window_position = self.options.window_position
         
     | 
| 
       1169 
1272 
     | 
    
         
             
                    test.test.window_size = self.options.window_size
         
     | 
| 
       1170 
1273 
     | 
    
         
             
                    test.test.maximize_option = self.options.maximize_option
         
     | 
| 
       1171 
1274 
     | 
    
         
             
                    if self.options.save_screenshot and self.options.no_screenshot:
         
     | 
| 
         @@ -1192,15 +1295,19 @@ class SeleniumBrowser(Plugin): 
     | 
|
| 
       1192 
1295 
     | 
    
         
             
                        and not self.options.headless2
         
     | 
| 
       1193 
1296 
     | 
    
         
             
                        and not self.options.xvfb
         
     | 
| 
       1194 
1297 
     | 
    
         
             
                    ):
         
     | 
| 
       1195 
     | 
    
         
            -
                         
     | 
| 
       1196 
     | 
    
         
            -
                             
     | 
| 
       1197 
     | 
    
         
            -
             
     | 
| 
       1198 
     | 
    
         
            -
             
     | 
| 
       1199 
     | 
    
         
            -
             
     | 
| 
       1200 
     | 
    
         
            -
             
     | 
| 
       1201 
     | 
    
         
            -
             
     | 
| 
       1202 
     | 
    
         
            -
             
     | 
| 
       1203 
     | 
    
         
            -
             
     | 
| 
      
 1298 
     | 
    
         
            +
                        if not self.options.undetectable:
         
     | 
| 
      
 1299 
     | 
    
         
            +
                            print(
         
     | 
| 
      
 1300 
     | 
    
         
            +
                                "(Linux uses --headless by default. "
         
     | 
| 
      
 1301 
     | 
    
         
            +
                                "To override, use --headed / --gui. "
         
     | 
| 
      
 1302 
     | 
    
         
            +
                                "For Xvfb mode instead, use --xvfb. "
         
     | 
| 
      
 1303 
     | 
    
         
            +
                                "Or you can hide this info by using "
         
     | 
| 
      
 1304 
     | 
    
         
            +
                                "--headless / --headless2 / --uc.)"
         
     | 
| 
      
 1305 
     | 
    
         
            +
                            )
         
     | 
| 
      
 1306 
     | 
    
         
            +
                            self.options.headless = True
         
     | 
| 
      
 1307 
     | 
    
         
            +
                            test.test.headless = True
         
     | 
| 
      
 1308 
     | 
    
         
            +
                        else:
         
     | 
| 
      
 1309 
     | 
    
         
            +
                            self.options.xvfb = True
         
     | 
| 
      
 1310 
     | 
    
         
            +
                            test.test.xvfb = True
         
     | 
| 
       1204 
1311 
     | 
    
         
             
                    if self.options.use_wire and self.options.undetectable:
         
     | 
| 
       1205 
1312 
     | 
    
         
             
                        print(
         
     | 
| 
       1206 
1313 
     | 
    
         
             
                            "\n"
         
     | 
| 
         @@ -1214,8 +1321,10 @@ class SeleniumBrowser(Plugin): 
     | 
|
| 
       1214 
1321 
     | 
    
         
             
                    # Recorder Mode can still optimize scripts in --headless2 mode.
         
     | 
| 
       1215 
1322 
     | 
    
         
             
                    if self.options.recorder_mode and self.options.headless:
         
     | 
| 
       1216 
1323 
     | 
    
         
             
                        self.options.headless = False
         
     | 
| 
      
 1324 
     | 
    
         
            +
                        self.options.headless1 = False
         
     | 
| 
       1217 
1325 
     | 
    
         
             
                        self.options.headless2 = True
         
     | 
| 
       1218 
1326 
     | 
    
         
             
                        test.test.headless = False
         
     | 
| 
      
 1327 
     | 
    
         
            +
                        test.test.headless1 = False
         
     | 
| 
       1219 
1328 
     | 
    
         
             
                        test.test.headless2 = True
         
     | 
| 
       1220 
1329 
     | 
    
         
             
                    if not self.options.headless and not self.options.headless2:
         
     | 
| 
       1221 
1330 
     | 
    
         
             
                        self.options.headed = True
         
     | 
| 
         @@ -1229,7 +1338,7 @@ class SeleniumBrowser(Plugin): 
     | 
|
| 
       1229 
1338 
     | 
    
         
             
                    ):
         
     | 
| 
       1230 
1339 
     | 
    
         
             
                        width = settings.HEADLESS_START_WIDTH
         
     | 
| 
       1231 
1340 
     | 
    
         
             
                        height = settings.HEADLESS_START_HEIGHT
         
     | 
| 
       1232 
     | 
    
         
            -
                         
     | 
| 
      
 1341 
     | 
    
         
            +
                        with suppress(Exception):
         
     | 
| 
       1233 
1342 
     | 
    
         
             
                            from sbvirtualdisplay import Display
         
     | 
| 
       1234 
1343 
     | 
    
         | 
| 
       1235 
1344 
     | 
    
         
             
                            self._xvfb_display = Display(visible=0, size=(width, height))
         
     | 
| 
         @@ -1237,8 +1346,6 @@ class SeleniumBrowser(Plugin): 
     | 
|
| 
       1237 
1346 
     | 
    
         
             
                            sb_config._virtual_display = self._xvfb_display
         
     | 
| 
       1238 
1347 
     | 
    
         
             
                            self.headless_active = True
         
     | 
| 
       1239 
1348 
     | 
    
         
             
                            sb_config.headless_active = True
         
     | 
| 
       1240 
     | 
    
         
            -
                        except Exception:
         
     | 
| 
       1241 
     | 
    
         
            -
                            pass
         
     | 
| 
       1242 
1349 
     | 
    
         
             
                    sb_config._is_timeout_changed = False
         
     | 
| 
       1243 
1350 
     | 
    
         
             
                    sb_config._SMALL_TIMEOUT = settings.SMALL_TIMEOUT
         
     | 
| 
       1244 
1351 
     | 
    
         
             
                    sb_config._LARGE_TIMEOUT = settings.LARGE_TIMEOUT
         
     | 
| 
         @@ -1271,7 +1378,7 @@ class SeleniumBrowser(Plugin): 
     | 
|
| 
       1271 
1378 
     | 
    
         
             
                        pass
         
     | 
| 
       1272 
1379 
     | 
    
         
             
                    except Exception:
         
     | 
| 
       1273 
1380 
     | 
    
         
             
                        pass
         
     | 
| 
       1274 
     | 
    
         
            -
                     
     | 
| 
      
 1381 
     | 
    
         
            +
                    with suppress(Exception):
         
     | 
| 
       1275 
1382 
     | 
    
         
             
                        if (
         
     | 
| 
       1276 
1383 
     | 
    
         
             
                            hasattr(self, "_xvfb_display")
         
     | 
| 
       1277 
1384 
     | 
    
         
             
                            and self._xvfb_display
         
     | 
| 
         @@ -1288,5 +1395,3 @@ class SeleniumBrowser(Plugin): 
     | 
|
| 
       1288 
1395 
     | 
    
         
             
                        ):
         
     | 
| 
       1289 
1396 
     | 
    
         
             
                            sb_config._virtual_display.stop()
         
     | 
| 
       1290 
1397 
     | 
    
         
             
                            sb_config._virtual_display = None
         
     | 
| 
       1291 
     | 
    
         
            -
                    except Exception:
         
     | 
| 
       1292 
     | 
    
         
            -
                        pass
         
     | 
| 
         @@ -267,13 +267,6 @@ def process_test_file(code_lines, new_lang): 
     | 
|
| 
       267 
267 
     | 
    
         | 
| 
       268 
268 
     | 
    
         | 
| 
       269 
269 
     | 
    
         
             
            def main():
         
     | 
| 
       270 
     | 
    
         
            -
                if (
         
     | 
| 
       271 
     | 
    
         
            -
                    "win32" in sys.platform
         
     | 
| 
       272 
     | 
    
         
            -
                    and hasattr(colorama, "just_fix_windows_console")
         
     | 
| 
       273 
     | 
    
         
            -
                ):
         
     | 
| 
       274 
     | 
    
         
            -
                    colorama.just_fix_windows_console()
         
     | 
| 
       275 
     | 
    
         
            -
                else:
         
     | 
| 
       276 
     | 
    
         
            -
                    colorama.init(autoreset=True)
         
     | 
| 
       277 
270 
     | 
    
         
             
                c1 = colorama.Fore.BLUE + colorama.Back.LIGHTCYAN_EX
         
     | 
| 
       278 
271 
     | 
    
         
             
                c2 = colorama.Fore.BLUE + colorama.Back.LIGHTYELLOW_EX
         
     | 
| 
       279 
272 
     | 
    
         
             
                c3 = colorama.Fore.RED + colorama.Back.LIGHTGREEN_EX
         
     | 
| 
         @@ -1,4 +1,3 @@ 
     | 
|
| 
       1 
     | 
    
         
            -
            #!/usr/bin/env python3
         
     | 
| 
       2 
1 
     | 
    
         
             
            import logging
         
     | 
| 
       3 
2 
     | 
    
         
             
            import os
         
     | 
| 
       4 
3 
     | 
    
         
             
            import re
         
     | 
| 
         @@ -10,6 +9,7 @@ import selenium.webdriver.chrome.service 
     | 
|
| 
       10 
9 
     | 
    
         
             
            import selenium.webdriver.chrome.webdriver
         
     | 
| 
       11 
10 
     | 
    
         
             
            import selenium.webdriver.common.service
         
     | 
| 
       12 
11 
     | 
    
         
             
            import selenium.webdriver.remote.command
         
     | 
| 
      
 12 
     | 
    
         
            +
            from contextlib import suppress
         
     | 
| 
       13 
13 
     | 
    
         
             
            from .cdp import CDP
         
     | 
| 
       14 
14 
     | 
    
         
             
            from .cdp import PageElement
         
     | 
| 
       15 
15 
     | 
    
         
             
            from .dprocess import start_detached
         
     | 
| 
         @@ -132,8 +132,11 @@ class Chrome(selenium.webdriver.chrome.webdriver.WebDriver): 
     | 
|
| 
       132 
132 
     | 
    
         
             
                        options = ChromeOptions()
         
     | 
| 
       133 
133 
     | 
    
         
             
                    try:
         
     | 
| 
       134 
134 
     | 
    
         
             
                        if hasattr(options, "_session") and options._session is not None:
         
     | 
| 
       135 
     | 
    
         
            -
                            # Prevent reuse of options
         
     | 
| 
       136 
     | 
    
         
            -
                             
     | 
| 
      
 135 
     | 
    
         
            +
                            # Prevent reuse of options.
         
     | 
| 
      
 136 
     | 
    
         
            +
                            # (Probably a port overlap. Quit existing driver and continue.)
         
     | 
| 
      
 137 
     | 
    
         
            +
                            logger.debug("You cannot reuse the ChromeOptions object")
         
     | 
| 
      
 138 
     | 
    
         
            +
                            with suppress(Exception):
         
     | 
| 
      
 139 
     | 
    
         
            +
                                options._session.quit()
         
     | 
| 
       137 
140 
     | 
    
         
             
                    except AttributeError:
         
     | 
| 
       138 
141 
     | 
    
         
             
                        pass
         
     | 
| 
       139 
142 
     | 
    
         
             
                    options._session = self
         
     | 
| 
         @@ -201,11 +204,9 @@ class Chrome(selenium.webdriver.chrome.webdriver.WebDriver): 
     | 
|
| 
       201 
204 
     | 
    
         
             
                            # Create a temporary folder for the user-data profile.
         
     | 
| 
       202 
205 
     | 
    
         
             
                            options.add_argument(arg)
         
     | 
| 
       203 
206 
     | 
    
         
             
                    if not language:
         
     | 
| 
       204 
     | 
    
         
            -
                         
     | 
| 
      
 207 
     | 
    
         
            +
                        with suppress(Exception):
         
     | 
| 
       205 
208 
     | 
    
         
             
                            import locale
         
     | 
| 
       206 
209 
     | 
    
         
             
                            language = locale.getlocale()[0].replace("_", "-")
         
     | 
| 
       207 
     | 
    
         
            -
                        except Exception:
         
     | 
| 
       208 
     | 
    
         
            -
                            pass
         
     | 
| 
       209 
210 
     | 
    
         
             
                        if (
         
     | 
| 
       210 
211 
     | 
    
         
             
                            not language
         
     | 
| 
       211 
212 
     | 
    
         
             
                            or "English" in language
         
     | 
| 
         @@ -234,6 +235,7 @@ class Chrome(selenium.webdriver.chrome.webdriver.WebDriver): 
     | 
|
| 
       234 
235 
     | 
    
         
             
                                "--no-first-run",
         
     | 
| 
       235 
236 
     | 
    
         
             
                                "--no-service-autorun",
         
     | 
| 
       236 
237 
     | 
    
         
             
                                "--password-store=basic",
         
     | 
| 
      
 238 
     | 
    
         
            +
                                "--profile-directory=Default",
         
     | 
| 
       237 
239 
     | 
    
         
             
                            ]
         
     | 
| 
       238 
240 
     | 
    
         
             
                        )
         
     | 
| 
       239 
241 
     | 
    
         
             
                    options.add_argument(
         
     | 
| 
         @@ -242,7 +244,7 @@ class Chrome(selenium.webdriver.chrome.webdriver.WebDriver): 
     | 
|
| 
       242 
244 
     | 
    
         
             
                    )
         
     | 
| 
       243 
245 
     | 
    
         
             
                    if hasattr(options, 'handle_prefs'):
         
     | 
| 
       244 
246 
     | 
    
         
             
                        options.handle_prefs(user_data_dir)
         
     | 
| 
       245 
     | 
    
         
            -
                     
     | 
| 
      
 247 
     | 
    
         
            +
                    with suppress(Exception):
         
     | 
| 
       246 
248 
     | 
    
         
             
                        import json
         
     | 
| 
       247 
249 
     | 
    
         
             
                        with open(
         
     | 
| 
       248 
250 
     | 
    
         
             
                            os.path.join(
         
     | 
| 
         @@ -263,8 +265,6 @@ class Chrome(selenium.webdriver.chrome.webdriver.WebDriver): 
     | 
|
| 
       263 
265 
     | 
    
         
             
                            fs.seek(0, 0)
         
     | 
| 
       264 
266 
     | 
    
         
             
                            fs.truncate()
         
     | 
| 
       265 
267 
     | 
    
         
             
                            json.dump(config, fs)
         
     | 
| 
       266 
     | 
    
         
            -
                    except Exception:
         
     | 
| 
       267 
     | 
    
         
            -
                        pass
         
     | 
| 
       268 
268 
     | 
    
         
             
                    creationflags = 0
         
     | 
| 
       269 
269 
     | 
    
         
             
                    if "win32" in sys.platform:
         
     | 
| 
       270 
270 
     | 
    
         
             
                        creationflags = subprocess.CREATE_NO_WINDOW
         
     | 
| 
         @@ -278,19 +278,21 @@ class Chrome(selenium.webdriver.chrome.webdriver.WebDriver): 
     | 
|
| 
       278 
278 
     | 
    
         
             
                                options.binary_location, *options.arguments
         
     | 
| 
       279 
279 
     | 
    
         
             
                            )
         
     | 
| 
       280 
280 
     | 
    
         
             
                        else:
         
     | 
| 
       281 
     | 
    
         
            -
                             
     | 
| 
       282 
     | 
    
         
            -
                                 
     | 
| 
       283 
     | 
    
         
            -
                                stdin=subprocess.PIPE,
         
     | 
| 
       284 
     | 
    
         
            -
                                stdout=subprocess.PIPE,
         
     | 
| 
       285 
     | 
    
         
            -
                                stderr=subprocess.PIPE,
         
     | 
| 
       286 
     | 
    
         
            -
                                close_fds=IS_POSIX,
         
     | 
| 
       287 
     | 
    
         
            -
                                creationflags=creationflags,
         
     | 
| 
      
 281 
     | 
    
         
            +
                            gui_lock = fasteners.InterProcessLock(
         
     | 
| 
      
 282 
     | 
    
         
            +
                                constants.MultiBrowser.PYAUTOGUILOCK
         
     | 
| 
       288 
283 
     | 
    
         
             
                            )
         
     | 
| 
       289 
     | 
    
         
            -
                             
     | 
| 
      
 284 
     | 
    
         
            +
                            with gui_lock:
         
     | 
| 
      
 285 
     | 
    
         
            +
                                browser = subprocess.Popen(
         
     | 
| 
      
 286 
     | 
    
         
            +
                                    [options.binary_location, *options.arguments],
         
     | 
| 
      
 287 
     | 
    
         
            +
                                    stdin=subprocess.PIPE,
         
     | 
| 
      
 288 
     | 
    
         
            +
                                    stdout=subprocess.PIPE,
         
     | 
| 
      
 289 
     | 
    
         
            +
                                    stderr=subprocess.PIPE,
         
     | 
| 
      
 290 
     | 
    
         
            +
                                    close_fds=IS_POSIX,
         
     | 
| 
      
 291 
     | 
    
         
            +
                                    creationflags=creationflags,
         
     | 
| 
      
 292 
     | 
    
         
            +
                                )
         
     | 
| 
      
 293 
     | 
    
         
            +
                                self.browser_pid = browser.pid
         
     | 
| 
       290 
294 
     | 
    
         
             
                        service_ = None
         
     | 
| 
       291 
295 
     | 
    
         
             
                        log_output = subprocess.PIPE
         
     | 
| 
       292 
     | 
    
         
            -
                        if sys.version_info < (3, 8):
         
     | 
| 
       293 
     | 
    
         
            -
                            log_output = os.devnull
         
     | 
| 
       294 
296 
     | 
    
         
             
                        if patch_driver:
         
     | 
| 
       295 
297 
     | 
    
         
             
                            service_ = selenium.webdriver.chrome.service.Service(
         
     | 
| 
       296 
298 
     | 
    
         
             
                                executable_path=self.patcher.executable_path,
         
     | 
| 
         @@ -338,7 +340,7 @@ class Chrome(selenium.webdriver.chrome.webdriver.WebDriver): 
     | 
|
| 
       338 
340 
     | 
    
         | 
| 
       339 
341 
     | 
    
         
             
                def _get_cdc_props(self):
         
     | 
| 
       340 
342 
     | 
    
         
             
                    cdc_props = []
         
     | 
| 
       341 
     | 
    
         
            -
                     
     | 
| 
      
 343 
     | 
    
         
            +
                    with suppress(Exception):
         
     | 
| 
       342 
344 
     | 
    
         
             
                        cdc_props = self.execute_script(
         
     | 
| 
       343 
345 
     | 
    
         
             
                            """
         
     | 
| 
       344 
346 
     | 
    
         
             
                            let objectToInspect = window,
         
     | 
| 
         @@ -351,8 +353,6 @@ class Chrome(selenium.webdriver.chrome.webdriver.WebDriver): 
     | 
|
| 
       351 
353 
     | 
    
         
             
                            return result.filter(i => i.match(/^[a-z]{3}_[a-z]{22}_.*/i))
         
     | 
| 
       352 
354 
     | 
    
         
             
                            """
         
     | 
| 
       353 
355 
     | 
    
         
             
                        )
         
     | 
| 
       354 
     | 
    
         
            -
                    except Exception:
         
     | 
| 
       355 
     | 
    
         
            -
                        pass
         
     | 
| 
       356 
356 
     | 
    
         
             
                    return cdc_props
         
     | 
| 
       357 
357 
     | 
    
         | 
| 
       358 
358 
     | 
    
         
             
                def _hook_remove_cdc_props(self, cdc_props):
         
     | 
| 
         @@ -423,46 +423,57 @@ class Chrome(selenium.webdriver.chrome.webdriver.WebDriver): 
     | 
|
| 
       423 
423 
     | 
    
         
             
                    - Starts the chromedriver service that runs in the background.
         
     | 
| 
       424 
424 
     | 
    
         
             
                    - Recreates the session."""
         
     | 
| 
       425 
425 
     | 
    
         
             
                    if hasattr(self, "service"):
         
     | 
| 
       426 
     | 
    
         
            -
                         
     | 
| 
       427 
     | 
    
         
            -
                            self.service. 
     | 
| 
       428 
     | 
    
         
            -
             
     | 
| 
       429 
     | 
    
         
            -
             
     | 
| 
      
 426 
     | 
    
         
            +
                        with suppress(Exception):
         
     | 
| 
      
 427 
     | 
    
         
            +
                            if self.service.is_connectable():
         
     | 
| 
      
 428 
     | 
    
         
            +
                                self.stop_client()
         
     | 
| 
      
 429 
     | 
    
         
            +
                                self.service.stop()
         
     | 
| 
       430 
430 
     | 
    
         
             
                        if isinstance(timeout, str):
         
     | 
| 
       431 
431 
     | 
    
         
             
                            if timeout.lower() == "breakpoint":
         
     | 
| 
       432 
432 
     | 
    
         
             
                                breakpoint()  # To continue:
         
     | 
| 
       433 
433 
     | 
    
         
             
                                pass  # Type "c" & press ENTER!
         
     | 
| 
       434 
434 
     | 
    
         
             
                        else:
         
     | 
| 
       435 
435 
     | 
    
         
             
                            time.sleep(timeout)
         
     | 
| 
       436 
     | 
    
         
            -
                         
     | 
| 
      
 436 
     | 
    
         
            +
                        with suppress(Exception):
         
     | 
| 
       437 
437 
     | 
    
         
             
                            self.service.start()
         
     | 
| 
       438 
     | 
    
         
            -
             
     | 
| 
       439 
     | 
    
         
            -
                            pass
         
     | 
| 
       440 
     | 
    
         
            -
                    try:
         
     | 
| 
      
 438 
     | 
    
         
            +
                    with suppress(Exception):
         
     | 
| 
       441 
439 
     | 
    
         
             
                        self.start_session()
         
     | 
| 
       442 
     | 
    
         
            -
                     
     | 
| 
       443 
     | 
    
         
            -
                         
     | 
| 
      
 440 
     | 
    
         
            +
                    with suppress(Exception):
         
     | 
| 
      
 441 
     | 
    
         
            +
                        if self.current_url.startswith("chrome-extension://"):
         
     | 
| 
      
 442 
     | 
    
         
            +
                            self.close()
         
     | 
| 
      
 443 
     | 
    
         
            +
                            if self.service.is_connectable():
         
     | 
| 
      
 444 
     | 
    
         
            +
                                self.stop_client()
         
     | 
| 
      
 445 
     | 
    
         
            +
                                self.service.stop()
         
     | 
| 
      
 446 
     | 
    
         
            +
                            self.service.start()
         
     | 
| 
      
 447 
     | 
    
         
            +
                            self.start_session()
         
     | 
| 
      
 448 
     | 
    
         
            +
                    self._is_connected = True
         
     | 
| 
       444 
449 
     | 
    
         | 
| 
       445 
450 
     | 
    
         
             
                def disconnect(self):
         
     | 
| 
       446 
451 
     | 
    
         
             
                    """Stops the chromedriver service that runs in the background.
         
     | 
| 
       447 
452 
     | 
    
         
             
                    To use driver methods again, you MUST call driver.connect()"""
         
     | 
| 
       448 
453 
     | 
    
         
             
                    if hasattr(self, "service"):
         
     | 
| 
       449 
     | 
    
         
            -
                         
     | 
| 
       450 
     | 
    
         
            -
                            self.service. 
     | 
| 
       451 
     | 
    
         
            -
             
     | 
| 
       452 
     | 
    
         
            -
             
     | 
| 
      
 454 
     | 
    
         
            +
                        with suppress(Exception):
         
     | 
| 
      
 455 
     | 
    
         
            +
                            if self.service.is_connectable():
         
     | 
| 
      
 456 
     | 
    
         
            +
                                self.stop_client()
         
     | 
| 
      
 457 
     | 
    
         
            +
                                self.service.stop()
         
     | 
| 
      
 458 
     | 
    
         
            +
                    self._is_connected = False
         
     | 
| 
       453 
459 
     | 
    
         | 
| 
       454 
460 
     | 
    
         
             
                def connect(self):
         
     | 
| 
       455 
461 
     | 
    
         
             
                    """Starts the chromedriver service that runs in the background
         
     | 
| 
       456 
462 
     | 
    
         
             
                    and recreates the session."""
         
     | 
| 
       457 
463 
     | 
    
         
             
                    if hasattr(self, "service"):
         
     | 
| 
       458 
     | 
    
         
            -
                         
     | 
| 
      
 464 
     | 
    
         
            +
                        with suppress(Exception):
         
     | 
| 
       459 
465 
     | 
    
         
             
                            self.service.start()
         
     | 
| 
       460 
     | 
    
         
            -
             
     | 
| 
       461 
     | 
    
         
            -
                            pass
         
     | 
| 
       462 
     | 
    
         
            -
                    try:
         
     | 
| 
      
 466 
     | 
    
         
            +
                    with suppress(Exception):
         
     | 
| 
       463 
467 
     | 
    
         
             
                        self.start_session()
         
     | 
| 
       464 
     | 
    
         
            -
                     
     | 
| 
       465 
     | 
    
         
            -
                         
     | 
| 
      
 468 
     | 
    
         
            +
                    with suppress(Exception):
         
     | 
| 
      
 469 
     | 
    
         
            +
                        if self.current_url.startswith("chrome-extension://"):
         
     | 
| 
      
 470 
     | 
    
         
            +
                            self.close()
         
     | 
| 
      
 471 
     | 
    
         
            +
                            if self.service.is_connectable():
         
     | 
| 
      
 472 
     | 
    
         
            +
                                self.stop_client()
         
     | 
| 
      
 473 
     | 
    
         
            +
                                self.service.stop()
         
     | 
| 
      
 474 
     | 
    
         
            +
                            self.service.start()
         
     | 
| 
      
 475 
     | 
    
         
            +
                            self.start_session()
         
     | 
| 
      
 476 
     | 
    
         
            +
                    self._is_connected = True
         
     | 
| 
       466 
477 
     | 
    
         | 
| 
       467 
478 
     | 
    
         
             
                def start_session(self, capabilities=None):
         
     | 
| 
       468 
479 
     | 
    
         
             
                    if not capabilities:
         
     | 
| 
         @@ -486,13 +497,13 @@ class Chrome(selenium.webdriver.chrome.webdriver.WebDriver): 
     | 
|
| 
       486 
497 
     | 
    
         
             
                        pass
         
     | 
| 
       487 
498 
     | 
    
         
             
                    if hasattr(self, "service") and getattr(self.service, "process", None):
         
     | 
| 
       488 
499 
     | 
    
         
             
                        logger.debug("Stopping webdriver service")
         
     | 
| 
       489 
     | 
    
         
            -
                         
     | 
| 
       490 
     | 
    
         
            -
             
     | 
| 
      
 500 
     | 
    
         
            +
                        with suppress(Exception):
         
     | 
| 
      
 501 
     | 
    
         
            +
                            self.stop_client()
         
     | 
| 
      
 502 
     | 
    
         
            +
                            self.service.stop()
         
     | 
| 
      
 503 
     | 
    
         
            +
                    with suppress(Exception):
         
     | 
| 
       491 
504 
     | 
    
         
             
                        if self.reactor and isinstance(self.reactor, Reactor):
         
     | 
| 
       492 
505 
     | 
    
         
             
                            logger.debug("Shutting down Reactor")
         
     | 
| 
       493 
506 
     | 
    
         
             
                            self.reactor.event.set()
         
     | 
| 
       494 
     | 
    
         
            -
                    except Exception:
         
     | 
| 
       495 
     | 
    
         
            -
                        pass
         
     | 
| 
       496 
507 
     | 
    
         
             
                    if (
         
     | 
| 
       497 
508 
     | 
    
         
             
                        hasattr(self, "keep_user_data_dir")
         
     | 
| 
       498 
509 
     | 
    
         
             
                        and hasattr(self, "user_data_dir")
         
     | 
| 
         @@ -521,18 +532,14 @@ class Chrome(selenium.webdriver.chrome.webdriver.WebDriver): 
     | 
|
| 
       521 
532 
     | 
    
         
             
                    self.patcher = None
         
     | 
| 
       522 
533 
     | 
    
         | 
| 
       523 
534 
     | 
    
         
             
                def __del__(self):
         
     | 
| 
       524 
     | 
    
         
            -
                     
     | 
| 
      
 535 
     | 
    
         
            +
                    with suppress(Exception):
         
     | 
| 
       525 
536 
     | 
    
         
             
                        if "win32" in sys.platform:
         
     | 
| 
       526 
537 
     | 
    
         
             
                            self.stop_client()
         
     | 
| 
       527 
538 
     | 
    
         
             
                            self.command_executor.close()
         
     | 
| 
       528 
539 
     | 
    
         
             
                        else:
         
     | 
| 
       529 
540 
     | 
    
         
             
                            super().quit()
         
     | 
| 
       530 
     | 
    
         
            -
                     
     | 
| 
       531 
     | 
    
         
            -
                        pass
         
     | 
| 
       532 
     | 
    
         
            -
                    try:
         
     | 
| 
      
 541 
     | 
    
         
            +
                    with suppress(Exception):
         
     | 
| 
       533 
542 
     | 
    
         
             
                        self.quit()
         
     | 
| 
       534 
     | 
    
         
            -
                    except Exception:
         
     | 
| 
       535 
     | 
    
         
            -
                        pass
         
     | 
| 
       536 
543 
     | 
    
         | 
| 
       537 
544 
     | 
    
         
             
                def __enter__(self):
         
     | 
| 
       538 
545 
     | 
    
         
             
                    return self
         
     | 
    
        seleniumbase/undetected/cdp.py
    CHANGED
    
    
| 
         @@ -0,0 +1 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            from seleniumbase.undetected.cdp_driver import cdp_util  # noqa
         
     | 
| 
         @@ -0,0 +1,110 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            import warnings as _warnings
         
     | 
| 
      
 2 
     | 
    
         
            +
            from collections.abc import Mapping as _Mapping, Sequence as _Sequence
         
     | 
| 
      
 3 
     | 
    
         
            +
            import logging
         
     | 
| 
      
 4 
     | 
    
         
            +
             
     | 
| 
      
 5 
     | 
    
         
            +
            __logger__ = logging.getLogger(__name__)
         
     | 
| 
      
 6 
     | 
    
         
            +
            __all__ = ["cdict", "ContraDict"]
         
     | 
| 
      
 7 
     | 
    
         
            +
             
     | 
| 
      
 8 
     | 
    
         
            +
             
     | 
| 
      
 9 
     | 
    
         
            +
            def cdict(*args, **kwargs):
         
     | 
| 
      
 10 
     | 
    
         
            +
                """Factory function"""
         
     | 
| 
      
 11 
     | 
    
         
            +
                return ContraDict(*args, **kwargs)
         
     | 
| 
      
 12 
     | 
    
         
            +
             
     | 
| 
      
 13 
     | 
    
         
            +
             
     | 
| 
      
 14 
     | 
    
         
            +
            class ContraDict(dict):
         
     | 
| 
      
 15 
     | 
    
         
            +
                """
         
     | 
| 
      
 16 
     | 
    
         
            +
                Directly inherited from dict.
         
     | 
| 
      
 17 
     | 
    
         
            +
                Accessible by attribute. o.x == o['x']
         
     | 
| 
      
 18 
     | 
    
         
            +
                This works also for all corner cases.
         
     | 
| 
      
 19 
     | 
    
         
            +
                Native json.dumps and json.loads work with it.
         
     | 
| 
      
 20 
     | 
    
         
            +
             
     | 
| 
      
 21 
     | 
    
         
            +
                Names like "keys", "update", "values" etc won't overwrite the methods,
         
     | 
| 
      
 22 
     | 
    
         
            +
                but will just be available using dict lookup notation obj['items']
         
     | 
| 
      
 23 
     | 
    
         
            +
                instead of obj.items.
         
     | 
| 
      
 24 
     | 
    
         
            +
             
     | 
| 
      
 25 
     | 
    
         
            +
                All key names are converted to snake_case.
         
     | 
| 
      
 26 
     | 
    
         
            +
                Hyphen's (-), dot's (.) or whitespaces are replaced by underscore (_).
         
     | 
| 
      
 27 
     | 
    
         
            +
                Autocomplete works even if the objects comes from a list.
         
     | 
| 
      
 28 
     | 
    
         
            +
                Recursive action. Dict assignments will be converted too.
         
     | 
| 
      
 29 
     | 
    
         
            +
                """
         
     | 
| 
      
 30 
     | 
    
         
            +
                __module__ = None
         
     | 
| 
      
 31 
     | 
    
         
            +
             
     | 
| 
      
 32 
     | 
    
         
            +
                def __init__(self, *args, **kwargs):
         
     | 
| 
      
 33 
     | 
    
         
            +
                    super().__init__()
         
     | 
| 
      
 34 
     | 
    
         
            +
                    # silent = kwargs.pop("silent", False)
         
     | 
| 
      
 35 
     | 
    
         
            +
                    _ = dict(*args, **kwargs)
         
     | 
| 
      
 36 
     | 
    
         
            +
             
     | 
| 
      
 37 
     | 
    
         
            +
                    super().__setattr__("__dict__", self)
         
     | 
| 
      
 38 
     | 
    
         
            +
                    for k, v in _.items():
         
     | 
| 
      
 39 
     | 
    
         
            +
                        _check_key(k, self, False, True)
         
     | 
| 
      
 40 
     | 
    
         
            +
                        super().__setitem__(k, _wrap(self.__class__, v))
         
     | 
| 
      
 41 
     | 
    
         
            +
             
     | 
| 
      
 42 
     | 
    
         
            +
                def __setitem__(self, key, value):
         
     | 
| 
      
 43 
     | 
    
         
            +
                    super().__setitem__(key, _wrap(self.__class__, value))
         
     | 
| 
      
 44 
     | 
    
         
            +
             
     | 
| 
      
 45 
     | 
    
         
            +
                def __setattr__(self, key, value):
         
     | 
| 
      
 46 
     | 
    
         
            +
                    super().__setitem__(key, _wrap(self.__class__, value))
         
     | 
| 
      
 47 
     | 
    
         
            +
             
     | 
| 
      
 48 
     | 
    
         
            +
                def __getattribute__(self, attribute):
         
     | 
| 
      
 49 
     | 
    
         
            +
                    if attribute in self:
         
     | 
| 
      
 50 
     | 
    
         
            +
                        return self[attribute]
         
     | 
| 
      
 51 
     | 
    
         
            +
                    if not _check_key(attribute, self, True, silent=True):
         
     | 
| 
      
 52 
     | 
    
         
            +
                        return getattr(super(), attribute)
         
     | 
| 
      
 53 
     | 
    
         
            +
                    return object.__getattribute__(self, attribute)
         
     | 
| 
      
 54 
     | 
    
         
            +
             
     | 
| 
      
 55 
     | 
    
         
            +
             
     | 
| 
      
 56 
     | 
    
         
            +
            def _wrap(cls, v):
         
     | 
| 
      
 57 
     | 
    
         
            +
                if isinstance(v, _Mapping):
         
     | 
| 
      
 58 
     | 
    
         
            +
                    v = cls(v)
         
     | 
| 
      
 59 
     | 
    
         
            +
                elif isinstance(v, _Sequence) and not isinstance(
         
     | 
| 
      
 60 
     | 
    
         
            +
                    v, (str, bytes, bytearray, set, tuple)
         
     | 
| 
      
 61 
     | 
    
         
            +
                ):
         
     | 
| 
      
 62 
     | 
    
         
            +
                    v = list([_wrap(cls, x) for x in v])
         
     | 
| 
      
 63 
     | 
    
         
            +
                return v
         
     | 
| 
      
 64 
     | 
    
         
            +
             
     | 
| 
      
 65 
     | 
    
         
            +
             
     | 
| 
      
 66 
     | 
    
         
            +
            _warning_names = (
         
     | 
| 
      
 67 
     | 
    
         
            +
                "items",
         
     | 
| 
      
 68 
     | 
    
         
            +
                "keys",
         
     | 
| 
      
 69 
     | 
    
         
            +
                "values",
         
     | 
| 
      
 70 
     | 
    
         
            +
                "update",
         
     | 
| 
      
 71 
     | 
    
         
            +
                "clear",
         
     | 
| 
      
 72 
     | 
    
         
            +
                "copy",
         
     | 
| 
      
 73 
     | 
    
         
            +
                "fromkeys",
         
     | 
| 
      
 74 
     | 
    
         
            +
                "get",
         
     | 
| 
      
 75 
     | 
    
         
            +
                "items",
         
     | 
| 
      
 76 
     | 
    
         
            +
                "keys",
         
     | 
| 
      
 77 
     | 
    
         
            +
                "pop",
         
     | 
| 
      
 78 
     | 
    
         
            +
                "popitem",
         
     | 
| 
      
 79 
     | 
    
         
            +
                "setdefault",
         
     | 
| 
      
 80 
     | 
    
         
            +
                "update",
         
     | 
| 
      
 81 
     | 
    
         
            +
                "values",
         
     | 
| 
      
 82 
     | 
    
         
            +
                "class",
         
     | 
| 
      
 83 
     | 
    
         
            +
            )
         
     | 
| 
      
 84 
     | 
    
         
            +
             
     | 
| 
      
 85 
     | 
    
         
            +
            _warning_names_message = """\n\
         
     | 
| 
      
 86 
     | 
    
         
            +
                While creating a ContraDict object, a key offending key name '{0}'
         
     | 
| 
      
 87 
     | 
    
         
            +
                has been found, which might behave unexpected.
         
     | 
| 
      
 88 
     | 
    
         
            +
                You will only be able to look it up using key,
         
     | 
| 
      
 89 
     | 
    
         
            +
                eg. myobject['{0}']. myobject.{0} will not work with that name."""
         
     | 
| 
      
 90 
     | 
    
         
            +
             
     | 
| 
      
 91 
     | 
    
         
            +
             
     | 
| 
      
 92 
     | 
    
         
            +
            def _check_key(
         
     | 
| 
      
 93 
     | 
    
         
            +
                key: str, mapping: _Mapping, boolean: bool = False, silent=True
         
     | 
| 
      
 94 
     | 
    
         
            +
            ):
         
     | 
| 
      
 95 
     | 
    
         
            +
                """Checks `key` and warns if needed.
         
     | 
| 
      
 96 
     | 
    
         
            +
                :param key:
         
     | 
| 
      
 97 
     | 
    
         
            +
                :param boolean: return True or False instead of passthrough
         
     | 
| 
      
 98 
     | 
    
         
            +
                """
         
     | 
| 
      
 99 
     | 
    
         
            +
                e = None
         
     | 
| 
      
 100 
     | 
    
         
            +
                if not isinstance(key, (str,)):
         
     | 
| 
      
 101 
     | 
    
         
            +
                    if boolean:
         
     | 
| 
      
 102 
     | 
    
         
            +
                        return True
         
     | 
| 
      
 103 
     | 
    
         
            +
                    return key
         
     | 
| 
      
 104 
     | 
    
         
            +
                if key.lower() in _warning_names or any(_ in key for _ in ("-", ".")):
         
     | 
| 
      
 105 
     | 
    
         
            +
                    if not silent:
         
     | 
| 
      
 106 
     | 
    
         
            +
                        _warnings.warn(_warning_names_message.format(key))
         
     | 
| 
      
 107 
     | 
    
         
            +
                    e = True
         
     | 
| 
      
 108 
     | 
    
         
            +
                if not boolean:
         
     | 
| 
      
 109 
     | 
    
         
            +
                    return key
         
     | 
| 
      
 110 
     | 
    
         
            +
                return not e
         
     |