diff --git a/django/test/selenium.py b/django/test/selenium.py index 6e6badd933c54..26bbce5f3b559 100644 --- a/django/test/selenium.py +++ b/django/test/selenium.py @@ -17,6 +17,8 @@ class SeleniumTestCaseBase(type(LiveServerTestCase)): external_host = None # Sentinel value to differentiate browser-specific instances. browser = None + # Run browsers in headless mode + headless = False def __new__(cls, name, bases, attrs): """ @@ -62,11 +64,24 @@ def __new__(cls, name, bases, attrs): def import_webdriver(cls, browser): return import_string("selenium.webdriver.%s.webdriver.WebDriver" % browser) + @classmethod + def import_options(cls, browser): + return import_string("selenium.webdriver.%s.options.Options" % browser) + @classmethod def get_capability(cls, browser): from selenium.webdriver.common.desired_capabilities import DesiredCapabilities return getattr(DesiredCapabilities, browser.upper()) + def create_options(self): + options = self.import_options(self.browser)() + if self.headless: + try: + options.headless = True + except AttributeError: + pass # only Chrome and Firefox support the headless mode + return options + def create_webdriver(self): if self.selenium_hub: from selenium import webdriver @@ -74,7 +89,7 @@ def create_webdriver(self): command_executor=self.selenium_hub, desired_capabilities=self.get_capability(self.browser), ) - return self.import_webdriver(self.browser)() + return self.import_webdriver(self.browser)(options=self.create_options()) @tag('selenium') diff --git a/docs/internals/contributing/writing-code/unit-tests.txt b/docs/internals/contributing/writing-code/unit-tests.txt index 51d1e61313597..a915fe76c6c35 100644 --- a/docs/internals/contributing/writing-code/unit-tests.txt +++ b/docs/internals/contributing/writing-code/unit-tests.txt @@ -210,6 +210,10 @@ See the `selenium.webdriver`_ package for the list of available browsers. Specifying ``--selenium`` automatically sets ``--tags=selenium`` to run only the tests that require selenium. +Some browsers such as Chrome and Firefox support a headless mode, which can be +faster and more stable in conjunction with Selenium tests. Add the +``--selenium-headless`` option to enable the headless mode. + .. _selenium.webdriver: https://github.com/SeleniumHQ/selenium/tree/master/py/selenium/webdriver .. _running-unit-tests-dependencies: diff --git a/tests/runtests.py b/tests/runtests.py index 0861ec879843f..67186104bb8b5 100755 --- a/tests/runtests.py +++ b/tests/runtests.py @@ -437,6 +437,10 @@ def paired_tests(paired_test, options, test_labels, parallel): '--selenium', action=ActionSelenium, metavar='BROWSERS', help='A comma-separated list of browsers to run the Selenium tests against.', ) + parser.add_argument( + '--selenium-headless', action='store_true', + help='Run selenium tests in headless mode, if the browser support the option.' + ) parser.add_argument( '--selenium-hub', help='A URL for a selenium hub instance to use in combination with --selenium.', @@ -489,6 +493,8 @@ def paired_tests(paired_test, options, test_labels, parallel): if options.selenium_hub: SeleniumTestCaseBase.selenium_hub = options.selenium_hub SeleniumTestCaseBase.external_host = options.external_host + if options.selenium_headless: + SeleniumTestCaseBase.headless = True SeleniumTestCaseBase.browsers = options.selenium if options.bisect: