Skip to content

Commit

Permalink
Fix #30220 -- Headless browser mode for selenium test
Browse files Browse the repository at this point in the history
Both Chrome and Firefox support a new headless mode now. Besides
being faster, it also is more reliable as well as convenient since
there are no windows popping up.
  • Loading branch information
codingjoe committed Apr 6, 2019
1 parent 79065b5 commit e908985
Show file tree
Hide file tree
Showing 3 changed files with 26 additions and 1 deletion.
17 changes: 16 additions & 1 deletion django/test/selenium.py
Expand Up @@ -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):
"""
Expand Down Expand Up @@ -62,19 +64,32 @@ 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
return webdriver.Remote(
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')
Expand Down
4 changes: 4 additions & 0 deletions docs/internals/contributing/writing-code/unit-tests.txt
Expand Up @@ -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:
Expand Down
6 changes: 6 additions & 0 deletions tests/runtests.py
Expand Up @@ -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.',
Expand Down Expand Up @@ -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:
Expand Down

0 comments on commit e908985

Please sign in to comment.