Skip to content

Commit 235d9bd

Browse files
committed
Add option to change Chromium's "pageLoadStrategy"
1 parent 15dda29 commit 235d9bd

File tree

7 files changed

+130
-0
lines changed

7 files changed

+130
-0
lines changed

seleniumbase/behave/behave_sb.py

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@
4141
-D firefox-pref=SET (Set a Firefox preference:value set, comma-separated.)
4242
-D extension-zip=ZIP (Load a Chrome Extension .zip|.crx, comma-separated.)
4343
-D extension-dir=DIR (Load a Chrome Extension directory, comma-separated.)
44+
-D pls=PLS (Set pageLoadStrategy on Chrome: "normal", "eager", or "none".)
4445
-D headless (Run tests in headless mode. The default arg on Linux OS.)
4546
-D headed (Run tests in headed/GUI mode on Linux OS.)
4647
-D xvfb (Run tests using the Xvfb virtual display server on Linux OS.)
@@ -153,6 +154,7 @@ def get_configured_sb(context):
153154
sb.device_metrics = None
154155
sb.extension_zip = None
155156
sb.extension_dir = None
157+
sb.page_load_strategy = None
156158
sb.database_env = "test"
157159
sb.log_path = "latest_logs/"
158160
sb.archive_logs = False
@@ -212,6 +214,7 @@ def get_configured_sb(context):
212214

213215
# Set a few sb_config vars early in case parsing args fails
214216
sb_config.dashboard = None
217+
sb_config._has_logs = None
215218
sb_config._has_exception = None
216219
sb_config.save_screenshot = None
217220

@@ -418,6 +421,24 @@ def get_configured_sb(context):
418421
extension_dir = sb.extension_dir # revert to default
419422
sb.extension_dir = extension_dir
420423
continue
424+
# Handle: -D pls=PLS / page-load-strategy=PLS / page_load_strategy=PLS
425+
if low_key in ["pls", "page-load-strategy", "page_load_strategy"]:
426+
page_load_strategy = userdata[key].lower()
427+
if page_load_strategy in ["normal", "eager", "none"]:
428+
sb.page_load_strategy = page_load_strategy
429+
elif page_load_strategy == "true":
430+
raise Exception(
431+
'\nThe "pls" / "page-load-strategy" arg requires a value!'
432+
'\nChoose from ["normal", "eager", "none"]'
433+
'\nEg. -D pls="none"'
434+
)
435+
else:
436+
raise Exception(
437+
'\n"%s" is not a valid "pls" / "page-load-strategy" value!'
438+
'\nChoose from ["normal", "eager", "none"]'
439+
'\nEg. -D pls="none"' % page_load_strategy
440+
)
441+
continue
421442
# Handle: -D database-env=ENVIRONMENT / database_env=ENVIRONMENT
422443
if low_key in ["database-env", "database_env"]:
423444
database_env = userdata[key].lower()

seleniumbase/config/settings.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,18 @@
1616
LARGE_TIMEOUT = 10
1717
EXTREME_TIMEOUT = 30
1818

19+
# Default page load timeout.
20+
# If a page takes longer than this to load, you'll get the following error:
21+
# selenium.common.exceptions.TimeoutException:
22+
# Message: timeout: Timed out receiving message from renderer: PLT
23+
# In global Selenium settings, this value is set to 300 seconds by default.
24+
PAGE_LOAD_TIMEOUT = 120
25+
26+
# Default page load strategy.
27+
# ["normal", "eager", "none"]
28+
# Selenium default = "normal"
29+
PAGE_LOAD_STRATEGY = "normal"
30+
1931
# If True, existing logs from past test runs will be saved and take up space.
2032
# If False, only the logs from the most recent test run will be saved locally.
2133
# You can also archive existing logs on the command line with: "--archive_logs"

