WebDriver Wrapper documentation

What is WebDriver Wrapper? Better interface of WebDriver in Python. WebDriver is great for testing whole web apps, but it’s pain using available API. This wrapper wraps it and handle following for you:

Installation

pip install webdriverwrapper

If you want also suggestions, then also install extra requirements:

pip install webdriverwrapper[seggestions]

Then you will see something like this:

driver.get_elm('qbdfq')
NoSuchElementException: Message: No element <* id=qbdfq> found at https://www.google.com, did you mean id=gbsfw?

Hello World!

driver = Chrome()
driver.get('http://www.google.com')
form_elm = driver.get_elm('gbqf')
form_elm.fill_out_and_submit({
    'q': 'Hello World!',
})
driver.wait_for_element(id_='search')
driver.quit()

Documentation

Wrapper

class webdriverwrapper.wrapper._WebdriverBaseWrapper[source]

Class wrapping both selenium.WebDriver and selenium.WebElement.

click(*args, **kwds)[source]

When you not pass any argument, it clicks on current element. If you pass some arguments, it works as following snippet. For more info what you can pass check out method get_elm().

driver.get_elm('someid').click()
contains_text(text)[source]

Does page or element contains text?

Uses method get_elms().

default_wait_timeout = 10

Default timeout in seconds for wait* methods (such as wait_for_element).

New in version 2.7.

find_element_by_text(text)[source]

Returns first element on page or in element containing text.

New in version 2.0.

Deprecated since version 2.8: Use get_elm() instead.

find_elements_by_text(text)[source]

Returns all elements on page or in element containing text.

Changed in version 2.0: Searching in all text nodes. Before it wouldn’t find string “text” in HTML like <div>some<br />text in another text node</div>.

Deprecated since version 2.8: Use get_elms() instead.

get_elm(id_=None, class_name=None, name=None, tag_name=None, text=None, xpath=None, parent_id=None, parent_class_name=None, parent_name=None, parent_tag_name=None, css_selector=None)[source]

Returns first found element. This method uses get_elms().

get_elms(id_=None, class_name=None, name=None, tag_name=None, text=None, xpath=None, parent_id=None, parent_class_name=None, parent_name=None, parent_tag_name=None, css_selector=None)[source]

Shortcut for find_element* methods. It’s shorter and you can quickly find element in element.

elm = driver.find_element_by_id('someid')
elm.find_elements_by_class_name('someclasss')

# vs.

elm = driver.get_elm(parent_id='someid', class_name='someclass')

Changed in version 2.8: Added text param. Use it instead of old find_element[s]_by_text methods. Thanks to that it can be used also in wait_for_element* methods.

wait(timeout=None)[source]

Calls following snippet so you don’t have to remember what import. See WebDriverWait for more information. Detault timeout is ~.default_wait_timeout.

selenium.webdriver.support.wait.WebDriverWait(driver, timeout)

Example:

driver.wait().until(lambda driver: len(driver.find_element_by_id('elm')) > 10)

If you need to wait for element, consider using wait_for_element() instead.

wait_for_element(timeout=None, message='', *args, **kwds)[source]

Shortcut for waiting for element. If it not ends with exception, it returns that element. Detault timeout is ~.default_wait_timeout. Same as following:

selenium.webdriver.support.wait.WebDriverWait(driver, timeout).until(lambda driver: driver.get_elm(...))

Changed in version 2.5: Waits only for visible elements.

Changed in version 2.6: Returned functionality back in favor of new method wait_for_element_show().

wait_for_element_hide(timeout=None, message='', *args, **kwds)[source]

Shortcut for waiting for hiding of element. Detault timeout is ~.default_wait_timeout. Same as following:

selenium.webdriver.support.wait.WebDriverWait(driver, timeout).until(lambda driver: not driver.get_elm(...))

New in version 2.0.

wait_for_element_show(timeout=None, message='', *args, **kwds)[source]

Shortcut for waiting for visible element. If it not ends with exception, it returns that element. Detault timeout is ~.default_wait_timeout. Same as following:

selenium.webdriver.support.wait.WebDriverWait(driver, timeout).until(lambda driver: driver.get_elm(...))

New in version 2.6.

class webdriverwrapper.wrapper._WebdriverWrapper(*args, **kwds)[source]

Class wrapping selenium.WebDriver.

break_point()[source]

