Skip to content

Make --headless mode the default setting on Linux #348

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 8 commits into from
Jul 25, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
[<img src="https://cdn2.hubspot.net/hubfs/100006/images/super_logo_4d.png" title="SeleniumBase" height="48">](https://github.com/seleniumbase/SeleniumBase/blob/master/README.md)
[<img src="https://cdn2.hubspot.net/hubfs/100006/images/super_logo_6.png" title="SeleniumBase" height="48">](https://github.com/seleniumbase/SeleniumBase/blob/master/README.md)

[<img src="https://img.shields.io/github/release/seleniumbase/SeleniumBase.svg" />](https://github.com/seleniumbase/SeleniumBase/releases) [<img src="https://dev.azure.com/seleniumbase/seleniumbase/_apis/build/status/seleniumbase.SeleniumBase?branchName=master" />](https://dev.azure.com/seleniumbase/seleniumbase/_build/latest?definitionId=1&branchName=master) [<img src="https://travis-ci.org/seleniumbase/SeleniumBase.svg?branch=master" alt="Build Status" />](https://travis-ci.org/seleniumbase/SeleniumBase) [<img src="https://badges.gitter.im/seleniumbase/SeleniumBase.svg" alt="Join the Gitter Chat" />](https://gitter.im/seleniumbase/SeleniumBase) [<img src="https://img.shields.io/badge/license-MIT-22BBCC.svg" alt="MIT License" />](https://github.com/seleniumbase/SeleniumBase/blob/master/LICENSE) [<img src="https://img.shields.io/github/stars/seleniumbase/seleniumbase.svg" alt="GitHub Stars" />](https://github.com/seleniumbase/SeleniumBase/stargazers)<br />

Expand Down Expand Up @@ -60,7 +60,7 @@ cd examples
pytest my_first_test.py --browser=chrome
```
* Chrome is the default browser if not specified with ``--browser=BROWSER``.
* You MUST add ``--headless`` for your tests to run on a headless machine (No GUI). You can also run in headless mode on any machine.
* On Linux ``--headless`` is the default behavior (running with no GUI). You can also run in headless mode on any OS. If your Linux machine has a GUI and you want to see the web browser as tests run, add ``--headed`` or ``--gui``.

**Check out [my_first_test.py](https://github.com/seleniumbase/SeleniumBase/blob/master/examples/my_first_test.py) to see what a simple test looks like:**
* <i>By default, [CSS Selectors](https://www.w3schools.com/cssref/css_selectors.asp) are used for finding page elements.</i>
Expand Down Expand Up @@ -169,7 +169,7 @@ pytest test_suite.py --browser=chrome
pytest test_suite.py --browser=firefox
```

If you want to run tests headlessly, use ``--headless``, which you'll need to do if your system lacks a GUI interface. Even if your system does have a GUI interface, it may still support headless browser automation.
If you want to run tests headlessly, use ``--headless``, which you'll need to do if your system lacks a GUI interface (``--headless`` is the default setting on Linux). Even if your system does have a GUI interface, it may still support headless browser automation.

To run Pytest multithreaded on multiple CPUs at the same time, add ``-n=NUM`` or ``-n NUM`` on the command line, where NUM is the number of CPUs you want to use.

Expand Down
1 change: 1 addition & 0 deletions examples/raw_parameter_script.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
b = MyTestClass("test_basic")
b.browser = "chrome"
b.headless = False
b.headed = False
b.servername = "localhost"
b.port = 4444
b.data = None
Expand Down
2 changes: 2 additions & 0 deletions help_docs/method_summary.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ self.open(url)

self.open_url(url)

self.get(url)

self.visit(url)

self.click(selector, by=By.CSS_SELECTOR, timeout=settings.SMALL_TIMEOUT, delay=0)
Expand Down
16 changes: 13 additions & 3 deletions seleniumbase/fixtures/base_case.py
Original file line number Diff line number Diff line change
Expand Up @@ -92,11 +92,15 @@ def open(self, url):
self.__demo_mode_pause_if_active()

def open_url(self, url):
""" Same as open() """
""" Same as open() - Original saved for backwards compatibility. """
self.open(url)

def get(self, url):
""" Same as open() - WebDriver uses this method name. """
self.open(url)

def visit(self, url):
""" Same as open() """
""" Same as open() - Some JS frameworks use this method name. """
self.open(url)

def click(self, selector, by=By.CSS_SELECTOR,
Expand Down Expand Up @@ -3170,6 +3174,7 @@ def setUp(self, masterqa_mode=False):
self.with_selenium = sb_config.with_selenium # Should be True
self.headless = sb_config.headless
self.headless_active = False
self.headed = sb_config.headed
self.log_path = sb_config.log_path
self.with_testing_base = sb_config.with_testing_base
self.with_basic_test_info = sb_config.with_basic_test_info
Expand Down Expand Up @@ -3473,7 +3478,12 @@ def tearDown(self):
self.__quit_all_drivers()
if self.headless:
if self.headless_active:
self.display.stop()
try:
self.display.stop()
except AttributeError:
pass
except Exception:
pass
self.display = None
if self.with_db_reporting:
if has_exception:
Expand Down
27 changes: 24 additions & 3 deletions seleniumbase/plugins/pytest_plugin.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@

import optparse
import pytest
import sys
from seleniumbase import config as sb_config
from seleniumbase.core import log_helper
from seleniumbase.core import proxy_helper
Expand Down Expand Up @@ -159,8 +160,18 @@ def pytest_addoption(parser):
action="store_true",
dest='headless',
default=False,
help="""Using this makes Webdriver run headlessly,
which is required on headless machines.""")
help="""Using this makes Webdriver run web browsers
headlessly, which is required on headless machines.
Default: False on Mac/Windows. True on Linux.""")
parser.addoption('--headed', '--gui',
action="store_true",
dest='headed',
default=False,
help="""Using this makes Webdriver run web browsers with
a GUI when running tests on Linux machines.
(The default setting on Linux is headless.)
(The default setting on Mac or Windows is headed.)
""")
parser.addoption('--is_pytest', '--is-pytest',
action="store_true",
dest='is_pytest',
Expand Down Expand Up @@ -257,6 +268,7 @@ def pytest_configure(config):
sb_config.with_selenium = config.getoption('with_selenium')
sb_config.user_agent = config.getoption('user_agent')
sb_config.headless = config.getoption('headless')
sb_config.headed = config.getoption('headed')
sb_config.extension_zip = config.getoption('extension_zip')
sb_config.extension_dir = config.getoption('extension_dir')
sb_config.with_testing_base = config.getoption('with_testing_base')
Expand Down Expand Up @@ -285,7 +297,16 @@ def pytest_configure(config):
sb_config.save_screenshot = config.getoption('save_screenshot')
sb_config.visual_baseline = config.getoption('visual_baseline')
sb_config.timeout_multiplier = config.getoption('timeout_multiplier')
sb_config.pytest_html_report = config.getoption("htmlpath") # --html=FILE
sb_config.pytest_html_report = config.getoption('htmlpath') # --html=FILE

if "linux" in sys.platform and (
not sb_config.headed and not sb_config.headless):
print(
"(Running with --headless on Linux. "
"Use --headed or --gui to override.)")
sb_config.headless = True
if not sb_config.headless:
sb_config.headed = True

if sb_config.with_testing_base:
log_helper.log_folder_setup(sb_config.log_path, sb_config.archive_logs)
Expand Down
47 changes: 40 additions & 7 deletions seleniumbase/plugins/selenium_plugin.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@
by providing a WebDriver object for the tests to use.
"""

import sys
from nose.plugins import Plugin
from pyvirtualdisplay import Display
from seleniumbase.core import proxy_helper
from seleniumbase.fixtures import constants

Expand All @@ -25,6 +25,7 @@ class SeleniumBrowser(Plugin):
self.options.extension_zip -- load a Chrome Extension ZIP (--extension_zip)
self.options.extension_dir -- load a Chrome Extension DIR (--extension_dir)
self.options.headless -- the option to run headlessly (--headless)
self.options.headed -- the option to run with a GUI on Linux (--headed)
self.options.demo_mode -- the option to slow down Selenium (--demo_mode)
self.options.demo_sleep -- Selenium action delay in DemoMode (--demo_sleep)
self.options.highlights -- # of highlight animations shown (--highlights)
Expand Down Expand Up @@ -128,8 +129,18 @@ def options(self, parser, env):
action="store_true",
dest='headless',
default=False,
help="""Using this makes Webdriver run headlessly,
which is required on headless machines.""")
help="""Using this makes Webdriver run web browsers headlessly,
which is required on headless machines.
Default: False on Mac/Windows. True on Linux.""")
parser.add_option(
'--headed', '--gui',
action="store_true",
dest='headed',
default=False,
help="""Using this makes Webdriver run web browsers with
a GUI when running tests on Linux machines.
(The default setting on Linux is headless.)
(The default setting on Mac or Windows is headed.)""")
parser.add_option(
'--demo_mode', '--demo-mode', '--demo',
action="store_true",
Expand Down Expand Up @@ -233,6 +244,7 @@ def beforeTest(self, test):
test.test.browser = self.options.browser
test.test.cap_file = self.options.cap_file
test.test.headless = self.options.headless
test.test.headed = self.options.headed
test.test.servername = self.options.servername
test.test.port = self.options.port
test.test.user_data_dir = self.options.user_data_dir
Expand All @@ -256,10 +268,26 @@ def beforeTest(self, test):
if test.test.servername != "localhost":
# Use Selenium Grid (Use --server=127.0.0.1 for localhost Grid)
test.test.use_grid = True
if "linux" in sys.platform and (
not self.options.headed and not self.options.headless):
print(
"(Running with --headless on Linux. "
"Use --headed or --gui to override.)")
self.options.headless = True
test.test.headless = True
if not self.options.headless:
self.options.headed = True
test.test.headed = True
if self.options.headless:
self.display = Display(visible=0, size=(1920, 1200))
self.display.start()
self.headless_active = True
try:
from pyvirtualdisplay import Display
self.display = Display(visible=0, size=(1440, 1080))
self.display.start()
self.headless_active = True
except Exception:
# pyvirtualdisplay might not be necessary anymore because
# Chrome and Firefox now have built-in headless displays
pass
# The driver will be received later
self.driver = None
test.test.driver = self.driver
Expand All @@ -278,4 +306,9 @@ def afterTest(self, test):
pass
if self.options.headless:
if self.headless_active:
self.display.stop()
try:
self.display.stop()
except AttributeError:
pass
except Exception:
pass
2 changes: 1 addition & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@

setup(
name='seleniumbase',
version='1.25.6',
version='1.26.0',
description='Reliable Browser Automation & Testing Framework',
long_description=long_description,
long_description_content_type='text/markdown',
Expand Down