seleniumbase/core/browser_launcher.py

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -283,6 +283,7 @@ def _set_chrome_options(
283283
user_data_dir,
284284
extension_zip,
285285
extension_dir,
286+
page_load_strategy,
286287
external_pdf,
287288
servername,
288289
mobile_emulator,
@@ -439,6 +440,22 @@ def _set_chrome_options(
439440
chrome_options.add_argument("--disable-hang-monitor")
440441
chrome_options.add_argument("--disable-prompt-on-repost")
441442
chrome_options.add_argument("--disable-3d-apis")
443+
if (
444+
selenium4_or_newer
445+
and page_load_strategy
446+
and page_load_strategy.lower() in ["eager", "none"]
447+
):
448+
# Only change it if not "normal", which is the default.
449+
chrome_options.page_load_strategy = page_load_strategy.lower()
450+
elif (
451+
selenium4_or_newer
452+
and not page_load_strategy
453+
and hasattr(settings, "PAGE_LOAD_STRATEGY")
454+
and settings.PAGE_LOAD_STRATEGY
455+
and settings.PAGE_LOAD_STRATEGY.lower() in ["eager", "none"]
456+
):
457+
# Only change it if not "normal", which is the default.
458+
chrome_options.page_load_strategy = settings.PAGE_LOAD_STRATEGY.lower()
442459
if servername != "localhost":
443460
use_auto_ext = True # Use Automation Extension with the Selenium Grid
444461
if not use_auto_ext: # Disable Automation Extension / detection. (Default)
@@ -768,6 +785,7 @@ def get_driver(
768785
user_data_dir=None,
769786
extension_zip=None,
770787
extension_dir=None,
788+
page_load_strategy=None,
771789
external_pdf=None,
772790
test_id=None,
773791
mobile_emulator=False,
@@ -873,6 +891,7 @@ def get_driver(
873891
user_data_dir,
874892
extension_zip,
875893
extension_dir,
894+
page_load_strategy,
876895
external_pdf,
877896
test_id,
878897
mobile_emulator,
@@ -914,6 +933,7 @@ def get_driver(
914933
user_data_dir,
915934
extension_zip,
916935
extension_dir,
936+
page_load_strategy,
917937
external_pdf,
918938
mobile_emulator,
919939
device_width,
@@ -959,6 +979,7 @@ def get_remote_driver(
959979
user_data_dir,
960980
extension_zip,
961981
extension_dir,
982+
page_load_strategy,
962983
external_pdf,
963984
test_id,
964985
mobile_emulator,
@@ -1052,6 +1073,7 @@ def get_remote_driver(
10521073
user_data_dir,
10531074
extension_zip,
10541075
extension_dir,
1076+
page_load_strategy,
10551077
external_pdf,
10561078
servername,
10571079
mobile_emulator,
@@ -1275,6 +1297,7 @@ def get_remote_driver(
12751297
user_data_dir,
12761298
extension_zip,
12771299
extension_dir,
1300+
page_load_strategy,
12781301
external_pdf,
12791302
servername,
12801303
mobile_emulator,
@@ -1467,6 +1490,7 @@ def get_local_driver(
14671490
user_data_dir,
14681491
extension_zip,
14691492
extension_dir,
1493+
page_load_strategy,
14701494
external_pdf,
14711495
mobile_emulator,
14721496
device_width,
@@ -1808,6 +1832,24 @@ def get_local_driver(
18081832
edge_options.add_argument("--disable-hang-monitor")
18091833
edge_options.add_argument("--disable-prompt-on-repost")
18101834
edge_options.add_argument("--disable-3d-apis")
1835+
if (
1836+
selenium4_or_newer
1837+
and page_load_strategy
1838+
and page_load_strategy.lower() in ["eager", "none"]
1839+
):
1840+
# Only change it if not "normal", which is the default.
1841+
edge_options.page_load_strategy = page_load_strategy.lower()
1842+
elif (
1843+
selenium4_or_newer
1844+
and not page_load_strategy
1845+
and hasattr(settings, "PAGE_LOAD_STRATEGY")
1846+
and settings.PAGE_LOAD_STRATEGY
1847+
and settings.PAGE_LOAD_STRATEGY.lower() in ["eager", "none"]
1848+
):
1849+
# Only change it if not "normal", which is the default.
1850+
edge_options.page_load_strategy = (
1851+
settings.PAGE_LOAD_STRATEGY.lower()
1852+
)
18111853
if (settings.DISABLE_CSP_ON_CHROME or disable_csp) and not headless:
18121854
# Headless Edge doesn't support extensions, which are required
18131855
# for disabling the Content Security Policy on Edge
@@ -2029,6 +2071,7 @@ def get_local_driver(
20292071
user_data_dir,
20302072
extension_zip,
20312073
extension_dir,
2074+
page_load_strategy,
20322075
external_pdf,
20332076
servername,
20342077
mobile_emulator,
@@ -2086,6 +2129,7 @@ def get_local_driver(
20862129
user_data_dir,
20872130
extension_zip,
20882131
extension_dir,
2132+
page_load_strategy,
20892133
external_pdf,
20902134
servername,
20912135
mobile_emulator,
@@ -2220,6 +2264,7 @@ def get_local_driver(
22202264
user_data_dir,
22212265
extension_zip,
22222266
extension_dir,
2267+
page_load_strategy,
22232268
external_pdf,
22242269
servername,
22252270
mobile_emulator,

seleniumbase/fixtures/base_case.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3171,6 +3171,7 @@ def get_new_driver(
31713171
user_data_dir=None,
31723172
extension_zip=None,
31733173
extension_dir=None,
3174+
page_load_strategy=None,
31743175
external_pdf=None,
31753176
is_mobile=None,
31763177
d_width=None,
@@ -3215,6 +3216,7 @@ def get_new_driver(
32153216
user_data_dir - Chrome's User Data Directory to use (Chrome-only)
32163217
extension_zip - A Chrome Extension ZIP file to use (Chrome-only)
32173218
extension_dir - A Chrome Extension folder to use (Chrome-only)
3219+
page_load_strategy - the option to change pageLoadStrategy (Chrome)
32183220
external_pdf - "plugins.always_open_pdf_externally": True. (Chrome)
32193221
is_mobile - the option to use the mobile emulator (Chrome-only)
32203222
d_width - the device width of the mobile emulator (Chrome-only)
@@ -3319,6 +3321,8 @@ def get_new_driver(
33193321
extension_zip = self.extension_zip
33203322
if extension_dir is None:
33213323
extension_dir = self.extension_dir
3324+
if page_load_strategy is None:
3325+
page_load_strategy = self.page_load_strategy
33223326
if external_pdf is None:
33233327
external_pdf = self.external_pdf
33243328
test_id = self.__get_test_id()
@@ -3378,6 +3382,7 @@ def get_new_driver(
33783382
user_data_dir=user_data_dir,
33793383
extension_zip=extension_zip,
33803384
extension_dir=extension_dir,
3385+
page_load_strategy=page_load_strategy,
33813386
external_pdf=external_pdf,
33823387
test_id=test_id,
33833388
mobile_emulator=is_mobile,
@@ -12528,6 +12533,7 @@ def setUp(self, masterqa_mode=False):
1252812533
self.user_data_dir = sb_config.user_data_dir
1252912534
self.extension_zip = sb_config.extension_zip
1253012535
self.extension_dir = sb_config.extension_dir
12536+
self.page_load_strategy = sb_config.page_load_strategy
1253112537
self.external_pdf = sb_config.external_pdf
1253212538
self._final_debug = sb_config.final_debug
1253312539
self.window_size = sb_config.window_size
@@ -12809,6 +12815,7 @@ def setUp(self, masterqa_mode=False):
1280912815
user_data_dir=self.user_data_dir,
1281012816
extension_zip=self.extension_zip,
1281112817
extension_dir=self.extension_dir,
12818+
page_load_strategy=self.page_load_strategy,
1281212819
external_pdf=self.external_pdf,
1281312820
is_mobile=self.mobile_emulator,
1281412821
d_width=self.__device_width,

seleniumbase/fixtures/constants.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,13 @@ class ValidEnvs:
3737
]
3838

3939

40+
class PageLoadStrategy:
41+
# Usage Example => "--pls=none"
42+
NORMAL = "normal"
43+
EAGER = "eager"
44+
NONE = "none"
45+
46+
4047
class Files:
4148
DOWNLOADS_FOLDER = "downloaded_files"
4249
ARCHIVED_DOWNLOADS_FOLDER = "archived_files"

seleniumbase/plugins/pytest_plugin.py

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@ def pytest_addoption(parser):
5656
--firefox-pref=SET (Set a Firefox preference:value set, comma-separated.)
5757
--extension-zip=ZIP (Load a Chrome Extension .zip|.crx, comma-separated.)
5858
--extension-dir=DIR (Load a Chrome Extension directory, comma-separated.)
59+
--pls=PLS (Set pageLoadStrategy on Chrome: "normal", "eager", or "none".)
5960
--headless (Run tests in headless mode. The default arg on Linux OS.)
6061
--headed (Run tests in headed/GUI mode on Linux OS.)
6162
--xvfb (Run tests using the Xvfb virtual display server on Linux OS.)
@@ -565,6 +566,22 @@ def pytest_addoption(parser):
565566
(Can also be a comma-separated list of directories.)
566567
Default: None.""",
567568
)
569+
parser.addoption(
570+
"--pls",
571+
"--page_load_strategy",
572+
"--page-load-strategy",
573+
action="store",
574+
dest="page_load_strategy",
575+
type=str.lower,
576+
choices=(
577+
constants.PageLoadStrategy.NORMAL,
578+
constants.PageLoadStrategy.EAGER,
579+
constants.PageLoadStrategy.NONE,
580+
),
581+
default=None,
582+
help="""This option sets Chrome's pageLoadStrategy.
583+
List of choices: "normal", "eager", "none".""",
584+
)
568585
parser.addoption(
569586
"--headless",
570587
action="store_true",
@@ -1221,6 +1238,7 @@ def pytest_configure(config):
12211238
sb_config.firefox_pref = config.getoption("firefox_pref")
12221239
sb_config.extension_zip = config.getoption("extension_zip")
12231240
sb_config.extension_dir = config.getoption("extension_dir")
1241+
sb_config.page_load_strategy = config.getoption("page_load_strategy")
12241242
sb_config.with_testing_base = config.getoption("with_testing_base")
12251243
sb_config.with_db_reporting = config.getoption("with_db_reporting")
12261244
sb_config.with_s3_logging = config.getoption("with_s3_logging")

seleniumbase/plugins/selenium_plugin.py

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,12 +38,14 @@ class SeleniumBrowser(Plugin):
3838
--firefox-pref=SET (Set a Firefox preference:value set, comma-separated.)
3939
--extension-zip=ZIP (Load a Chrome Extension .zip|.crx, comma-separated.)
4040
--extension-dir=DIR (Load a Chrome Extension directory, comma-separated.)
41+
--pls=PLS (Set pageLoadStrategy on Chrome: "normal", "eager", or "none".)
4142
--headless (Run tests in headless mode. The default arg on Linux OS.)
4243
--headed (Run tests in headed/GUI mode on Linux OS.)
4344
--xvfb (Run tests using the Xvfb virtual display server on Linux OS.)
4445
--locale=LOCALE_CODE (Set the Language Locale Code for the web browser.)
4546
--interval=SECONDS (The autoplay interval for presentations & tour steps)
4647
--start-page=URL (The starting URL for the web browser when tests begin.)
48+
--skip-js-waits (Skip waiting for readyState to be complete or Angular.)
4749
--time-limit=SECONDS (Safely fail any test that exceeds the time limit.)
4850
--slow (Slow down the automation. Faster than using Demo Mode.)
4951
--demo (Slow down and visually see test actions as they occur.)
@@ -304,6 +306,21 @@ def options(self, parser, env):
304306
(Can also be a comma-separated list of directories.)
305307
Default: None.""",
306308
)
309+
parser.add_option(
310+
"--pls",
311+
"--page_load_strategy",
312+
"--page-load-strategy",
313+
action="store",
314+
dest="page_load_strategy",
315+
choices=(
316+
constants.PageLoadStrategy.NORMAL,
317+
constants.PageLoadStrategy.EAGER,
318+
constants.PageLoadStrategy.NONE,
319+
),
320+
default=None,
321+
help="""This option sets Chrome's pageLoadStrategy.
322+
List of choices: "normal", "eager", "none".""",
323+
)
307324
parser.add_option(
308325
"--headless",
309326
action="store_true",
@@ -772,12 +789,15 @@ def beforeTest(self, test):
772789
test.test.locale_code = self.options.locale_code
773790
test.test.interval = self.options.interval
774791
test.test.start_page = self.options.start_page
792+
if self.options.skip_js_waits:
793+
settings.SKIP_JS_WAITS = True
775794
test.test.protocol = self.options.protocol
776795
test.test.servername = self.options.servername
777796
test.test.port = self.options.port
778797
test.test.user_data_dir = self.options.user_data_dir
779798
test.test.extension_zip = self.options.extension_zip
780799
test.test.extension_dir = self.options.extension_dir
800+
test.test.page_load_strategy = self.options.page_load_strategy
781801
test.test.chromium_arg = self.options.chromium_arg
782802
test.test.firefox_arg = self.options.firefox_arg
783803
test.test.firefox_pref = self.options.firefox_pref

0 commit comments

Comments
 (0)