Stops testing and wait for pressing enter to continue.

Useful when you need check Chrome console for some info for example.

New in version 2.1.

close_alert(ignore_exception=False)[source]

JS alerts all blocking. This method closes it. If there is no alert, method raises exception. In tests is good to call this method with ignore_exception setted to True which will ignore any exception.

close_other_windows()[source]

Closes all not current windows. Useful for tests - after each test you can automatically close all windows.

close_window(window_name=None, title=None, url=None)[source]

WebDriver implements only closing current window. If you want to close some window without having to switch to it, use this method.

download_url(url=None)[source]

With WebDriver you can’t check status code or headers. For this you have to make classic request. But web pages needs cookies and by this it gets ugly. You can easily use this method.

When you not pass url, current_url will be used.

Returns _Download instance.

fill_out(data, prefix='', turbo=False)[source]

Shortcut for filling out first <form> on page. See Form for more information.

New in version 2.0.

fill_out_and_submit(data, prefix='', turbo=False)[source]

Shortcut for filling out first <form> on page. See Form for more information.

New in version 2.0.

get_alert()[source]

Returns instance of Alert.

get_url(path=None, query=None)[source]

You have to pass absolute URL to method get(). This method help you to pass only relative path and/or query. Scheme and domains is append to URL from current_url.

query can be final string or dictionary. On dictionary it calls urllib.urlencode().

New in version 2.0.

go_to(path=None, query=None)[source]

You have to pass absolute URL to method get(). This method help you to pass only relative path and/or query. See method get_url() for more information.

Changed in version 2.0: Removed parameter domain. If you want to go to completely another web app, use absolute address.

html

Returns innerHTML of whole page. On page have to be tag body.

New in version 2.2.

make_screenshot(screenshot_name=None)[source]

Shortcut for get_screenshot_as_file but with configured path. If you are using base WebdriverTestCase. or pytest, screenshot_path is passed to driver automatically.

If screenshot_name is not passed, current timestamp is used.

New in version 2.2.

switch_to_window(window_name=None, title=None, url=None)[source]

WebDriver implements switching to other window only by it’s name. With wrapper there is also option to switch by title of window or URL. URL can be also relative path.

wait_for_alert(timeout=None)[source]

Shortcut for waiting for alert. If it not ends with exception, it returns that alert. Detault timeout is ~.default_wait_timeout.

class webdriverwrapper.wrapper._WebElementWrapper(webelement)[source]

Class wrapping selenium.WebElement.

clear()[source]

Clears the text if it’s a text entry element.

current_url

Accessing current_url also on elements.

download_file()[source]

With WebDriver you can’t check status code or headers. For this you have to make classic request. But web pages needs cookies and data from forms and by this it gets pretty ugly. You can easily use this method.

It can handle downloading of page/file by link or any type of form.

Returns _Download instance.

html

Returns innerHTML.

New in version 2.2.

Forms

class webdriverwrapper.forms.Form(webelement)[source]
fill_out(data, prefix='', skip_reset=False)[source]

Fill out data by dictionary (key is name attribute of inputs). You can pass normal Pythonic data and don’t have to care about how to use API of WebDriver.

By prefix you can specify prefix of all name attributes. For example you can have inputs called client.name and client.surname - then you will pass to prefix string "client." and in dictionary just "name".

Option skip_reset is for skipping reset, so it can go faster. For example for multiple selects it calls deselect_all first, but it need to for every option check if it is selected and it is very slow for really big multiple selects. If you know that it is not filled, you can skip it and safe in some cases up to one minute! Also same with text inputs, but first is called clear.

Example:

driver.get_elm('formid').fill_out({
    'name': 'Michael',
    'surname': 'Horejsek',
    'age': 24,
    'enabled': True,
    'multibox': ['value1', 'value2']
}, prefix='user_')

Changed in version 2.2: turbo renamed to skip_reset and used also for common elements like text inputs or textareas.

fill_out_and_submit(data, prefix='', skip_reset=False)[source]

Calls fill_out() and then submit().

reset()[source]

Try to find element with ID “[FORM_ID]_reset” and click on it.

You should use it for forms where you have cleaning/reseting of data.

submit()[source]

Try to find element with ID “[FORM_ID]_submit” and click on it. If no element doesn’t exists it will call default behaviour - submiting of form by pressing enter.

Downloading

