Skip to content

Commit 0fa2fe3

Browse files
committed
Add option to use Chrome's old headless mode
1 parent 4310a4d commit 0fa2fe3

File tree

7 files changed

+121
-14
lines changed

7 files changed

+121
-14
lines changed

seleniumbase/behave/behave_sb.py

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -44,8 +44,9 @@
4444
-D sjw (Skip JS Waits for readyState to be "complete" or Angular to load.)
4545
-D wfa (Wait for AngularJS to be done loading after specific web actions.)
4646
-D pls=PLS (Set pageLoadStrategy on Chrome: "normal", "eager", or "none".)
47-
-D headless (Run tests in headless mode. The default arg on Linux OS.)
48-
-D headless2 (Use the new headless mode, which supports extensions.)
47+
-D headless (The default headless mode. Linux uses this mode by default.)
48+
-D headless1 (Use Chrome's old headless mode. Fast, but has limitations.)
49+
-D headless2 (Use Chrome's new headless mode, which supports extensions.)
4950
-D headed (Run tests in headed/GUI mode on Linux OS, where not default.)
5051
-D xvfb (Run tests using the Xvfb virtual display server on Linux OS.)
5152
-D xvfb-metrics=STRING (Set Xvfb display size on Linux: "Width,Height".)
@@ -144,6 +145,7 @@ def get_configured_sb(context):
144145
sb.browser = "chrome"
145146
sb.is_behave = True
146147
sb.headless = False
148+
sb.headless1 = False
147149
sb.headless2 = False
148150
sb.headless_active = False
149151
sb.headed = False
@@ -296,6 +298,11 @@ def get_configured_sb(context):
296298
sb.headless = True
297299
continue
298300
# Handle: -D headless2
301+
if low_key == "headless1":
302+
sb.headless1 = True
303+
sb.headless = True
304+
continue
305+
# Handle: -D headless2
299306
if low_key == "headless2":
300307
sb.headless2 = True
301308
continue
@@ -864,6 +871,7 @@ def get_configured_sb(context):
864871
# Recorder Mode can still optimize scripts in "-D headless2" mode.
865872
if sb.recorder_ext and sb.headless:
866873
sb.headless = False
874+
sb.headless1 = False
867875
sb.headless2 = True
868876
if sb.headless2 and sb.browser == "firefox":
869877
sb.headless2 = False # Only for Chromium browsers
@@ -900,11 +908,13 @@ def get_configured_sb(context):
900908
# Recorder Mode can still optimize scripts in --headless2 mode.
901909
if sb.recorder_mode and sb.headless:
902910
sb.headless = False
911+
sb.headless1 = False
903912
sb.headless2 = True
904913
if not sb.headless and not sb.headless2:
905914
sb.headed = True
906915
if sb.browser == "safari" and sb.headless:
907916
sb.headless = False # Safari doesn't support headless mode
917+
sb.headless1 = False
908918
if sb.save_screenshot_after_test and sb.no_screenshot_after_test:
909919
sb.save_screenshot_after_test = False # "no_screenshot" has priority
910920
if sb.servername != "localhost":

seleniumbase/core/browser_launcher.py

Lines changed: 39 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1553,6 +1553,7 @@ def _set_chrome_options(
15531553
log_cdp_events,
15541554
no_sandbox,
15551555
disable_gpu,
1556+
headless1,
15561557
headless2,
15571558
incognito,
15581559
guest_mode,
@@ -1771,7 +1772,10 @@ def _set_chrome_options(
17711772
pass # Processed After Version Check
17721773
elif headless:
17731774
if not undetectable:
1774-
chrome_options.add_argument("--headless")
1775+
if headless1:
1776+
chrome_options.add_argument("--headless=old")
1777+
else:
1778+
chrome_options.add_argument("--headless")
17751779
if undetectable and servername and servername != "localhost":
17761780
# The Grid Node will need Chrome 109 or newer
17771781
chrome_options.add_argument("--headless=new")
@@ -2193,6 +2197,7 @@ def get_driver(
21932197
log_cdp_events=False,
21942198
no_sandbox=False,
21952199
disable_gpu=False,
2200+
headless1=False,
21962201
headless2=False,
21972202
incognito=False,
21982203
guest_mode=False,
@@ -2406,6 +2411,7 @@ def get_driver(
24062411
log_cdp_events,
24072412
no_sandbox,
24082413
disable_gpu,
2414+
headless1,
24092415
headless2,
24102416
incognito,
24112417
guest_mode,
@@ -2462,6 +2468,7 @@ def get_driver(
24622468
log_cdp_events,
24632469
no_sandbox,
24642470
disable_gpu,
2471+
headless1,
24652472
headless2,
24662473
incognito,
24672474
guest_mode,
@@ -2522,6 +2529,7 @@ def get_remote_driver(
25222529
log_cdp_events,
25232530
no_sandbox,
25242531
disable_gpu,
2532+
headless1,
25252533
headless2,
25262534
incognito,
25272535
guest_mode,
@@ -2657,6 +2665,7 @@ def get_remote_driver(
26572665
log_cdp_events,
26582666
no_sandbox,
26592667
disable_gpu,
2668+
headless1,
26602669
headless2,
26612670
incognito,
26622671
guest_mode,
@@ -2829,6 +2838,7 @@ def get_remote_driver(
28292838
log_cdp_events,
28302839
no_sandbox,
28312840
disable_gpu,
2841+
headless1,
28322842
headless2,
28332843
incognito,
28342844
guest_mode,
@@ -2948,6 +2958,7 @@ def get_local_driver(
29482958
log_cdp_events,
29492959
no_sandbox,
29502960
disable_gpu,
2961+
headless1,
29512962
headless2,
29522963
incognito,
29532964
guest_mode,
@@ -3425,8 +3436,14 @@ def get_local_driver(
34253436
else:
34263437
pass # Will need Xvfb on Linux
34273438
elif headless:
3428-
if "--headless" not in edge_options.arguments:
3429-
edge_options.add_argument("--headless")
3439+
if (
3440+
"--headless" not in edge_options.arguments
3441+
and "--headless=old" not in edge_options.arguments
3442+
):
3443+
if headless1:
3444+
edge_options.add_argument("--headless=old")
3445+
else:
3446+
edge_options.add_argument("--headless")
34303447
if mobile_emulator and not is_using_uc(undetectable, browser_name):
34313448
emulator_settings = {}
34323449
device_metrics = {}
@@ -3788,6 +3805,7 @@ def get_local_driver(
37883805
log_cdp_events,
37893806
no_sandbox,
37903807
disable_gpu,
3808+
headless1,
37913809
headless2,
37923810
incognito,
37933811
guest_mode,
@@ -3960,8 +3978,14 @@ def get_local_driver(
39603978
except Exception:
39613979
pass # Will need Xvfb on Linux
39623980
elif headless:
3963-
if "--headless" not in chrome_options.arguments:
3964-
chrome_options.add_argument("--headless")
3981+
if (
3982+
"--headless" not in chrome_options.arguments
3983+
and "--headless=old" not in chrome_options.arguments
3984+
):
3985+
if headless1:
3986+
chrome_options.add_argument("--headless=old")
3987+
else:
3988+
chrome_options.add_argument("--headless")
39653989
if LOCAL_CHROMEDRIVER and os.path.exists(LOCAL_CHROMEDRIVER):
39663990
try:
39673991
make_driver_executable_if_not(LOCAL_CHROMEDRIVER)
@@ -4227,6 +4251,12 @@ def get_local_driver(
42274251
chrome_options.arguments.remove(
42284252
"--headless"
42294253
)
4254+
if "--headless=old" in (
4255+
chrome_options.arguments
4256+
):
4257+
chrome_options.arguments.remove(
4258+
"--headless=old"
4259+
)
42304260
uc_chrome_version = None
42314261
if (
42324262
use_version.isnumeric()
@@ -4300,6 +4330,7 @@ def get_local_driver(
43004330
False, # log_cdp_events
43014331
no_sandbox,
43024332
disable_gpu,
4333+
False, # headless1
43034334
False, # headless2
43044335
incognito,
43054336
guest_mode,
@@ -4541,6 +4572,7 @@ def get_local_driver(
45414572
False, # log_cdp_events
45424573
no_sandbox,
45434574
disable_gpu,
4575+
False, # headless1
45444576
False, # headless2
45454577
incognito,
45464578
guest_mode,
@@ -4792,6 +4824,8 @@ def get_local_driver(
47924824
)
47934825
if "--headless" in chrome_options.arguments:
47944826
chrome_options.arguments.remove("--headless")
4827+
if "--headless=old" in chrome_options.arguments:
4828+
chrome_options.arguments.remove("--headless=old")
47954829
service = ChromeService(
47964830
log_output=os.devnull,
47974831
service_args=["--disable-build-check"]

seleniumbase/fixtures/base_case.py

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3771,6 +3771,7 @@ def get_new_driver(
37713771
log_cdp_events=None,
37723772
no_sandbox=None,
37733773
disable_gpu=None,
3774+
headless1=None,
37743775
headless2=None,
37753776
incognito=None,
37763777
guest_mode=None,
@@ -3830,6 +3831,7 @@ def get_new_driver(
38303831
log_cdp_events - capture {"performance": "ALL", "browser": "ALL"})
38313832
no_sandbox - the option to enable the "No-Sandbox" feature (Chrome)
38323833
disable_gpu - the option to enable Chrome's "Disable GPU" feature
3834+
headless1 - the option to use the older headless mode (Chromium)
38333835
headless2 - the option to use the newer headless mode (Chromium)
38343836
incognito - the option to enable Chrome's Incognito mode (Chrome)
38353837
guest_mode - the option to enable Chrome's Guest mode (Chrome)
@@ -3938,6 +3940,8 @@ def get_new_driver(
39383940
no_sandbox = self.no_sandbox
39393941
if disable_gpu is None:
39403942
disable_gpu = self.disable_gpu
3943+
if headless1 is None:
3944+
headless1 = self.headless1
39413945
if headless2 is None:
39423946
headless2 = self.headless2
39433947
if incognito is None:
@@ -4036,6 +4040,7 @@ def get_new_driver(
40364040
log_cdp_events=log_cdp_events,
40374041
no_sandbox=no_sandbox,
40384042
disable_gpu=disable_gpu,
4043+
headless1=headless1,
40394044
headless2=headless2,
40404045
incognito=incognito,
40414046
guest_mode=guest_mode,
@@ -14324,6 +14329,10 @@ def setUp(self, masterqa_mode=False):
1432414329
self.env = self.environment # Add a shortened version
1432514330
self.with_selenium = sb_config.with_selenium # Should be True
1432614331
self.headless = sb_config.headless
14332+
self.headless1 = sb_config.headless1
14333+
if self.headless1:
14334+
self.headless = True
14335+
self.headless2 = sb_config.headless2
1432714336
self.headless_active = False
1432814337
sb_config.headless_active = False
1432914338
self.headed = sb_config.headed
@@ -14392,7 +14401,6 @@ def setUp(self, masterqa_mode=False):
1439214401
self.log_cdp_events = sb_config.log_cdp_events
1439314402
self.no_sandbox = sb_config.no_sandbox
1439414403
self.disable_gpu = sb_config.disable_gpu
14395-
self.headless2 = sb_config.headless2
1439614404
self.incognito = sb_config.incognito
1439714405
self.guest_mode = sb_config.guest_mode
1439814406
self.dark_mode = sb_config.dark_mode
@@ -14768,6 +14776,7 @@ def setUp(self, masterqa_mode=False):
1476814776
log_cdp_events=self.log_cdp_events,
1476914777
no_sandbox=self.no_sandbox,
1477014778
disable_gpu=self.disable_gpu,
14779+
headless1=self.headless1,
1477114780
headless2=self.headless2,
1477214781
incognito=self.incognito,
1477314782
guest_mode=self.guest_mode,

seleniumbase/plugins/driver_manager.py

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,8 @@ def __exit__(self, exc_type, exc_val, exc_tb):
6565

6666
def Driver(
6767
browser=None, # Choose from "chrome", "edge", "firefox", or "safari".
68-
headless=None, # The original headless mode for Chromium and Firefox.
68+
headless=None, # The default headless mode for Chromium and Firefox.
69+
headless1=None, # Chromium's old headless mode. (Fast, but limited)
6970
headless2=None, # Chromium's new headless mode. (Has more features)
7071
headed=None, # Run tests in headed/GUI mode on Linux, where not default.
7172
locale_code=None, # Set the Language Locale Code for the web browser.
@@ -336,6 +337,13 @@ def Driver(
336337
headless = True
337338
else:
338339
headless = False
340+
if headless1 is None:
341+
if "--headless1" in sys_argv:
342+
headless1 = True
343+
else:
344+
headless1 = False
345+
if headless1:
346+
headless = True
339347
if headless2 is None:
340348
if "--headless2" in sys_argv:
341349
headless2 = True
@@ -601,6 +609,7 @@ def Driver(
601609
headless = True
602610
if recorder_mode and headless:
603611
headless = False
612+
headless1 = False
604613
headless2 = True
605614
if headless2 and browser == "firefox":
606615
headless2 = False # Only for Chromium browsers
@@ -773,6 +782,7 @@ def Driver(
773782
log_cdp_events=log_cdp_events,
774783
no_sandbox=no_sandbox,
775784
disable_gpu=disable_gpu,
785+
headless1=headless1,
776786
headless2=headless2,
777787
incognito=incognito,
778788
guest_mode=guest_mode,

seleniumbase/plugins/pytest_plugin.py

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -62,8 +62,9 @@ def pytest_addoption(parser):
6262
--sjw (Skip JS Waits for readyState to be "complete" or Angular to load.)
6363
--wfa (Wait for AngularJS to be done loading after specific web actions.)
6464
--pls=PLS (Set pageLoadStrategy on Chrome: "normal", "eager", or "none".)
65-
--headless (Run tests in headless mode. The default arg on Linux OS.)
66-
--headless2 (Use the new headless mode, which supports extensions.)
65+
--headless (The default headless mode. Linux uses this mode by default.)
66+
--headless1 (Use Chrome's old headless mode. Fast, but has limitations.)
67+
--headless2 (Use Chrome's new headless mode, which supports extensions.)
6768
--headed (Run tests in headed/GUI mode on Linux OS, where not default.)
6869
--xvfb (Run tests using the Xvfb virtual display server on Linux OS.)
6970
--xvfb-metrics=STRING (Set Xvfb display size on Linux: "Width,Height".)
@@ -700,6 +701,15 @@ def pytest_addoption(parser):
700701
UNLESS using a virtual display with Xvfb.
701702
Default: False on Mac/Windows. True on Linux.""",
702703
)
704+
parser.addoption(
705+
"--headless1",
706+
action="store_true",
707+
dest="headless1",
708+
default=False,
709+
help="""This option activates the old headless mode,
710+
which is faster, but has limitations.
711+
(May be phased out by Chrome in the future.)""",
712+
)
703713
parser.addoption(
704714
"--headless2",
705715
action="store_true",
@@ -1533,6 +1543,9 @@ def pytest_configure(config):
15331543
sb_config.mobile_emulator = config.getoption("mobile_emulator")
15341544
sb_config.device_metrics = config.getoption("device_metrics")
15351545
sb_config.headless = config.getoption("headless")
1546+
sb_config.headless1 = config.getoption("headless1")
1547+
if sb_config.headless1:
1548+
sb_config.headless = True
15361549
sb_config.headless2 = config.getoption("headless2")
15371550
if sb_config.headless2 and sb_config.browser == "firefox":
15381551
sb_config.headless2 = False # Only for Chromium browsers
@@ -1759,6 +1772,7 @@ def pytest_configure(config):
17591772
# Recorder Mode can still optimize scripts in --headless2 mode.
17601773
if sb_config.recorder_mode and sb_config.headless:
17611774
sb_config.headless = False
1775+
sb_config.headless1 = False
17621776
sb_config.headless2 = True
17631777

17641778
if not sb_config.headless and not sb_config.headless2:
@@ -1779,6 +1793,7 @@ def pytest_configure(config):
17791793

17801794
if sb_config.browser == "safari" and sb_config.headless:
17811795
sb_config.headless = False # Safari doesn't support headless mode
1796+
sb_config.headless1 = False
17821797

17831798
if sb_config.dash_title:
17841799
constants.Dashboard.TITLE = sb_config.dash_title.replace("_", " ")

0 commit comments

Comments
 (0)