diff --git a/README.md b/README.md index 6312b683ec9..82f0841910e 100755 --- a/README.md +++ b/README.md @@ -653,8 +653,9 @@ pytest test_coffee_cart.py --trace --sjw # (Skip JS Waits for readyState to be "complete" or Angular to load.) --wfa # (Wait for AngularJS to be done loading after specific web actions.) --pls=PLS # (Set pageLoadStrategy on Chrome: "normal", "eager", or "none".) ---headless # (Run tests in headless mode. The default arg on Linux OS.) ---headless2 # (Use the new headless mode, which supports extensions.) +--headless # (The default headless mode. Linux uses this mode by default.) +--headless1 # (Use Chrome's old headless mode. Fast, but has limitations.) +--headless2 # (Use Chrome's new headless mode, which supports extensions.) --headed # (Run tests in headed/GUI mode on Linux OS, where not default.) --xvfb # (Run tests using the Xvfb virtual display server on Linux OS.) --xvfb-metrics=STRING # (Set Xvfb display size on Linux: "Width,Height".) diff --git a/examples/handle_alert_test.py b/examples/handle_alert_test.py index 780841c81d1..c7eed9b8cb9 100644 --- a/examples/handle_alert_test.py +++ b/examples/handle_alert_test.py @@ -7,6 +7,7 @@ def test_alerts(self): self.open("about:blank") self.execute_script('window.alert("ALERT!!!");') self.sleep(1) # Not needed (Lets you see the alert pop up) + self.assert_true(self.is_alert_present()) self.accept_alert() self.sleep(1) # Not needed (Lets you see the alert go away) self.execute_script('window.prompt("My Prompt","defaultText");') @@ -15,6 +16,7 @@ def test_alerts(self): self.assert_equal(alert.text, "My Prompt") # Not input field self.dismiss_alert() self.sleep(1) # Not needed (Lets you see the alert go away) + self.assert_false(self.is_alert_present()) if self.browser == "safari" and self._reuse_session: # Alerts can freeze Safari if reusing the browser session self.driver.quit() diff --git a/help_docs/customizing_test_runs.md b/help_docs/customizing_test_runs.md index 8566d968346..a7918d3e79f 100644 --- a/help_docs/customizing_test_runs.md +++ b/help_docs/customizing_test_runs.md @@ -144,8 +144,9 @@ pytest my_first_test.py --settings-file=custom_settings.py --sjw # (Skip JS Waits for readyState to be "complete" or Angular to load.) --wfa # (Wait for AngularJS to be done loading after specific web actions.) --pls=PLS # (Set pageLoadStrategy on Chrome: "normal", "eager", or "none".) ---headless # (Run tests in headless mode. The default arg on Linux OS.) ---headless2 # (Use the new headless mode, which supports extensions.) +--headless # (The default headless mode. Linux uses this mode by default.) +--headless1 # (Use Chrome's old headless mode. Fast, but has limitations.) +--headless2 # (Use Chrome's new headless mode, which supports extensions.) --headed # (Run tests in headed/GUI mode on Linux OS, where not default.) --xvfb # (Run tests using the Xvfb virtual display server on Linux OS.) --xvfb-metrics=STRING # (Set Xvfb display size on Linux: "Width,Height".) diff --git a/help_docs/method_summary.md b/help_docs/method_summary.md index b99dea1e743..cc932c471c7 100644 --- a/help_docs/method_summary.md +++ b/help_docs/method_summary.md @@ -550,6 +550,8 @@ self.inspect_html() self.is_valid_url(url) +self.is_alert_present() + self.is_online() self.is_chromium() diff --git a/mkdocs_build/requirements.txt b/mkdocs_build/requirements.txt index bb862790a7b..cbb5e00d1ab 100644 --- a/mkdocs_build/requirements.txt +++ b/mkdocs_build/requirements.txt @@ -20,7 +20,7 @@ lxml==5.3.0 pyquery==2.0.1 readtime==3.0.0 mkdocs==1.6.1 -mkdocs-material==9.5.36 +mkdocs-material==9.5.37 mkdocs-exclude-search==0.6.6 mkdocs-simple-hooks==0.1.5 mkdocs-material-extensions==1.3.1 diff --git a/seleniumbase/__version__.py b/seleniumbase/__version__.py index 429f6b81506..8881df4afa8 100755 --- a/seleniumbase/__version__.py +++ b/seleniumbase/__version__.py @@ -1,2 +1,2 @@ # seleniumbase package -__version__ = "4.31.0" +__version__ = "4.31.1" diff --git a/seleniumbase/behave/behave_sb.py b/seleniumbase/behave/behave_sb.py index 17609334fcc..8f95950a989 100644 --- a/seleniumbase/behave/behave_sb.py +++ b/seleniumbase/behave/behave_sb.py @@ -44,8 +44,9 @@ -D sjw (Skip JS Waits for readyState to be "complete" or Angular to load.) -D wfa (Wait for AngularJS to be done loading after specific web actions.) -D pls=PLS (Set pageLoadStrategy on Chrome: "normal", "eager", or "none".) --D headless (Run tests in headless mode. The default arg on Linux OS.) --D headless2 (Use the new headless mode, which supports extensions.) +-D headless (The default headless mode. Linux uses this mode by default.) +-D headless1 (Use Chrome's old headless mode. Fast, but has limitations.) +-D headless2 (Use Chrome's new headless mode, which supports extensions.) -D headed (Run tests in headed/GUI mode on Linux OS, where not default.) -D xvfb (Run tests using the Xvfb virtual display server on Linux OS.) -D xvfb-metrics=STRING (Set Xvfb display size on Linux: "Width,Height".) @@ -144,6 +145,7 @@ def get_configured_sb(context): sb.browser = "chrome" sb.is_behave = True sb.headless = False + sb.headless1 = False sb.headless2 = False sb.headless_active = False sb.headed = False @@ -296,6 +298,11 @@ def get_configured_sb(context): sb.headless = True continue # Handle: -D headless2 + if low_key == "headless1": + sb.headless1 = True + sb.headless = True + continue + # Handle: -D headless2 if low_key == "headless2": sb.headless2 = True continue @@ -864,6 +871,7 @@ def get_configured_sb(context): # Recorder Mode can still optimize scripts in "-D headless2" mode. if sb.recorder_ext and sb.headless: sb.headless = False + sb.headless1 = False sb.headless2 = True if sb.headless2 and sb.browser == "firefox": sb.headless2 = False # Only for Chromium browsers @@ -900,11 +908,13 @@ def get_configured_sb(context): # Recorder Mode can still optimize scripts in --headless2 mode. if sb.recorder_mode and sb.headless: sb.headless = False + sb.headless1 = False sb.headless2 = True if not sb.headless and not sb.headless2: sb.headed = True if sb.browser == "safari" and sb.headless: sb.headless = False # Safari doesn't support headless mode + sb.headless1 = False if sb.save_screenshot_after_test and sb.no_screenshot_after_test: sb.save_screenshot_after_test = False # "no_screenshot" has priority if sb.servername != "localhost": diff --git a/seleniumbase/console_scripts/logo_helper.py b/seleniumbase/console_scripts/logo_helper.py index fcef74af242..a9d053d666e 100644 --- a/seleniumbase/console_scripts/logo_helper.py +++ b/seleniumbase/console_scripts/logo_helper.py @@ -3,7 +3,9 @@ http://www.patorjk.com/software/taag/#p=display&f=Slant&t=SeleniumBase """ import colorama +import os import sys +from contextlib import suppress r""" ______ __ _ ____ @@ -66,4 +68,49 @@ def get_seleniumbase_logo(): sb += " " sb += cr sb += cr + with suppress(Exception): + terminal_width = os.get_terminal_size().columns + if isinstance(terminal_width, int) and terminal_width >= 66: + return sb + + # If the logo is wider than the screen width, use a smaller one: + r""" + ___ _ _ ___ + / __| ___| |___ _ _ (_)_ _ _ __ | _ ) __ _ ______ + \__ \/ -_) / -_) ' \| | \| | ' \ | _ \/ _` (_-< -_) + |___/\___|_\___|_||_|_|\_,_|_|_|_\|___/\__,_/__|___| + """ + sb = " " + sb += cr + sb += "\n" + sb += c1 + sb += " ___ _ _ " + sb += c2 + sb += " ___ " + sb += cr + sb += "\n" + sb += c1 + sb += "/ __| ___| |___ _ _ (_)_ _ _ __ " + sb += c2 + sb += "| _ ) __ _ ______ " + sb += cr + sb += "\n" + sb += c1 + sb += "\\__ \\/ -_) / -_) ' \\| | \\| | ' \\ " + sb += c2 + sb += "| _ \\/ _` (_-< -_)" + sb += cr + sb += "\n" + sb += c1 + sb += "|___/\\___|_\\___|_||_|_|\\_,_|_|_|_\\" + sb += c2 + sb += "|___/\\__,_/__|___|" + sb += cr + sb += "\n" + sb += c3 + sb += " " + sb += c4 + sb += " " + sb += cr + sb += cr return sb diff --git a/seleniumbase/console_scripts/run.py b/seleniumbase/console_scripts/run.py index 870a30616c5..7f62f7cdd2c 100644 --- a/seleniumbase/console_scripts/run.py +++ b/seleniumbase/console_scripts/run.py @@ -54,8 +54,8 @@ def show_usage(): show_basic_usage() sc = "" - sc += ' Type "sbase help [COMMAND]" for specific command info.\n' - sc += ' For info on all commands, type: "seleniumbase --help".\n' + sc += ' Type "sbase help [COMMAND]" for specific info.\n' + sc += ' For all commands, type: "seleniumbase --help".\n' sc += ' Use "pytest" for running tests.\n' if "linux" not in sys.platform: c1 = colorama.Fore.BLUE + colorama.Back.LIGHTCYAN_EX @@ -76,12 +76,15 @@ def show_basic_usage(): seleniumbase_logo = logo_helper.get_seleniumbase_logo() print(seleniumbase_logo) + time.sleep(0.044) print("") - time.sleep(0.28) # Enough time to see the logo + time.sleep(0.033) show_package_location() + time.sleep(0.032) show_version_info() + time.sleep(0.031) print("") - time.sleep(0.62) # Enough time to see the version + time.sleep(0.68) # Enough time to see the logo & version sc = "" sc += ' * USAGE: "seleniumbase [COMMAND] [PARAMETERS]"\n' sc += ' * OR: "sbase [COMMAND] [PARAMETERS]"\n' diff --git a/seleniumbase/core/browser_launcher.py b/seleniumbase/core/browser_launcher.py index 03845961959..6af8df48729 100644 --- a/seleniumbase/core/browser_launcher.py +++ b/seleniumbase/core/browser_launcher.py @@ -203,6 +203,8 @@ def extend_driver(driver): driver.is_exact_text_visible = DM.is_exact_text_visible driver.is_attribute_present = DM.is_attribute_present driver.is_non_empty_text_visible = DM.is_non_empty_text_visible + driver.is_valid_url = DM.is_valid_url + driver.is_alert_present = DM.is_alert_present driver.is_online = DM.is_online driver.js_click = DM.js_click driver.get_text = DM.get_text @@ -1553,6 +1555,7 @@ def _set_chrome_options( log_cdp_events, no_sandbox, disable_gpu, + headless1, headless2, incognito, guest_mode, @@ -1771,7 +1774,10 @@ def _set_chrome_options( pass # Processed After Version Check elif headless: if not undetectable: - chrome_options.add_argument("--headless") + if headless1: + chrome_options.add_argument("--headless=old") + else: + chrome_options.add_argument("--headless") if undetectable and servername and servername != "localhost": # The Grid Node will need Chrome 109 or newer chrome_options.add_argument("--headless=new") @@ -2193,6 +2199,7 @@ def get_driver( log_cdp_events=False, no_sandbox=False, disable_gpu=False, + headless1=False, headless2=False, incognito=False, guest_mode=False, @@ -2406,6 +2413,7 @@ def get_driver( log_cdp_events, no_sandbox, disable_gpu, + headless1, headless2, incognito, guest_mode, @@ -2462,6 +2470,7 @@ def get_driver( log_cdp_events, no_sandbox, disable_gpu, + headless1, headless2, incognito, guest_mode, @@ -2522,6 +2531,7 @@ def get_remote_driver( log_cdp_events, no_sandbox, disable_gpu, + headless1, headless2, incognito, guest_mode, @@ -2657,6 +2667,7 @@ def get_remote_driver( log_cdp_events, no_sandbox, disable_gpu, + headless1, headless2, incognito, guest_mode, @@ -2829,6 +2840,7 @@ def get_remote_driver( log_cdp_events, no_sandbox, disable_gpu, + headless1, headless2, incognito, guest_mode, @@ -2948,6 +2960,7 @@ def get_local_driver( log_cdp_events, no_sandbox, disable_gpu, + headless1, headless2, incognito, guest_mode, @@ -3425,8 +3438,14 @@ def get_local_driver( else: pass # Will need Xvfb on Linux elif headless: - if "--headless" not in edge_options.arguments: - edge_options.add_argument("--headless") + if ( + "--headless" not in edge_options.arguments + and "--headless=old" not in edge_options.arguments + ): + if headless1: + edge_options.add_argument("--headless=old") + else: + edge_options.add_argument("--headless") if mobile_emulator and not is_using_uc(undetectable, browser_name): emulator_settings = {} device_metrics = {} @@ -3788,6 +3807,7 @@ def get_local_driver( log_cdp_events, no_sandbox, disable_gpu, + headless1, headless2, incognito, guest_mode, @@ -3960,8 +3980,14 @@ def get_local_driver( except Exception: pass # Will need Xvfb on Linux elif headless: - if "--headless" not in chrome_options.arguments: - chrome_options.add_argument("--headless") + if ( + "--headless" not in chrome_options.arguments + and "--headless=old" not in chrome_options.arguments + ): + if headless1: + chrome_options.add_argument("--headless=old") + else: + chrome_options.add_argument("--headless") if LOCAL_CHROMEDRIVER and os.path.exists(LOCAL_CHROMEDRIVER): try: make_driver_executable_if_not(LOCAL_CHROMEDRIVER) @@ -4227,6 +4253,12 @@ def get_local_driver( chrome_options.arguments.remove( "--headless" ) + if "--headless=old" in ( + chrome_options.arguments + ): + chrome_options.arguments.remove( + "--headless=old" + ) uc_chrome_version = None if ( use_version.isnumeric() @@ -4300,6 +4332,7 @@ def get_local_driver( False, # log_cdp_events no_sandbox, disable_gpu, + False, # headless1 False, # headless2 incognito, guest_mode, @@ -4541,6 +4574,7 @@ def get_local_driver( False, # log_cdp_events no_sandbox, disable_gpu, + False, # headless1 False, # headless2 incognito, guest_mode, @@ -4792,6 +4826,8 @@ def get_local_driver( ) if "--headless" in chrome_options.arguments: chrome_options.arguments.remove("--headless") + if "--headless=old" in chrome_options.arguments: + chrome_options.arguments.remove("--headless=old") service = ChromeService( log_output=os.devnull, service_args=["--disable-build-check"] diff --git a/seleniumbase/core/sb_driver.py b/seleniumbase/core/sb_driver.py index 02dd0de4ab0..6fc9dea1730 100644 --- a/seleniumbase/core/sb_driver.py +++ b/seleniumbase/core/sb_driver.py @@ -161,6 +161,17 @@ def is_non_empty_text_visible(self, *args, **kwargs): self.driver, *args, **kwargs ) + def is_valid_url(self, url): + """Return True if the url is a valid url.""" + return page_utils.is_valid_url(url) + + def is_alert_present(self): + try: + self.driver.switch_to.alert + return True + except Exception: + return False + def is_online(self): return self.driver.execute_script("return navigator.onLine;") diff --git a/seleniumbase/fixtures/base_case.py b/seleniumbase/fixtures/base_case.py index e8a81c4a002..e3ef884946b 100644 --- a/seleniumbase/fixtures/base_case.py +++ b/seleniumbase/fixtures/base_case.py @@ -3771,6 +3771,7 @@ def get_new_driver( log_cdp_events=None, no_sandbox=None, disable_gpu=None, + headless1=None, headless2=None, incognito=None, guest_mode=None, @@ -3830,6 +3831,7 @@ def get_new_driver( log_cdp_events - capture {"performance": "ALL", "browser": "ALL"}) no_sandbox - the option to enable the "No-Sandbox" feature (Chrome) disable_gpu - the option to enable Chrome's "Disable GPU" feature + headless1 - the option to use the older headless mode (Chromium) headless2 - the option to use the newer headless mode (Chromium) incognito - the option to enable Chrome's Incognito mode (Chrome) guest_mode - the option to enable Chrome's Guest mode (Chrome) @@ -3938,6 +3940,8 @@ def get_new_driver( no_sandbox = self.no_sandbox if disable_gpu is None: disable_gpu = self.disable_gpu + if headless1 is None: + headless1 = self.headless1 if headless2 is None: headless2 = self.headless2 if incognito is None: @@ -4036,6 +4040,7 @@ def get_new_driver( log_cdp_events=log_cdp_events, no_sandbox=no_sandbox, disable_gpu=disable_gpu, + headless1=headless1, headless2=headless2, incognito=incognito, guest_mode=guest_mode, @@ -7808,6 +7813,13 @@ def is_valid_url(self, url): """Return True if the url is a valid url.""" return page_utils.is_valid_url(url) + def is_alert_present(self): + try: + self.driver.switch_to.alert + return True + except Exception: + return False + def is_online(self): """Return True if connected to the Internet.""" return self.execute_script("return navigator.onLine;") @@ -14324,6 +14336,10 @@ def setUp(self, masterqa_mode=False): self.env = self.environment # Add a shortened version self.with_selenium = sb_config.with_selenium # Should be True self.headless = sb_config.headless + self.headless1 = sb_config.headless1 + if self.headless1: + self.headless = True + self.headless2 = sb_config.headless2 self.headless_active = False sb_config.headless_active = False self.headed = sb_config.headed @@ -14392,7 +14408,6 @@ def setUp(self, masterqa_mode=False): self.log_cdp_events = sb_config.log_cdp_events self.no_sandbox = sb_config.no_sandbox self.disable_gpu = sb_config.disable_gpu - self.headless2 = sb_config.headless2 self.incognito = sb_config.incognito self.guest_mode = sb_config.guest_mode self.dark_mode = sb_config.dark_mode @@ -14768,6 +14783,7 @@ def setUp(self, masterqa_mode=False): log_cdp_events=self.log_cdp_events, no_sandbox=self.no_sandbox, disable_gpu=self.disable_gpu, + headless1=self.headless1, headless2=self.headless2, incognito=self.incognito, guest_mode=self.guest_mode, diff --git a/seleniumbase/fixtures/page_utils.py b/seleniumbase/fixtures/page_utils.py index ae02add9c76..abae8feeee4 100644 --- a/seleniumbase/fixtures/page_utils.py +++ b/seleniumbase/fixtures/page_utils.py @@ -163,12 +163,15 @@ def is_valid_url(url): r"(?:/?|[/?]\S+)$", re.IGNORECASE, ) - return ( + if ( regex.match(url) or url.startswith(( "about:", "blob:", "chrome:", "data:", "edge:", "file:" )) - ) + ): + return True + else: + return False def _get_unique_links(page_url, soup): diff --git a/seleniumbase/plugins/driver_manager.py b/seleniumbase/plugins/driver_manager.py index a3f19e5a48e..982acfc3633 100644 --- a/seleniumbase/plugins/driver_manager.py +++ b/seleniumbase/plugins/driver_manager.py @@ -65,8 +65,9 @@ def __exit__(self, exc_type, exc_val, exc_tb): def Driver( browser=None, # Choose from "chrome", "edge", "firefox", or "safari". - headless=None, # The original headless mode for Chromium and Firefox. - headless2=None, # Chromium's new headless mode. (Has more features) + headless=None, # Use the default headless mode for Chromium and Firefox. + headless1=None, # Use Chromium's old headless mode. (Fast, but limited) + headless2=None, # Use Chromium's new headless mode. (Has more features) headed=None, # Run tests in headed/GUI mode on Linux, where not default. locale_code=None, # Set the Language Locale Code for the web browser. protocol=None, # The Selenium Grid protocol: "http" or "https". @@ -154,74 +155,75 @@ def Driver( Optional Parameters: -------------------- - browser: # Choose from "chrome", "edge", "firefox", or "safari". - headless: # The original headless mode for Chromium and Firefox. - headless2: # Chromium's new headless mode. (Has more features) - headed: # Run tests in headed/GUI mode on Linux, where not default. - locale_code: # Set the Language Locale Code for the web browser. - protocol: # The Selenium Grid protocol: "http" or "https". - servername: # The Selenium Grid server/IP used for tests. - port: # The Selenium Grid port used by the test server. - proxy: # Use proxy. Format: "SERVER:PORT" or "USER:PASS@SERVER:PORT". - proxy_bypass_list: # Skip proxy when using the listed domains. - proxy_pac_url: # Use PAC file. (Format: URL or USERNAME:PASSWORD@URL) - multi_proxy: # Allow multiple proxies with auth when multi-threaded. - agent: # Modify the web browser's User-Agent string. - cap_file: # The desired capabilities to use with a Selenium Grid. - cap_string: # The desired capabilities to use with a Selenium Grid. - recorder_ext: # Enables the SeleniumBase Recorder Chromium extension. - disable_js: # Disable JavaScript on websites. Pages might break! - disable_csp: # Disable the Content Security Policy of websites. - enable_ws: # Enable Web Security on Chromium-based browsers. - disable_ws: # Reverse of "enable_ws". (None and False are different) - enable_sync: # Enable "Chrome Sync" on websites. - use_auto_ext: # Use Chrome's automation extension. - undetectable: # Use undetected-chromedriver to evade bot-detection. - uc_cdp_events: # Capture CDP events in undetected-chromedriver mode. - uc_subprocess: # Use undetected-chromedriver as a subprocess. - log_cdp_events: # Capture {"performance": "ALL", "browser": "ALL"} - no_sandbox: # (DEPRECATED) - "--no-sandbox" is always used now. - disable_gpu: # (DEPRECATED) - GPU is disabled if not "swiftshader". - incognito: # Enable Chromium's Incognito mode. - guest_mode: # Enable Chromium's Guest mode. - dark_mode: # Enable Chromium's Dark mode. - devtools: # Open Chromium's DevTools when the browser opens. - remote_debug: # Enable Chrome's Debugger on "http://localhost:9222". - enable_3d_apis: # Enable WebGL and 3D APIs. - swiftshader: # Chrome: --use-gl=angle / --use-angle=swiftshader-webgl - ad_block_on: # Block some types of display ads from loading. - host_resolver_rules: # Set host-resolver-rules, comma-separated. - block_images: # Block images from loading during tests. - do_not_track: # Tell websites that you don't want to be tracked. - chromium_arg: # "ARG=N,ARG2" (Set Chromium args, ","-separated.) - firefox_arg: # "ARG=N,ARG2" (Set Firefox args, comma-separated.) - firefox_pref: # SET (Set Firefox PREFERENCE:VALUE set, ","-separated) - user_data_dir: # Set the Chrome user data directory to use. - extension_zip: # Load a Chrome Extension .zip|.crx, comma-separated. - extension_dir: # Load a Chrome Extension directory, comma-separated. - disable_features: # "F1,F2" (Disable Chrome features, ","-separated.) - binary_location: # Set path of the Chromium browser binary to use. - driver_version: # Set the chromedriver or uc_driver version to use. - page_load_strategy: # Set Chrome PLS to "normal", "eager", or "none". - use_wire: # Use selenium-wire's webdriver over selenium webdriver. - external_pdf: # Set Chrome "plugins.always_open_pdf_externally":True. - window_position: # Set the browser's starting window position: "X,Y" - window_size: # Set the browser's starting window size: "Width,Height" - is_mobile: # Use the mobile device emulator while running tests. - mobile: # Shortcut / Duplicate of "is_mobile". - d_width: # Set device width - d_height: # Set device height - d_p_r: # Set device pixel ratio - uc: # Shortcut / Duplicate of "undetectable". - undetected: # Shortcut / Duplicate of "undetectable". - uc_cdp: # Shortcut / Duplicate of "uc_cdp_events". - uc_sub: # Shortcut / Duplicate of "uc_subprocess". - log_cdp: # Shortcut / Duplicate of "log_cdp_events". - ad_block: # Shortcut / Duplicate of "ad_block_on". - server: # Shortcut / Duplicate of "servername". - guest: # Shortcut / Duplicate of "guest_mode". - wire: # Shortcut / Duplicate of "use_wire". - pls: # Shortcut / Duplicate of "page_load_strategy". + browser (str): Choose from "chrome", "edge", "firefox", or "safari". + headless (bool): Use the default headless mode for Chromium and Firefox. + headless1 (bool): Use Chromium's old headless mode. (Fast, but limited) + headless2 (bool): Use Chromium's new headless mode. (Has more features) + headed (bool): Run tests in headed/GUI mode on Linux, where not default. + locale_code (str): Set the Language Locale Code for the web browser. + protocol (str): The Selenium Grid protocol: "http" or "https". + servername (str): The Selenium Grid server/IP used for tests. + port (int): The Selenium Grid port used by the test server. + proxy (str): Use proxy. Format: "SERVER:PORT" or "USER:PASS@SERVER:PORT". + proxy_bypass_list (str): Skip proxy when using the listed domains. + proxy_pac_url (str): Use PAC file. (Format: URL or USERNAME:PASSWORD@URL) + multi_proxy (bool): Allow multiple proxies with auth when multi-threaded. + agent (str): Modify the web browser's User-Agent string. + cap_file (str): The desired capabilities to use with a Selenium Grid. + cap_string (str): The desired capabilities to use with a Selenium Grid. + recorder_ext (bool): Enables the SeleniumBase Recorder Chromium extension. + disable_js (bool): Disable JavaScript on websites. Pages might break! + disable_csp (bool): Disable the Content Security Policy of websites. + enable_ws (bool): Enable Web Security on Chromium-based browsers. + disable_ws (bool): Reverse of "enable_ws". (None and False are different) + enable_sync (bool): Enable "Chrome Sync" on websites. + use_auto_ext (bool): Use Chrome's automation extension. + undetectable (bool): Use undetected-chromedriver to evade bot-detection. + uc_cdp_events (bool): Capture CDP events in undetected-chromedriver mode. + uc_subprocess (bool): Use undetected-chromedriver as a subprocess. + log_cdp_events (bool): Capture {"performance": "ALL", "browser": "ALL"} + no_sandbox (bool): (DEPRECATED) - "--no-sandbox" is always used now. + disable_gpu (bool): (DEPRECATED) - GPU is disabled if not "swiftshader". + incognito (bool): Enable Chromium's Incognito mode. + guest_mode (bool): Enable Chromium's Guest mode. + dark_mode (bool): Enable Chromium's Dark mode. + devtools (bool): Open Chromium's DevTools when the browser opens. + remote_debug (bool): Enable Chrome's Debugger on "http://localhost:9222". + enable_3d_apis (bool): Enable WebGL and 3D APIs. + swiftshader (bool): Chrome: --use-gl=angle / --use-angle=swiftshader-webgl + ad_block_on (bool): Block some types of display ads from loading. + host_resolver_rules (str): Set host-resolver-rules, comma-separated. + block_images (bool): Block images from loading during tests. + do_not_track (bool): Tell websites that you don't want to be tracked. + chromium_arg (str): "ARG=N,ARG2" (Set Chromium args, ","-separated.) + firefox_arg (str): "ARG=N,ARG2" (Set Firefox args, comma-separated.) + firefox_pref (str): SET (Set Firefox PREFERENCE:VALUE set, ","-separated) + user_data_dir (str): Set the Chrome user data directory to use. + extension_zip (str): Load a Chrome Extension .zip|.crx, comma-separated. + extension_dir (str): Load a Chrome Extension directory, comma-separated. + disable_features (str): "F1,F2" (Disable Chrome features, ","-separated.) + binary_location (str): Set path of the Chromium browser binary to use. + driver_version (str): Set the chromedriver or uc_driver version to use. + page_load_strategy (str): Set Chrome PLS to "normal", "eager", or "none". + use_wire (bool): Use selenium-wire's webdriver over selenium webdriver. + external_pdf (bool): Set Chrome "plugins.always_open_pdf_externally":True + window_position (x,y): Set the browser's starting window position: "X,Y" + window_size (w,h): Set the browser's starting window size: "Width,Height" + is_mobile (bool): Use the mobile device emulator while running tests. + mobile (bool): Shortcut / Duplicate of "is_mobile". + d_width (int): Set device width + d_height (int): Set device height + d_p_r (float): Set device pixel ratio + uc (bool): Shortcut / Duplicate of "undetectable". + undetected (bool): Shortcut / Duplicate of "undetectable". + uc_cdp (bool): Shortcut / Duplicate of "uc_cdp_events". + uc_sub (bool): Shortcut / Duplicate of "uc_subprocess". + log_cdp (bool): Shortcut / Duplicate of "log_cdp_events". + ad_block (bool): Shortcut / Duplicate of "ad_block_on". + server (str): Shortcut / Duplicate of "servername". + guest (bool): Shortcut / Duplicate of "guest_mode". + wire (bool): Shortcut / Duplicate of "use_wire". + pls (str): Shortcut / Duplicate of "page_load_strategy". """ from seleniumbase import config as sb_config from seleniumbase.config import settings @@ -336,6 +338,13 @@ def Driver( headless = True else: headless = False + if headless1 is None: + if "--headless1" in sys_argv: + headless1 = True + else: + headless1 = False + if headless1: + headless = True if headless2 is None: if "--headless2" in sys_argv: headless2 = True @@ -601,6 +610,7 @@ def Driver( headless = True if recorder_mode and headless: headless = False + headless1 = False headless2 = True if headless2 and browser == "firefox": headless2 = False # Only for Chromium browsers @@ -773,6 +783,7 @@ def Driver( log_cdp_events=log_cdp_events, no_sandbox=no_sandbox, disable_gpu=disable_gpu, + headless1=headless1, headless2=headless2, incognito=incognito, guest_mode=guest_mode, diff --git a/seleniumbase/plugins/pytest_plugin.py b/seleniumbase/plugins/pytest_plugin.py index 16de9d68010..99e195d14ac 100644 --- a/seleniumbase/plugins/pytest_plugin.py +++ b/seleniumbase/plugins/pytest_plugin.py @@ -62,8 +62,9 @@ def pytest_addoption(parser): --sjw (Skip JS Waits for readyState to be "complete" or Angular to load.) --wfa (Wait for AngularJS to be done loading after specific web actions.) --pls=PLS (Set pageLoadStrategy on Chrome: "normal", "eager", or "none".) - --headless (Run tests in headless mode. The default arg on Linux OS.) - --headless2 (Use the new headless mode, which supports extensions.) + --headless (The default headless mode. Linux uses this mode by default.) + --headless1 (Use Chrome's old headless mode. Fast, but has limitations.) + --headless2 (Use Chrome's new headless mode, which supports extensions.) --headed (Run tests in headed/GUI mode on Linux OS, where not default.) --xvfb (Run tests using the Xvfb virtual display server on Linux OS.) --xvfb-metrics=STRING (Set Xvfb display size on Linux: "Width,Height".) @@ -700,6 +701,15 @@ def pytest_addoption(parser): UNLESS using a virtual display with Xvfb. Default: False on Mac/Windows. True on Linux.""", ) + parser.addoption( + "--headless1", + action="store_true", + dest="headless1", + default=False, + help="""This option activates the old headless mode, + which is faster, but has limitations. + (May be phased out by Chrome in the future.)""", + ) parser.addoption( "--headless2", action="store_true", @@ -1533,6 +1543,9 @@ def pytest_configure(config): sb_config.mobile_emulator = config.getoption("mobile_emulator") sb_config.device_metrics = config.getoption("device_metrics") sb_config.headless = config.getoption("headless") + sb_config.headless1 = config.getoption("headless1") + if sb_config.headless1: + sb_config.headless = True sb_config.headless2 = config.getoption("headless2") if sb_config.headless2 and sb_config.browser == "firefox": sb_config.headless2 = False # Only for Chromium browsers @@ -1759,6 +1772,7 @@ def pytest_configure(config): # Recorder Mode can still optimize scripts in --headless2 mode. if sb_config.recorder_mode and sb_config.headless: sb_config.headless = False + sb_config.headless1 = False sb_config.headless2 = True if not sb_config.headless and not sb_config.headless2: @@ -1779,6 +1793,7 @@ def pytest_configure(config): if sb_config.browser == "safari" and sb_config.headless: sb_config.headless = False # Safari doesn't support headless mode + sb_config.headless1 = False if sb_config.dash_title: constants.Dashboard.TITLE = sb_config.dash_title.replace("_", " ") diff --git a/seleniumbase/plugins/sb_manager.py b/seleniumbase/plugins/sb_manager.py index 4427910fc0e..547b1d1552e 100644 --- a/seleniumbase/plugins/sb_manager.py +++ b/seleniumbase/plugins/sb_manager.py @@ -32,8 +32,9 @@ def SB( rtf=None, # Shortcut / Duplicate of "raise_test_failure". raise_test_failure=None, # If "test" mode, raise Exception on 1st failure. browser=None, # Choose from "chrome", "edge", "firefox", or "safari". - headless=None, # The original headless mode for Chromium and Firefox. - headless2=None, # Chromium's new headless mode. (Has more features) + headless=None, # Use the default headless mode for Chromium and Firefox. + headless1=None, # Use Chromium's old headless mode. (Fast, but limited) + headless2=None, # Use Chromium's new headless mode. (Has more features) locale_code=None, # Set the Language Locale Code for the web browser. protocol=None, # The Selenium Grid protocol: "http" or "https". servername=None, # The Selenium Grid server/IP used for tests. @@ -146,104 +147,105 @@ def SB( Optional Parameters: -------------------- - test: Test Mode: Output, Logging, Continue on failure unless "rtf". - rtf: Shortcut / Duplicate of "raise_test_failure". - raise_test_failure: If "test" mode, raise Exception on 1st failure. - browser: Choose from "chrome", "edge", "firefox", or "safari". - headless: The original headless mode for Chromium and Firefox. - headless2: Chromium's new headless mode. (Has more features) - locale_code: Set the Language Locale Code for the web browser. - protocol: The Selenium Grid protocol: "http" or "https". - servername: The Selenium Grid server/IP used for tests. - port: The Selenium Grid port used by the test server. - proxy: Use proxy. Format: "SERVER:PORT" or "USER:PASS@SERVER:PORT". - proxy_bypass_list: Skip proxy when using the listed domains. - proxy_pac_url: Use PAC file. (Format: URL or USERNAME:PASSWORD@URL) - multi_proxy: # Allow multiple proxies with auth when multi-threaded. - agent: Modify the web browser's User-Agent string. - cap_file: The desired capabilities to use with a Selenium Grid. - cap_string: The desired capabilities to use with a Selenium Grid. - recorder_ext: Enables the SeleniumBase Recorder Chromium extension. - disable_js: Disable JavaScript on websites. Pages might break! - disable_csp: Disable the Content Security Policy of websites. - enable_ws: Enable Web Security on Chromium-based browsers. - enable_sync: Enable "Chrome Sync" on websites. - use_auto_ext: Use Chrome's automation extension. - undetectable: Use undetected-chromedriver to evade bot-detection. - uc_cdp_events: Capture CDP events in undetected-chromedriver mode. - uc_subprocess: Use undetected-chromedriver as a subprocess. - log_cdp_events: Capture {"performance": "ALL", "browser": "ALL"} - incognito: Enable Chromium's Incognito mode. - guest_mode: Enable Chromium's Guest mode. - dark_mode: Enable Chromium's Dark mode. - devtools: Open Chromium's DevTools when the browser opens. - remote_debug: Enable Chrome's Debugger on "http://localhost:9222". - enable_3d_apis: Enable WebGL and 3D APIs. - swiftshader: Chrome: --use-gl=angle / --use-angle=swiftshader-webgl - ad_block_on: Block some types of display ads from loading. - host_resolver_rules: Set host-resolver-rules, comma-separated. - block_images: Block images from loading during tests. - do_not_track: Tell websites that you don't want to be tracked. - chromium_arg: "ARG=N,ARG2" (Set Chromium args, ","-separated.) - firefox_arg: "ARG=N,ARG2" (Set Firefox args, comma-separated.) - firefox_pref: SET (Set Firefox PREFERENCE:VALUE set, ","-separated) - user_data_dir: Set the Chrome user data directory to use. - extension_zip: Load a Chrome Extension .zip|.crx, comma-separated. - extension_dir: Load a Chrome Extension directory, comma-separated. - disable_features: "F1,F2" (Disable Chrome features, ","-separated.) - binary_location: Set path of the Chromium browser binary to use. - driver_version: Set the chromedriver or uc_driver version to use. - skip_js_waits: Skip JS Waits (readyState=="complete" and Angular). - wait_for_angularjs: Wait for AngularJS to load after some actions. - use_wire: Use selenium-wire's webdriver over selenium webdriver. - external_pdf: Set Chrome "plugins.always_open_pdf_externally":True. - window_position: Set the browser's starting window position: "X,Y" - window_size: Set the browser's starting window size: "Width,Height" - is_mobile: Use the mobile device emulator while running tests. - mobile: Shortcut / Duplicate of "is_mobile". - device_metrics: Set mobile metrics: "CSSWidth,CSSHeight,PixelRatio" - xvfb: Run tests using the Xvfb virtual display server on Linux OS. - xvfb_metrics: Set Xvfb display size on Linux: "Width,Height". - start_page: The starting URL for the web browser when tests begin. - rec_print: If Recorder is enabled, prints output after tests end. - rec_behave: Like Recorder Mode, but also generates behave-gherkin. - record_sleep: If Recorder enabled, also records self.sleep calls. - data: Extra test data. Access with "self.data" in tests. - var1: Extra test data. Access with "self.var1" in tests. - var2: Extra test data. Access with "self.var2" in tests. - var3: Extra test data. Access with "self.var3" in tests. - variables: DICT (Extra test data. Access with "self.variables") - account: Set account. Access with "self.account" in tests. - environment: Set the test env. Access with "self.env" in tests. - headed: Run tests in headed/GUI mode on Linux, where not default. - maximize: Start tests with the browser window maximized. - disable_ws: Reverse of "enable_ws". (None and False are different) - disable_beforeunload: Disable the "beforeunload" event on Chromium. - settings_file: A file for overriding default SeleniumBase settings. - uc: Shortcut / Duplicate of "undetectable". - undetected: Shortcut / Duplicate of "undetectable". - uc_cdp: Shortcut / Duplicate of "uc_cdp_events". - uc_sub: Shortcut / Duplicate of "uc_subprocess". - log_cdp: Shortcut / Duplicate of "log_cdp_events". - ad_block: Shortcut / Duplicate of "ad_block_on". - server: Shortcut / Duplicate of "servername". - guest: Shortcut / Duplicate of "guest_mode". - wire: Shortcut / Duplicate of "use_wire". - pls: Shortcut / Duplicate of "page_load_strategy". - sjw: Shortcut / Duplicate of "skip_js_waits". - wfa: Shortcut / Duplicate of "wait_for_angularjs". - save_screenshot: Save a screenshot at the end of each test. - no_screenshot: No screenshots saved unless tests directly ask it. - page_load_strategy: Set Chrome PLS to "normal", "eager", or "none". - timeout_multiplier: Multiplies the default timeout values. - js_checking_on: Check for JavaScript errors after page loads. - slow: Slow down the automation. Faster than using Demo Mode. - demo: Slow down and visually see test actions as they occur. - demo_sleep: SECONDS (Set wait time after Slow & Demo Mode actions.) - message_duration: SECONDS (The time length for Messenger alerts.) - highlights: Number of highlight animations for Demo Mode actions. - interval: SECONDS (Autoplay interval for SB Slides & Tour steps.) - time_limit: SECONDS (Safely fail tests that exceed the time limit.) + test (bool): Test Mode: Output, Logging, Continue on failure unless "rtf". + rtf (bool): Shortcut / Duplicate of "raise_test_failure". + raise_test_failure (bool): If "test" mode, raise Exception on 1st failure. + browser (str): Choose from "chrome", "edge", "firefox", or "safari". + headless (bool): Use the default headless mode for Chromium and Firefox. + headless1 (bool): Use Chromium's old headless mode. (Fast, but limited) + headless2 (bool): Use Chromium's new headless mode. (Has more features) + locale_code (str): Set the Language Locale Code for the web browser. + protocol (str): The Selenium Grid protocol: "http" or "https". + servername (str): The Selenium Grid server/IP used for tests. + port (int): The Selenium Grid port used by the test server. + proxy (str): Use proxy. Format: "SERVER:PORT" or "USER:PASS@SERVER:PORT". + proxy_bypass_list (str): Skip proxy when using the listed domains. + proxy_pac_url (str): Use PAC file. (Format: URL or USERNAME:PASSWORD@URL) + multi_proxy (bool): # Allow multiple proxies with auth when multithreaded. + agent (str): Modify the web browser's User-Agent string. + cap_file (str): The desired capabilities to use with a Selenium Grid. + cap_string (str): The desired capabilities to use with a Selenium Grid. + recorder_ext (bool): Enables the SeleniumBase Recorder Chromium extension. + disable_js (bool): Disable JavaScript on websites. Pages might break! + disable_csp (bool): Disable the Content Security Policy of websites. + enable_ws (bool): Enable Web Security on Chromium-based browsers. + enable_sync (bool): Enable "Chrome Sync" on websites. + use_auto_ext (bool): Use Chrome's automation extension. + undetectable (bool): Use undetected-chromedriver to evade bot-detection. + uc_cdp_events (bool): Capture CDP events in undetected-chromedriver mode. + uc_subprocess (bool): Use undetected-chromedriver as a subprocess. + log_cdp_events (bool): Capture {"performance": "ALL", "browser": "ALL"} + incognito (bool): Enable Chromium's Incognito mode. + guest_mode (bool): Enable Chromium's Guest mode. + dark_mode (bool): Enable Chromium's Dark mode. + devtools (bool): Open Chromium's DevTools when the browser opens. + remote_debug (bool): Enable Chrome's Debugger on "http://localhost:9222". + enable_3d_apis (bool): Enable WebGL and 3D APIs. + swiftshader (bool): Chrome: --use-gl=angle / --use-angle=swiftshader-webgl + ad_block_on (bool): Block some types of display ads from loading. + host_resolver_rules (str): Set host-resolver-rules, comma-separated. + block_images (bool): Block images from loading during tests. + do_not_track (bool): Tell websites that you don't want to be tracked. + chromium_arg (str): "ARG=N,ARG2" (Set Chromium args, ","-separated.) + firefox_arg (str): "ARG=N,ARG2" (Set Firefox args, comma-separated.) + firefox_pref (str): SET (Set Firefox PREFERENCE:VALUE set, ","-separated) + user_data_dir (str): Set the Chrome user data directory to use. + extension_zip (str): Load a Chrome Extension .zip|.crx, comma-separated. + extension_dir (str): Load a Chrome Extension directory, comma-separated. + disable_features (str): "F1,F2" (Disable Chrome features, ","-separated.) + binary_location (str): Set path of the Chromium browser binary to use. + driver_version (str): Set the chromedriver or uc_driver version to use. + skip_js_waits (bool): Skip JS Waits (readyState=="complete" and Angular). + wait_for_angularjs (bool): Wait for AngularJS to load after some actions. + use_wire (bool): Use selenium-wire's webdriver over selenium webdriver. + external_pdf (bool): Set Chrome "plugins.always_open_pdf_externally":True. + window_position (x,y): Set the browser's starting window position: "X,Y" + window_size (w,h): Set the browser's starting window size: "Width,Height" + is_mobile (bool): Use the mobile device emulator while running tests. + mobile (bool): Shortcut / Duplicate of "is_mobile". + device_metrics (w,h,pr): Mobile metrics: "CSSWidth,CSSHeight,PixelRatio" + xvfb (bool): Run tests using the Xvfb virtual display server on Linux OS. + xvfb_metrics (w,h): Set Xvfb display size on Linux: "Width,Height". + start_page (str): The starting URL for the web browser when tests begin. + rec_print (bool): If Recorder is enabled, prints output after tests end. + rec_behave (bool): Like Recorder Mode, but also generates behave-gherkin. + record_sleep (bool): If Recorder enabled, also records self.sleep calls. + data (str): Extra test data. Access with "self.data" in tests. + var1 (str): Extra test data. Access with "self.var1" in tests. + var2 (str): Extra test data. Access with "self.var2" in tests. + var3 (str): Extra test data. Access with "self.var3" in tests. + variables (dict): Extra test data. Access with "self.variables". + account (str): Set account. Access with "self.account" in tests. + environment (str): Set the test env. Access with "self.env" in tests. + headed (bool): Run tests in headed/GUI mode on Linux, where not default. + maximize (bool): Start tests with the browser window maximized. + disable_ws (bool): Reverse of "enable_ws". (None and False are different) + disable_beforeunload (bool): Disable the "beforeunload" event on Chromium. + settings_file (str): A file for overriding default SeleniumBase settings. + uc (bool): Shortcut / Duplicate of "undetectable". + undetected (bool): Shortcut / Duplicate of "undetectable". + uc_cdp (bool): Shortcut / Duplicate of "uc_cdp_events". + uc_sub (bool): Shortcut / Duplicate of "uc_subprocess". + log_cdp (bool): Shortcut / Duplicate of "log_cdp_events". + ad_block (bool): Shortcut / Duplicate of "ad_block_on". + server (str): Shortcut / Duplicate of "servername". + guest (bool): Shortcut / Duplicate of "guest_mode". + wire (bool): Shortcut / Duplicate of "use_wire". + pls (str): Shortcut / Duplicate of "page_load_strategy". + sjw (bool): Shortcut / Duplicate of "skip_js_waits". + wfa (bool): Shortcut / Duplicate of "wait_for_angularjs". + save_screenshot (bool): Save a screenshot at the end of each test. + no_screenshot (bool): No screenshots saved unless tests directly ask it. + page_load_strategy (str): Set Chrome PLS to "normal", "eager", or "none". + timeout_multiplier (float): Multiplies the default timeout values. + js_checking_on (bool): Check for JavaScript errors after page loads. + slow (bool): Slow down the automation. Faster than using Demo Mode. + demo (bool): Slow down and visually see test actions as they occur. + demo_sleep (float): SECONDS (Set wait time after Slow & Demo Mode actions) + message_duration (float): SECONDS (The time length for Messenger alerts.) + highlights (int): Number of highlight animations for Demo Mode actions. + interval (float): SECONDS (Autoplay interval for SB Slides & Tour steps.) + time_limit (float): SECONDS (Safely fail tests that exceed the time limit) """ import os import sys @@ -401,6 +403,13 @@ def SB( headless = True else: headless = False + if headless1 is None: + if "--headless1" in sys_argv: + headless1 = True + else: + headless1 = False + if headless1: + headless = True if headless2 is None: if "--headless2" in sys_argv: headless2 = True @@ -672,6 +681,7 @@ def SB( recorder_ext = True if recorder_mode and headless: headless = False + headless1 = False headless2 = True sb_config.proxy_driver = False if "--proxy-driver" in sys_argv or "--proxy_driver" in sys_argv: @@ -801,6 +811,7 @@ def SB( save_screenshot = False # "no_screenshot" has priority if browser == "safari" and headless: headless = False # Safari doesn't support headless mode + headless1 = False if js_checking_on is None: if "--check-js" in sys_argv: js_checking_on = True @@ -921,6 +932,7 @@ def SB( sb_config.is_nosetest = False sb_config.is_context_manager = True sb_config.headless = headless + sb_config.headless1 = headless1 sb_config.headless2 = headless2 sb_config.headed = headed sb_config.xvfb = xvfb @@ -1026,6 +1038,7 @@ def SB( sb.is_nosetest = False sb.is_context_manager = sb_config.is_context_manager sb.headless = sb_config.headless + sb.headless1 = sb_config.headless1 sb.headless2 = sb_config.headless2 sb.headed = sb_config.headed sb.xvfb = sb_config.xvfb diff --git a/seleniumbase/plugins/selenium_plugin.py b/seleniumbase/plugins/selenium_plugin.py index edbd340a9c6..ac903b98812 100644 --- a/seleniumbase/plugins/selenium_plugin.py +++ b/seleniumbase/plugins/selenium_plugin.py @@ -43,8 +43,9 @@ class SeleniumBrowser(Plugin): --sjw (Skip JS Waits for readyState to be "complete" or Angular to load.) --wfa (Wait for AngularJS to be done loading after specific web actions.) --pls=PLS (Set pageLoadStrategy on Chrome: "normal", "eager", or "none".) - --headless (Run tests in headless mode. The default arg on Linux OS.) - --headless2 (Use the new headless mode, which supports extensions.) + --headless (The default headless mode. Linux uses this mode by default.) + --headless1 (Use Chrome's old headless mode. Fast, but has limitations.) + --headless2 (Use Chrome's new headless mode, which supports extensions.) --headed (Run tests in headed/GUI mode on Linux OS, where not default.) --xvfb (Run tests using the Xvfb virtual display server on Linux OS.) --xvfb-metrics=STRING (Set Xvfb display size on Linux: "Width,Height".) @@ -437,6 +438,15 @@ def options(self, parser, env): UNLESS using a virtual display with Xvfb. Default: False on Mac/Windows. True on Linux.""", ) + parser.addoption( + "--headless1", + action="store_true", + dest="headless1", + default=False, + help="""This option activates the old headless mode, + which is faster, but has limitations. + (May be phased out by Chrome in the future.)""", + ) parser.addoption( "--headless2", action="store_true", @@ -1009,6 +1019,7 @@ def beforeTest(self, test): browser = self.options.browser test.test.browser = browser test.test.headless = None + test.test.headless1 = None test.test.headless2 = None # As a shortcut, you can use "--edge" instead of "--browser=edge", etc, # but you can only specify one default browser. (Default: chrome) @@ -1147,9 +1158,13 @@ def beforeTest(self, test): test.test.cap_file = self.options.cap_file test.test.cap_string = self.options.cap_string test.test.headless = self.options.headless + test.test.headless1 = self.options.headless1 + if test.test.headless1: + test.test.headless = True test.test.headless2 = self.options.headless2 if test.test.headless and test.test.browser == "safari": test.test.headless = False # Safari doesn't use headless + test.test.headless1 = False if test.test.headless2 and test.test.browser == "firefox": test.test.headless2 = False # Only for Chromium browsers test.test.headless = True # Firefox has regular headless @@ -1294,8 +1309,10 @@ def beforeTest(self, test): # Recorder Mode can still optimize scripts in --headless2 mode. if self.options.recorder_mode and self.options.headless: self.options.headless = False + self.options.headless1 = False self.options.headless2 = True test.test.headless = False + test.test.headless1 = False test.test.headless2 = True if not self.options.headless and not self.options.headless2: self.options.headed = True