class webdriverwrapper.download._Download[source]

Object returned by calling download_url() or download_file().

data

RAW data of response.

encoding

Encoding of reponse.

headers

Headers of response.

See requests.Response.headers for more information.

method

Used method of request. GET or POST.

status_code

Status code of response.

Testing

Supported are both UnitTest and PyTest tests. Each of them have own section bellow, but first you have to know something about “expecting decorators”.

After each test is called method check_expected_errors and check_expected_infos which will raise exception if there is some unexpected error. By default you doesn’t have to check everytime presence of some error - TestCase or PyTest fixtures does that for you automatically. But sometimes you want to test that something fail - that something ends with some error message or info message. For that there are several decorators.

# Following test go to relative page "settings" and fill out and submit form.
# Test have to ends on page where is info message to user with key sucessfuly_saved.
@expected_info_message('sucesfully_saved')
def test_save_data(driver):
    driver.go_to('settings')
    driver.fill_out_and_submit({
        'name': 'Michael',
    })

# Test have to ends on page indicating that user doesn't have permission.
@expected_error_page('403')
def test_access_admin_page(driver):
    driver.go_to('admin')

When you need some changes in method get_error_page, get_error_traceback, get_error_messages or get_info_messages, feel free to change it like that:

from webdriverwrapper import Chrome

driver = Chrome()

# Better to set it on instance, so you can change browser without changing this code.
dirver.__class__.get_error_page = your_method
dirver.__class__.get_error_traceback = your_method
dirver.__class__.get_error_messages = your_method
dirver.__class__.get_info_messages = your_method

Decorators

webdriverwrapper.decorators.expected_error_page(error_page)[source]

Decorator expecting defined error page at the end of test method. As param use what get_error_page() returns.

New in version 2.0: Before this decorator was called ShouldBeErrorPage.

webdriverwrapper.decorators.allowed_error_pages(*error_pages)[source]

Decorator ignoring defined error pages at the end of test method. As param use what get_error_page() returns.

New in version 2.0.

webdriverwrapper.decorators.expected_error_messages(*error_messages)[source]

Decorator expecting defined error messages at the end of test method. As param use what get_error_messages() returns.

New in version 2.0: Before this decorator was called ShouldBeError.

webdriverwrapper.decorators.allowed_error_messages(*error_messages)[source]

Decorator ignoring defined error messages at the end of test method. As param use what get_error_messages() returns.

New in version 2.0: Before this decorator was called CanBeError.

webdriverwrapper.decorators.allowed_any_error_message(func)[source]

Decorator ignoring any error messages at the end of test method. If you want allow only specific error message, use allowed_error_messages() instead.

New in version 2.0.

webdriverwrapper.decorators.expected_info_messages(*info_messages)[source]

Decorator expecting defined info messages at the end of test method. As param use what get_info_messages() returns.

New in version 2.0: Before this decorator was called ShouldBeInfo.

webdriverwrapper.decorators.allowed_info_messages(*info_messages)[source]

Decorator ignoring defined info messages at the end of test method. As param use what get_info_messages() returns.

New in version 2.0.

Example
@expected_info_messages('Your information was updated.')
def test_save(driver):
    driver.fill_out_and_submit({
        'name': 'Michael',
    })

Error and info messages

class webdriverwrapper.errors.WebdriverWrapperErrorMixin[source]

Mixin used in _WebdriverWrapper.

New in version 2.0: Before you had to change decorators ShouldByError, CanBeError and ShouldBeErrorPage which are gone. Now you can use original decorators and just change one of these methods. For more information check out section testing.

check_errors(expected_error_page=None, allowed_error_pages=[], expected_error_messages=[], allowed_error_messages=[])[source]

This method should be called whenever you need to check if there is some error. Normally you need only check_expected_errors called after each test (which you specify only once), but it will check errors only at the end of test. When you have big use case and you need to be sure that on every step is not any error, use this.

To parameters you should pass same values like to decorators expected_error_page(), allowed_error_pages(), expected_error_messages() and allowed_error_messages().

check_expected_errors(test_method)[source]

This method is called after each test. It will read decorated informations and check if there are expected errors.

You can set expected errors by decorators expected_error_page(), allowed_error_pages(), expected_error_messages(), allowed_error_messages() and allowed_any_error_message().

get_error_messages()[source]

Method returning error messages. Should return list of messages.

