Full pytest-dash documentation¶
Usage¶
Write integration tests¶
pytest-dash
provides fixtures and helper functions
to write Dash integration tests.
To start a Dash instance, you can use a dash_threaded
or
dash_subprocess
fixture.
The fixture will start the server when called and wait until the application has been loaded by the browser. The server will be automatically closed in the test teardown.
dash_threaded example¶
Start a dash application in a thread, close the server in teardown.
In this example we count the number of times a callback method is called
each time a clicked is called and assert the text output of a callback
by using wait_for_text_to_equal()
.
import dash
from dash.dependencies import Output, Input
from dash.exceptions import PreventUpdate
import dash_html_components as html
from pytest_dash import wait_for
def test_application(dash_threaded):
# The selenium driver is available on the fixture.
driver = dash_threaded.driver
app = dash.Dash(__name__)
counts = {'clicks': 0}
app.layout = html.Div([
html.Div('My test layout', id='out'),
html.Button('click me', id='click-me')
])
@app.callback(
Output('out', 'children'),
[Input('click-me', 'n_clicks')]
)
def on_click(n_clicks):
if n_clicks is None:
raise PreventUpdate
counts['clicks'] += 1
return 'Clicked: {}'.format(n_clicks)
dash_threaded(app)
btn = wait_for.wait_for_element_by_css_selector(driver, '#click-me')
btn.click()
wait_for.wait_for_text_to_equal(driver, '#out', 'Clicked: 1')
assert counts['clicks'] == 1
dash_subprocess example¶
Start the server in subprocess with waitress-serve
.
Kill the process in teardown.
from pytest_dash.wait_for import wait_for_text_to_equal
def test_subprocess(dash_subprocess):
driver = dash_subprocess.driver
dash_subprocess('test_apps.simple_app')
value_input = driver.find_element_by_id('value')
value_input.clear()
value_input.send_keys('Hello dash subprocess')
wait_for_text_to_equal(driver, '#out', 'Hello dash subprocess')
Note
This fixture is slower than threaded due to the process spawning.
See also
Fixtures: | dash_threaded dash_subprocess |
---|
Helpers¶
Importing applications¶
Import existing Dash applications from a file with
import_app()
.
The application must be named app.
Example: |
---|
from pytest_dash.application_runners import import_app
def test_application(dash_threaded):
app = import_app('my_app')
...
Write declarative scenario tests¶
Pytest-dash include a declarative way to generate tests in a yaml format.
When pytest finds yaml files prefixed with test_
in a directory, it will
generate tests from a Tests
object.
Schema¶
A yaml test file contains scenario definitions and a list of parametrized of scenarios to execute.
Globals¶
application: | Global default application to use in the tests if no option supplied. |
---|---|
Tests: | List of scenario to generate tests for. Test item props are used as parameter. |
Scenario object¶
parameters: | Object where the keys will be used to create a variable dictionary to
use in behavior commands. Use a parameter in commands by prefixing the key
with |
||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|
application: |
|
Scenario: # Key of the test
parameters: # Optional values to use in test
value:
default: 4
application: # The application settings to use in the test
path: test_apps.simple_app # Dot notation path to the app file.
options: # Application options such as port
port: 8051
event: # List of actions describing what happen.
- "enter $value in #input"
outcome: # The expected result of the event.
- "text in #output should be $value"
Tests: # List of all the scenarios to execute.
- Scenario # Runs Scenario with the default parameter.
- Scenario
value: 8 # Override the default parameter.
Syntax¶
There is 3 kind of rule for the grammar:
value
, return a value.command
, execute an action.comparison
, compare two value.
Rule | Kind | Example | Description |
---|---|---|---|
element_id | value | #my-element-id |
Find a single element by id |
element_selector | value | {#my-element-id > span} |
Find a single by selector |
elements_selector | value | *{#my-element-id > span} |
Find multiple elements by selector, actions will be executed on all elements (Currently click & length assertions) |
element_xpath | value | [//*[@id="btn-1"]] |
Find a single element by xpath |
elements_xpath | value | *[//div[@id="container"]/span] |
Find multiple elements by xpath. |
element_prop | value | #my-input.value |
A property of an element to use in comparisons. |
eq | comparison | #my-input.value should be 1 , #my-input.value == 1 |
Equality comparison |
lt | comparison | #my-input.value < 3 , #my-input.value should be less than 3 |
The value should be less than. |
lte | comparison | #my-input.value <= 3 ,``#my-input.value should be less or equal than 3`` |
The value on the left should be less or equal to. |
gt | comparison | #my-input.value > 3 , #my-input.value should be greater than 3 |
Value should be greater. |
gte | comparison | #my-input.value >= 3 , #my-input.value should be greater or equal than 3 |
Greater or equal comparison. |
text_equal | comparison | text in #output should be "Foo bar" |
Special comparison for text attribute, it uses the wait_for api. |
prop_compare | comparison | #output.value should be 3 |
Property comparison uses the wait_for api |
style_compare | comparison | style "padding" of #btn should be "3px" |
wait_for comparison for a style attribute of an element. |
clear | command | clear #my-input |
Clear the value of an element. |
click | command | click #my-btn |
Click on an element, the element must be visible to be clickable. |
send_value | command | enter "Foo bar" in #my-input |
Send keyboard input to an element. |
Note
The syntax can be extended with Hooks.
Examples¶
Application: |
---|
import dash
from dash.dependencies import Output, Input
from dash.exceptions import PreventUpdate
import dash_html_components as html
import dash_core_components as dcc
app = dash.Dash(__name__)
app.layout = html.Div([
dcc.Input(id='value', placeholder='my-value'),
html.Div(['You entered: ', html.Span(id='out')]),
html.Button('style-btn', id='style-btn'),
html.Div('style-container', id='style-output'),
])
@app.callback(Output('out', 'children'), [Input('value', 'value')])
def on_value(value):
if value is None:
raise PreventUpdate
Test: |
---|
SimpleCallback:
description: Test a dcc.Input callback output to a html.Div when a html.Button is clicked\
parameters:
var1:
description: Value to send to the input
type: str
default: hello world
application:
path: test_apps.simple_app
port: 8051
event:
- "clear #value"
- "enter $var1 in #value"
outcome:
- "#value.value == $var1"
- 'text in {#out} should be $var1'
Tests:
- SimpleCallback
- SimpleCallback:
var1: foo bar
See also
Run tests¶
Use $ pytest tests --webdriver Chrome
to run all the test
The --webdriver
option is used for choosing the selenium driver to use.
Choose from:
Note
The driver must be available on your environment PATH.
See also
Please refer to https://selenium-python.readthedocs.io/installation.html for selenium installation.
Configuration¶
The default webdriver for a project can be specified in pytest.ini instead of having to enter it on the command line every time you run a test.
Example: | ./pytest.ini |
---|
[pytest]
webdriver = Chrome
Hooks¶
pytest_add_behaviors¶
The scenario event/outcome syntax can be extended with
the pytest_add_behaviors()
hook.
add_behavior
is a decorator with the following keywords arguments:
syntax
The syntax to match, it will be available under the name of the function in the parser.kind
value
default, A value can be used in commands and comparisons.command
, Complete custom line parsing.comparison
, A comparison shouldassert
something inside the function.
inline/tree/meta
Only one can to be set to true, default is inline, decorate the function withlark.v_args(inline=inline, tree=tree, meta=meta)
, lark.v_args docs.
Example: | tests/conftest.py |
---|
def pytest_add_behaviors(add_behavior):
@add_behavior('"eval("/.*/")"')
def evaluate(command):
return eval(command)
See also
Lark grammar reference https://lark-parser.readthedocs.io/en/latest/grammar/
pytest_setup_selenium¶
If you need to configure the selenium driver used by the plugin, you can use
the pytest_setup_selenium
hook.
Example: | tests/conftest.py |
---|
from selenium.webdriver.chrome.options import Options
def pytest_setup_selenium(driver_name):
options = Options()
options.headless = True
return {
'chrome_options': options,
}
pytest_dash¶
pytest_dash package¶
Submodules¶
pytest_dash.application_runners module¶
pytest_dash.behavior_parser module¶
Custom lark parser and transformer for dash behavior tests.
-
class
pytest_dash.behavior_parser.
BehaviorTransformer
(driver, variables=None)[source]¶ Bases:
lark.visitors.Transformer
,object
Transform and execute behavior commands.
-
__init__
(driver, variables=None)[source]¶ Parameters: driver (selenium.webdriver.remote.webdriver.WebDriver) – Selenium driver to find elements in the tree
-
element_id
(*args, **kwargs)[source]¶ Find an element by id when found in the tree.
Example: #dropdown
Kind: value Parameters: element_id – Text after #
-
element_prop
(*args, **kwargs)[source]¶ Property value of an element
Example: #element.prop
Kind: value
-
element_selector
(*args, **kwargs)[source]¶ Find an element by selector when found in the tree.
Example: {#radio-items > label:nth-child(9) > input[type="radio"]}
Kind: value Parameters: selector – Text contained between { & }
-
elements_xpath
(*args, **kwargs)[source]¶ Find all elements by xpath
Example: *[//div/span]
Kind: value
-
escape_string
(*args, **kwargs)[source]¶ Escaped string handler, remove the
"
from the token.Kind: value
-
prop_compare
(*args, **kwargs)[source]¶ Wait for a property to equal a value.
Example: #output.id should be "my-element"
Kind: comparison
-
send_value
(*args, **kwargs)[source]¶ Send key inputs to the element
Example: enter "Hello" in #input
Kind: command
-
style_compare
(*args, **kwargs)[source]¶ Compare a style value of an of element.
Example: style “color” of #style should be “rgba(0, 0, 255, 1)”
Kind: comparison
Parameters: - style – Name of the style property
- element – Element to find
- _ – eq
- value – Value to compare to the element style attribute.
Returns:
-
-
class
pytest_dash.behavior_parser.
BehaviorTransformerMeta
[source]¶ Bases:
type
Dynamically create a parser transformer with user defined behaviors
-
pytest_dash.behavior_parser.
parser_factory
(driver, variables=None, behaviors=None)[source]¶ Create a Lark parser with a BehaviorTransformer with the provided selenium driver to find the elements.
A new behavior transformer class is created and behaviors are assigned a transformer function from the supplied behaviors in the pytest_add_behaviors hook.
Parameters: - driver – Selenium driver to use when parsing elements.
- variables – Variables to use in the parser transformer.
- behaviors – Custom behaviors, come from plugin.behaviors.
Returns:
pytest_dash.behaviors module¶
pytest_dash.errors module¶
Pytest-dash errors.
-
exception
pytest_dash.errors.
DashAppLoadingError
[source]¶ Bases:
pytest_dash.errors.PytestDashError
The dash app failed to load
-
exception
pytest_dash.errors.
InvalidDriverError
[source]¶ Bases:
pytest_dash.errors.PytestDashError
An invalid selenium driver was specified.
-
exception
pytest_dash.errors.
MissingBehaviorError
[source]¶ Bases:
pytest_dash.errors.PytestDashError
A behavior was missing from the
-
exception
pytest_dash.errors.
NoAppFoundError
[source]¶ Bases:
pytest_dash.errors.PytestDashError
No app was found in the file.
-
exception
pytest_dash.errors.
PytestDashError
[source]¶ Bases:
exceptions.Exception
Base error for pytest-dash.
-
exception
pytest_dash.errors.
ServerCloseError
[source]¶ Bases:
pytest_dash.errors.PytestDashError
Pytest-dash had trouble closing a server.
pytest_dash.new_hooks module¶
Custom hooks for pytest dash
-
pytest_dash.new_hooks.
pytest_add_behaviors
(add_behavior)[source]¶ Use this hook to add custom behavior parsing.
Example conftest.py
def pytest_add_behavior(add_behavior): @add_behavior('Text to parse') def custom_parse_action(params): pass
Parameters: add_behavior – Decorator for a behavior handler function. Returns:
-
pytest_dash.new_hooks.
pytest_setup_selenium
(driver_name)[source]¶ Called before the driver is created, return a dictionary to use as kwargs for the driver init.
Parameters: driver_name (str) – The name of the driver specified by either cli argument or in pytest.ini. Returns: The dictionary of kwargs to give to the driver constructor.
pytest_dash.plugin module¶
pytest_dash.wait_for module¶
Utils methods for pytest-dash such wait_for wrappers
-
pytest_dash.wait_for.
wait_for_element_by_css_selector
(driver, selector, timeout=10.0)[source]¶ Wait until a single element is found and return it. This variant use the css selector api: https://www.w3schools.com/jsref/met_document_queryselector.asp
Parameters: - driver (selenium.webdriver.remote.webdriver.WebDriver) – Selenium driver
- selector (str) – CSS selector to find.
- timeout (float) – Maximum time to find the element.
Returns:
-
pytest_dash.wait_for.
wait_for_element_by_id
(driver, _id, timeout=10)[source]¶ Wait until a single element is found and return it. This variant find by id.
Parameters: - driver (selenium.webdriver.remote.webdriver.WebDriver) – Selenium driver
- _id – The id of the element to find.
- timeout (float) – Maximum time to find the element.
Returns:
-
pytest_dash.wait_for.
wait_for_element_by_xpath
(driver, xpath, timeout=10)[source]¶ Wait until a single element is found and return it. This variant use xpath to find the element. https://www.w3schools.com/xml/xml_xpath.asp
Parameters: - driver (selenium.webdriver.remote.webdriver.WebDriver) – Selenium driver
- xpath (str) – Xpath query string.
- timeout (float) – Maximum time to find the element.
Returns:
-
pytest_dash.wait_for.
wait_for_elements_by_css_selector
(driver, selector, timeout=10.0)[source]¶ Wait until all elements are found by the selector before the timeout.
Parameters: - driver (selenium.webdriver.remote.webdriver.WebDriver) – Selenium driver
- selector (str) – Search for elements
- timeout (float) – Maximum wait time
Returns: Found elements
-
pytest_dash.wait_for.
wait_for_elements_by_xpath
(driver, xpath, timeout=10)[source]¶ Wait until all are found before the timeout. This variant use xpath to find the elements. https://www.w3schools.com/xml/xml_xpath.asp
Parameters: - driver (selenium.webdriver.remote.webdriver.WebDriver) – Selenium driver
- xpath (str) – Xpath query string.
- timeout (float) – Maximum time to find the element.
Returns:
-
pytest_dash.wait_for.
wait_for_property_to_equal
(driver, selector, prop_name, prop_value, timeout=10)[source]¶ Wait for an element property to equal a value.
Parameters: - driver (selenium.webdriver.remote.webdriver.WebDriver) – Selenium driver
- selector (str) – Selector of the element to assert it’s property.
- prop_name (str) – The name of property.
- prop_value – The value to assert.
- timeout (float) – Maximum time.
Returns:
-
pytest_dash.wait_for.
wait_for_style_to_equal
(driver, selector, style_attribute, style_assertion, timeout=10)[source]¶ Wait for an element style attribute to equal.
Parameters: - driver (selenium.webdriver.remote.webdriver.WebDriver) – Selenium driver
- selector (str) – Selector of the element to assert it’s style property.
- style_attribute (str) – The name of the CSS attribute to assert.
- style_assertion (str) – The value to equal of CSS attribute.
- timeout (float) – Maximum time.
Returns:
-
pytest_dash.wait_for.
wait_for_text_to_equal
(driver, selector, text, timeout=10)[source]¶ Wait an element text found by css selector is equal to text.
Parameters: - driver (selenium.webdriver.remote.webdriver.WebDriver) – Selenium driver
- selector (str) – Selector of the element to assert it’s text property.
- text (str) – Text to equal.
- timeout (float) – Maximum time for the text to equal.
Returns:
Examples¶
dash_threaded example¶
Start a dash application in a thread, close the server in teardown.
In this example we count the number of times a callback method is called
each time a clicked is called and assert the text output of a callback
by using wait_for_text_to_equal()
.
import dash
from dash.dependencies import Output, Input
from dash.exceptions import PreventUpdate
import dash_html_components as html
from pytest_dash import wait_for
def test_application(dash_threaded):
# The selenium driver is available on the fixture.
driver = dash_threaded.driver
app = dash.Dash(__name__)
counts = {'clicks': 0}
app.layout = html.Div([
html.Div('My test layout', id='out'),
html.Button('click me', id='click-me')
])
@app.callback(
Output('out', 'children'),
[Input('click-me', 'n_clicks')]
)
def on_click(n_clicks):
if n_clicks is None:
raise PreventUpdate
counts['clicks'] += 1
return 'Clicked: {}'.format(n_clicks)
dash_threaded(app)
btn = wait_for.wait_for_element_by_css_selector(driver, '#click-me')
btn.click()
wait_for.wait_for_text_to_equal(driver, '#out', 'Clicked: 1')
assert counts['clicks'] == 1
dash_subprocess example¶
Start the server in subprocess with waitress-serve
.
Kill the process in teardown.
from pytest_dash.wait_for import wait_for_text_to_equal
def test_subprocess(dash_subprocess):
driver = dash_subprocess.driver
dash_subprocess('test_apps.simple_app')
value_input = driver.find_element_by_id('value')
value_input.clear()
value_input.send_keys('Hello dash subprocess')
wait_for_text_to_equal(driver, '#out', 'Hello dash subprocess')
Note
This fixture is slower than threaded due to the process spawning.
Component gallery behavior test¶
Application: |
---|
import dash
from dash.dependencies import Output, Input
from dash.exceptions import PreventUpdate
import dash_html_components as html
import dash_core_components as dcc
app = dash.Dash(__name__)
app.layout = html.Div([
dcc.Input(id='input'),
dcc.Dropdown(
id='dropdown',
options=[{
'label': str(x),
'value': str(x)
} for x in range(1, 10)]
),
dcc.RadioItems(
id='radio-items',
options=[{
'label': str(x),
'value': str(x)
} for x in range(1, 10)]
),
html.Div(id='input-output'),
html.Div(id='dropdown-output'),
html.Div(id='radio-items-output'),
html.Button('change-style', id='change-style'),
html.Div(
'Style changer',
id='style-output',
style={'backgroundColor': 'rgba(255, 0, 0, 1)'}
),
html.Div(
id='multi-elements-click',
children=[
html.Button('btn-1', id='btn-1'),
html.Button('btn-2', id='btn-2'),
html.Button('btn-3', id='btn-3'),
]
),
html.Div(id='multi-elements-outputs')
])
for i in (
'input',
'dropdown',
'radio-items',
):
@app.callback(
Output('{}-output'.format(i), 'children'), [Input(i, 'value')]
)
def _wrap(value):
if value is None:
raise PreventUpdate
return str(value)
@app.callback(
Output('style-output', 'style'), [Input('change-style', 'n_clicks')]
)
def on_style_change(n_clicks):
if n_clicks is None:
raise PreventUpdate
return {'backgroundColor': 'rgba(0, 0, 255, 1)'}
@app.callback(
Output('multi-elements-outputs', 'children'),
[Input('btn-{}'.format(x), 'n_clicks') for x in range(1, 4)],
)
def on_multi_click(*args):
return [html.Span(x) for x in args if x]
Test: |
---|
application:
path: test_apps.component_gallery
InputBehavior:
description: Test text can entered/customized in a Input component in behavior tests.
parameters:
value:
default: Input value
event:
- "enter $value in #input"
outcome:
- "text in #input-output should be $value"
DropdownBehavior:
description: Test that a dropdown value can be selected in behavior tests.
parameters:
value:
default: '1'
event:
- 'enter $value in {#dropdown .Select-input input}'
- 'click {#dropdown .Select .Select-menu-outer}'
outcome:
- 'text in #dropdown-output should be $value'
RadioItemsBehavior:
description: Test radio items value can be changed in behavior tests.
event:
- 'click {#radio-items > label:nth-child(9) > input[type="radio"]}'
outcome:
- "text in #radio-items-output should be 9"
- '{#radio-items > label:nth-child(9) > input[type="radio"]}.checked should be true'
StyleChangeButtonBehavior:
description: Test style assertions in behavior tests
event:
- 'style "background-color" of #style-output should be "rgba(255, 0, 0, 1)"'
- 'click #change-style'
outcome:
- 'style "background-color" of #style-output should be "rgba(0, 0, 255, 1)"'
MultiElementsBehavior:
description: Test multiple elements found.
event:
- 'click *{#multi-elements-click > button}'
outcome:
- '*{#multi-elements-outputs > span}.length == 3'
XpathBehavior:
description: Test xpath element find.
event:
- 'click [//*[@id="btn-1"]]'
outcome:
- '*[//div[@id="multi-elements-outputs"]/span].length should be 1'
Tests:
- InputBehavior
- InputBehavior:
value: Non default
- DropdownBehavior
- RadioItemsBehavior
- StyleChangeButtonBehavior
- MultiElementsBehavior
- XpathBehavior
MIT License
Copyright (c) 2018 Philippe Duval
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
Changelog¶
Versions follow Semantic Versioning
[2.0.0] - 2019-02-12¶
Added¶
- Behavior tests from yaml description. #54
- Plugin configuration hooks for selenium options (Currently only
webdriver
)- Configuration from commandline
- Configuration from pytest.ini file.
- Added xpath wait_for wrappers.
- Added wait_for wrappers for multi elements find.
- Customizable behavior parsing thru
pytest_add_behavior
hook.
Changed¶
- Application runners (dash_threaded, dash_subprocess) refactored to a context manager with own selenium driver.
- Driver argument changed to
--webdriver
[1.1.0] 2019-01-01¶
Added¶
- Base exception type:
PytestDashError
#23 DashAppLoadingError
#23- Add port option to
dash_threaded
anddash_subprocess
. #28 - Add
start_wait_time
option todash_threadred
for waiting after starting the thread, default to 1 sec. #28 - Add more
wait_for
wrappers #41wait_for_style_to_equal
wait_for_property_to_equal
wait_for_element_by_*
[1.0.1] 2018-12-05¶
Changed¶
- Syntax for
utils.import_app
changed to dot notation, same asdash_subprocess
.
[1.0.0] 2018-12-04¶
Added¶
- Added
dash_subprocess
fixture, runs a dash app in a subprocess waitress-serve command. utils.wait_for_text_to_equal
utils.wait_for_element_by_css_selector
Removed¶
dash_app
fixture.
Renamed¶
start_dash
fixture todash_threaded
[0.1.1] 2018-10-04¶
Contributing to pytest-dash¶
Getting started¶
Fork and clone the repo
Create and activate .. code-block:: guess
$ python -m venv venv $ . venv/bin/activate
Install the dependencies
$ pip install -r requirements.txt
The plugin needs to be installed to run the tests locally
$ pip install -e .
Coding style¶
Commit messages¶
Prefix your commit messages with an emoji according to this list adapted from: https://gist.github.com/parmentf/035de27d6ed1dce0b36a
Commit type | Emoji | ||||
---|---|---|---|---|---|
Initial commit |
|
||||
Version tag |
|
||||
New feature |
|
||||
Bugfix |
|
||||
Metadata |
|
||||
Documentation |
|
||||
Documenting source code |
|
||||
Performance |
|
||||
Cosmetic |
|
||||
Tests |
|
||||
Adding a test |
|
||||
General update |
|
||||
Improve format/structure |
|
||||
Move code |
|
||||
Refactor code |
|
||||
DRY up code |
|
||||
Removing code/files |
|
||||
Continuous Integration |
|
||||
Security |
|
||||
Upgrading dependencies |
|
||||
Downgrading dependencies |
|
||||
Lint |
|
||||
Translation |
|
||||
Text |
|
||||
Critical hotfix |
|
||||
Deploying stuff |
|
||||
Fixing on MacOS |
|
||||
Fixing on Linux |
|
||||
Fixing on Windows |
|
||||
Adding CI build system |
|
||||
Analytics or tracking code |
|
||||
Removing a dependency |
|
||||
Adding a dependency |
|
||||
Docker |
|
||||
Configuration files |
|
||||
Bundles update |
|
||||
Merging branches |
|
||||
Bad code / need improv. |
|
||||
Reverting changes |
|
||||
Breaking changes |
|
||||
Code review changes |
|
||||
Accessibility |
|
||||
Move/rename repository |
|
||||
Other | Be creative |
Rebase instead of merge¶
The only option for merging pull requests is Rebase and merge. As such, it is advisable to rebase when pulling instead of merging.
Run the tests¶
- Make sure a selenium driver is available on your
PATH
- From the root directory:
$ pytest tests --driver Chrome
Build the docs¶
$ cd docs
- Generate the autodoc rst files:
$ make rst
- Generate the static html:
$ make html
- See the output by opening
docs/_build/html/index.html