Skip to content

Commit

Permalink
Add a capabilities marker for and remove the dedicated Sauce Labs vis…
Browse files Browse the repository at this point in the history
…ibility marker
  • Loading branch information
davehunt committed Aug 20, 2015
1 parent 50c8063 commit 4f5522c
Show file tree
Hide file tree
Showing 5 changed files with 64 additions and 58 deletions.
71 changes: 29 additions & 42 deletions docs/user_guide.rst
Original file line number Diff line number Diff line change
Expand Up @@ -187,13 +187,6 @@ Below is an example ``setup.cfg`` showing the configuration options:
[pytest]
sauce_labs_username = username
sauce_labs_api_key = secret
sauce_labs_job_visibility = public
The `sauce_labs_job_visibility` entry is used to determine who you share your
Sauce Labs jobs with. Check the
`documentation <https://saucelabs.com/docs/additional-config#sharing>`_ for the
accepted values. If not set, this defaults to
`public restricted <https://saucelabs.com/docs/additional-config#restricted>`_.
Running tests
~~~~~~~~~~~~~
Expand All @@ -210,32 +203,6 @@ the ``--capability`` command line arguments. See the
`test configuration documentation <https://docs.saucelabs.com/reference/test-configuration/>`_
for full details of what can be configured.

Job visibility
~~~~~~~~~~~~~~

You can specify the job sharing level for individual tests by setting a mark on
the test method. This takes priority over the ``sauce_labs_job_visibility``
entry in the configuration file:

.. code-block:: python
import pytest
@pytest.mark.sauce_labs_job_visibility('public')
def test_public(selenium):
assert True
You can also explicitly mark the test as private:

.. code-block:: python
import pytest
@pytest.mark.sauce_labs_job_visibility('private')
def test_private(selenium):
assert True
For the full list of accepted values, check the
`Sauce Labs documentation <https://saucelabs.com/docs/additional-config#sharing>`_.

BrowserStack
------------

Expand Down Expand Up @@ -304,13 +271,25 @@ the ``--capability`` command line arguments. See the
`test options <http://testingbot.com/support/other/test-options>`_
for full details of what can be configured.

Capabilities
------------
Specifying Capabilities
***********************

Configuration options are specified using a capabilities dictionary. This is
required when using a Selenium server to specify the target environment, but
can also be used to configure local drivers.

Command Line Capabilities
-------------------------

Simple capabilities can be set or overridden on the command line:

.. code-block:: bash
$ py.test --driver Remote --capability browserName Firefox
Capabilities Files
------------------

To specify capabilities, you can provide a JSON file on the command line using
the `pytest-variables <https://github.com/davehunt/pytest-variables>`_ plugin.
For example if you had a ``capabilties.json`` containing your capabilities, you
Expand All @@ -325,14 +304,10 @@ The following is an example of a variables file including capabilities:
"platform": "MAC" }
}
Simple capabilities can be set or overridden on the command line:

.. code-block:: bash
$ py.test --driver Remote --capability browserName Firefox
Capabilities Fixture
--------------------

You can also add or change capabilities by overwriting the ``capabilities``
fixture:
You can add or change capabilities by overwriting the ``capabilities`` fixture:

.. code-block:: python
Expand All @@ -342,6 +317,18 @@ fixture:
capabilities['tags'] = ['tag1', 'tag2', 'tag3']
return capabilities
Capabilities Marker
-------------------

You can add or change capabilities using the ``capabilities`` marker:

.. code-block:: python
import pytest
@pytest.mark.capabilities(foo='bar')
def test_capabilities(selenium):
selenium.get('http://www.example.com')
Common Selenium Setup
*********************

Expand Down
12 changes: 2 additions & 10 deletions pytest_selenium/cloud/saucelabs.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,17 +35,9 @@ def start_driver(self, item, capabilities):
keywords = item.keywords
marks = [m for m in keywords.keys() if isinstance(
keywords[m], MarkInfo)]
tags = capabilities.get('tags', []) + marks
try:
job_visibility = item.keywords['sauce_labs_job_visibility'].args[0]
except (IndexError, KeyError):
# mark is not present or has no value
job_visibility = item.config.getini('sauce_labs_job_visibility')

test_id = '.'.join(self.split_class_and_test_names(item.nodeid))
capabilities.update({
'name': test_id,
'public': job_visibility})
capabilities['name'] = test_id
tags = capabilities.get('tags', []) + marks
if tags:
capabilities['tags'] = tags
executor = 'http://{0}:{1}@ondemand.saucelabs.com:80/wd/hub'.format(
Expand Down
10 changes: 7 additions & 3 deletions pytest_selenium/driver.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,14 @@ def start_driver(item, capabilities):
options = item.config.option
if options.driver is None:
raise pytest.UsageError('--driver must be specified')
_capabilities = copy.deepcopy(capabilities) # make a copy
capabilities_marker = item.get_marker('capabilities')
if capabilities_marker is not None:
# add capabilities from the marker
_capabilities.update(capabilities_marker.kwargs)
# retrieve driver from appropriate method based on the value of --driver
driver = globals().get(
'{0}_driver'.format(options.driver.lower()))(
item, copy.deepcopy(capabilities))
driver = globals().get('{0}_driver'.format(
options.driver.lower()))(item, _capabilities)
if options.event_listener is not None:
# import the specified event listener and wrap the driver instance
mod_name, class_name = options.event_listener.rsplit('.', 1)
Expand Down
12 changes: 9 additions & 3 deletions pytest_selenium/pytest_selenium.py
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,15 @@ def selenium(request, _sensitive_skipping, capabilities):
return driver


def pytest_configure(config):
if hasattr(config, 'slaveinput'):
return # xdist slave
config.addinivalue_line(
'markers', 'capabilities(kwargs): add or change existing '
'capabilities. specify capabilities as keyword arguments, for example '
'capabilities(foo=''bar'')')


def pytest_runtest_makereport(__multicall__, item, call):
pytest_html = item.config.pluginmanager.getplugin('html')
extra_summary = []
Expand Down Expand Up @@ -151,9 +160,6 @@ def pytest_addoption(parser):
parser.addini('sauce_labs_api_key',
help='sauce labs api key',
default=os.getenv('SAUCELABS_API_KEY'))
parser.addini('sauce_labs_job_visibility',
help='default visibility for jobs',
default='public restricted')

# testingbot configuration
parser.addini('testingbot_key',
Expand Down
17 changes: 17 additions & 0 deletions testing/test_capabilities.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,3 +34,20 @@ def capabilities():
return {'foo': 'bar'}
""")
testdir.quick_qa(testfile, passed=1)


def test_mark(testdir):
# set a capability that we can influence and check on the selenium object
file_test = testdir.makepyfile("""
import pytest
@pytest.mark.nondestructive
@pytest.mark.capabilities(acceptSslCerts=False)
def test_capabilities(selenium):
print selenium.capabilities
assert selenium.capabilities['acceptSslCerts'] == False
@pytest.mark.nondestructive
def test_default(selenium):
assert selenium.capabilities['acceptSslCerts'] == True
""")
testdir.quick_qa(file_test, tests=2, passed=2)

0 comments on commit 4f5522c

Please sign in to comment.