By default it find element with class error and theirs value in attribute error or text if that attribute is missing. You can change this method accordingly to your app.

Error messages returned from this method are used in decorators expected_error_messages() and allowed_error_messages().

get_error_page()[source]

Method returning error page. Should return string.

By default it find element with class error-page and returns text of h1 header. You can change this method accordingly to your app.

Error page returned from this method is used in decorators expected_error_page() and allowed_error_pages().

get_error_traceback()[source]

Method returning traceback of error page.

By default it find element with class error-page and returns text of element with class traceback. You can change this method accordingly to your app.

get_js_errors()[source]

Method returning JS errors. Should return list of errors.

You have to include following JS snippet to your web app which will record all JS errors and this method will automatically read them.

<script type="text/javascript">
    window.jsErrors = [];
    window.onerror = function(errorMessage) {
        window.jsErrors[window.jsErrors.length] = errorMessage;
    }
</script>
class webdriverwrapper.info.WebdriverWrapperInfoMixin[source]

Mixin used in _WebdriverWrapper.

New in version 2.0: Before you had to change decorator ShouldBeInfo which is gone. Now you can use original decorators and just change one of these methods. For more information check out section testing.

check_expected_infos(test_method)[source]

This method is called after each test. It will read decorated informations and check if there are expected infos.

You can set expected infos by decorators expected_info_messages() and allowed_info_messages().

check_infos(expected_info_messages=[], allowed_info_messages=[])[source]

This method should be called whenever you need to check if there is some info. Normally you need only check_expected_infos called after each test (which you specify only once), but it will check infos only at the end of test. When you have big use case and you need to check messages on every step, use this.

To parameters you should pass same values like to decorators expected_info_messages() and allowed_info_messages().

get_info_messages()[source]

Method returning info messages. Should return list of messages.

By default it find element with class info and theirs value in attribute info or text if that attribute is missing. You can change this method accordingly to your app.

Info messages returned from this method are used in decorators expected_info_messages() and allowed_info_messages().

PyTest

Import whole module in your main conftest.py and define fixture _driver:

import pytest
from webdriverwrapper import Chrome
from webdriverwrapper.pytest import *


# Create browser once for all tests.
@pytest.yield_fixture(scope='session')
def session_driver():
    driver = Chrome()
    yield driver
    driver.quit()


# Before every test go to homepage.
@pytest.fixture(scope='function')
def _driver(session_driver):
    session_driver.get('http://www.google.com')
    return session_driver

Then you can write tests really simply:

def test_doodle(driver):
    driver.click('gbqfsb')
    assert driver.contains_text('Doodles')


def test_search(driver):
    driver.get_elm('gbqf').fill_out_and_submit({
        'q': 'hello',
    })
    driver.wait_for_element(id_='resultStats')
webdriverwrapper.pytest.conftest.pytest_report_header(config)[source]

Pytest hook, see _pytest.hookspec.pytest_report_header() (Writing plugins).

It’s important to see which URL is testing with which user and where are stored screenshots. It will be displayed before run of tests if you set some config values like that:

def pytest_configure(config):
    config.webdriverwrapper_screenshot_path = os.path.join('/', 'tmp', 'testresults')
    config.webdriverwrapper_testing_url = 'http://example.com'
    config.webdriverwrapper_testing_username = 'testing_username'

If your web app does not need any user, just don’t set it.

webdriverwrapper.pytest.conftest.pytest_runtest_makereport(item, call, __multicall__)[source]

Pytest hook, see _pytest.hookspec.pytest_runtest_makereport().

After each failed test will be generated screenshot if you specify where to save these screenshots.

def pytest_configure(config):
    config.webdriverwrapper_screenshot_path = os.path.join('/', 'tmp', 'testresults')
webdriverwrapper.pytest.conftest.driver(request, _driver)[source]

Fixture for testing. This fixture just take your driver by fixture called _driver and after each test call check_expected_errors() and check_expected_infos(). You have to just implement creating of your browser.

@pytest.yield_fixture(scope='session')
def _driver():
    driver = Chrome()
    yield driver
    driver.quit()

UnitTest

unittest.ONE_INSTANCE_FOR_ALL_TESTS = 0
unittest.ONE_INSTANCE_PER_TESTCASE = 1
unittest.ONE_INSTANCE_PER_TEST = 2
class webdriverwrapper.unittest.WebdriverTestCase(*args, **kwds)[source]

Base TestCase used for testing with unittest.

Example:

class TestCase(webdriverwrapper.unittest.WebdriverTestCase):
    domain = 'www.google.com'
    instances_of_driver = webdriverwrapper.unittest.ONE_INSTANCE_PER_TESTCASE
    screenshot_path = os.path.join('/', 'tmp', 'testreport')

    def _get_driver(self):
        return Chrome()

    def test_doodle(self):
        self.click('gbqfsb')
        self.assertTrue(self.contains_text('Doodles'))

    def test_search(self):
        self.get_elm('gbqf').fill_out_and_submit({
            'q': 'hello',
        })
        self.wait_for_element(id_='resultStats')
_get_driver()[source]

Create driver. By default it creates Firefox. Change it to your needs.

break_point()[source]

Alias for break_point().

check_errors(expected_error_page=None, allowed_error_pages=[], expected_error_messages=[], allowed_error_messages=[])[source]

Alias for check_errors().

Changed in version 2.0: Only alias. Code moved to wrapper so it could be used also by pytest.

click(*args, **kwds)[source]

Alias for click().

close_other_windows()[source]

Alias for close_other_windows().

close_window(window_name=None, title=None, url=None)[source]

Alias for close_window().

contains_text(text)[source]

Alias for contains_text().

debug(msg)[source]

Run the test without collecting errors in a TestResult

domain = None

If you want working relative go_to without having to call for first time get (because before that you can’t use relative path), set this attribute.

find_element_by_text(text)[source]

Alias for find_element_by_text().

New in version 2.0.

find_elements_by_text(text)[source]

Alias for find_elements_by_text().

get_elm(*args, **kwds)[source]

Alias for get_elm().

get_elms(*args, **kwds)[source]

Alias for get_elms().

go_to(*args, **kwds)[source]

Alias for go_to().

instances_of_driver = 0

Specify when you want to create fresh driver. By default there is one driver for all tests (ONE_INSTANCE_FOR_ALL_TESTS) and you have to close it by yourself by calling quit_driver().

If you need clear cookies, local storage and everything, then consider to use new driver for every TestCase or even every test method.

make_screenshot(screenshot_name=None)[source]

Save screenshot to screenshot_path with given name screenshot_name. If name is not given, then the name is name of current test (self.id()).

Changed in version 2.2: Use make_screenshot directly on driver instead. This method is used for making screenshot of failed tests and therefor does nothing if screenshot_path is not configured. It stays there only for compatibility.

static quit_driver()[source]

When you set instances_of_driver to ONE_INSTANCE_FOR_ALL_TESTS (which is default), then you have to quit driver by yourself by this method.

screenshot_path = ''

When you set this path, it will make automatically screenshots of failed tests and saved them to this path.

switch_to_window(window_name=None, title=None, url=None)[source]

Alias for switch_to_window().

wait(timeout=10)[source]

Alias for wait().

wait_after_test = False

For debug only. When you set to True, it will wait for pressing enter after each test before moving to next test. Ideal when you need to check out for example Chrome console.

But maybe better debuging is with break_point().

wait_for_element(*args, **kwds)[source]

Alias for wait_for_element().

Exceptions

You doesn’t have to care about some exception. In test result you will get some exception with clear message. But if you need something special or is there some confusion, these are all exceptions defined by this wrapper.

exception webdriverwrapper.exceptions.ErrorMessagesException(url, error_messages, expected_error_messages, allowed_error_messages)[source]

Exception raised when there is some unexpected error message. Like “some field is mandatory”, “wrong e-mail” and so on.

exception webdriverwrapper.exceptions.ErrorPageException(url, error_page, expected_error_page, allowed_error_pages, traceback=None)[source]

Exception raised when there is some unexpected error page. Like page 404, 500 and so on.

exception webdriverwrapper.exceptions.InfoMessagesException(url, info_messages, expected_info_messages, allowed_info_messages)[source]

Exception raised when there is missing some expected info message. Like “sucessfully saved” and so on.

exception webdriverwrapper.exceptions.JSErrorsException(url, js_errors)[source]

Exception raised when there is some JS error.

See get_js_errors for more information.

exception webdriverwrapper.exceptions.WebdriverWrapperException(url, msg)[source]

Base exception of WebDriver Wrapper.