API Reference#

browser#

Use environment variables to configure Selenium remote WebDriver. For use with SauceLabs (via SauceConnect) or local browsers.

exception bok_choy.browser.BrowserConfigError[source]#

Misconfiguration error in the environment variables.

bok_choy.browser.add_profile_customizer(func)[source]#

Add a new function that modifies the preferences of the firefox profile object it receives as an argument

bok_choy.browser.browser(tags=None, proxy=None, other_caps=None)[source]#

Interpret environment variables to configure Selenium. Performs validation, logging, and sensible defaults.

There are three cases:

  1. Local browsers: If the proper environment variables are not all set for the second case,

    then we use a local browser.

    • The environment variable SELENIUM_BROWSER can be set to specify which local browser to use. The default is Firefox.

    • Additionally, if a proxy instance is passed and the browser choice is either Chrome or Firefox, then the browser will be initialized with the proxy server set.

    • The environment variable SELENIUM_FIREFOX_PATH can be used for specifying a path to the Firefox binary. Default behavior is to use the system location.

    • The environment variable FIREFOX_PROFILE_PATH can be used for specifying a path to the Firefox profile. Default behavior is to use a barebones default profile with a few useful preferences set.

  2. Remote browser (not SauceLabs): Set all of the following environment variables, but not all of

    the ones needed for SauceLabs:

    • SELENIUM_BROWSER

    • SELENIUM_HOST

    • SELENIUM_PORT

  3. SauceLabs: Set all of the following environment variables:

    • SELENIUM_BROWSER

    • SELENIUM_VERSION

    • SELENIUM_PLATFORM

    • SELENIUM_HOST

    • SELENIUM_PORT

    • SAUCE_USER_NAME

    • SAUCE_API_KEY

NOTE: these are the environment variables set by the SauceLabs Jenkins plugin.

Optionally provide Jenkins info, used to identify jobs to Sauce:

  • JOB_NAME

  • BUILD_NUMBER

tags is a list of string tags to apply to the SauceLabs job. If not using SauceLabs, these will be ignored.

Keyword Arguments:
  • tags (list of str) – Tags to apply to the SauceLabs job. If not using SauceLabs, these will be ignored.

  • proxy – A proxy instance.

  • other_caps (dict of str) – Additional desired capabilities to provide to remote WebDriver instances. Note

  • for (that these values will be overwritten by environment variables described above. This is only used) –

  • and (remote driver instances, where such info is usually used by services for additional configuration) –

  • metadata.

Returns:

The configured browser object used to drive tests

Return type:

selenium.webdriver

Raises:

BrowserConfigError – The environment variables are not correctly specified.

bok_choy.browser.clear_profile_customizers()[source]#

Remove any previously-configured functions for customizing the firefox profile

bok_choy.browser.save_driver_logs(driver, prefix)[source]#

Save the selenium driver logs.

The location of the driver log files can be configured by the environment variable SELENIUM_DRIVER_LOG_DIR. If not set, this defaults to the current working directory.

Parameters:
  • driver (selenium.webdriver) – The Selenium-controlled browser.

  • prefix (str) – A prefix which will be used in the output file names for the logs.

Returns:

None

bok_choy.browser.save_screenshot(driver, name)[source]#

Save a screenshot of the browser.

The location of the screenshot can be configured by the environment variable SCREENSHOT_DIR. If not set, this defaults to the current working directory.

Parameters:
  • driver (selenium.webdriver) – The Selenium-controlled browser.

  • name (str) – A name for the screenshot, which will be used in the output file name.

Returns:

None

bok_choy.browser.save_source(driver, name)[source]#

Save the rendered HTML of the browser.

The location of the source can be configured by the environment variable SAVED_SOURCE_DIR. If not set, this defaults to the current working directory.

Parameters:
  • driver (selenium.webdriver) – The Selenium-controlled browser.

  • name (str) – A name to use in the output file name. Note that “.html” is appended automatically

Returns:

None

javascript#

Helpers for dealing with JavaScript synchronization issues.

bok_choy.javascript.js_defined(*js_vars)[source]#

Class decorator that ensures JavaScript variables are defined in the browser.

This adds a wait_for_js method to the class, which will block until all the expected JavaScript variables are defined.

Parameters:

js_vars (list of str) – List of JavaScript variable names to wait for.

Returns:

Decorated class

bok_choy.javascript.requirejs(*modules)[source]#

Class decorator that ensures RequireJS modules are loaded in the browser.

This adds a wait_for_js method to the class, which will block until all the expected RequireJS modules are loaded.

Parameters:

modules (list of str) –

Returns:

Decorated class

bok_choy.javascript.wait_for_js(function)[source]#

Method decorator that waits for JavaScript dependencies before executing function. If the function is not a method, the decorator has no effect.

Parameters:

function (callable) – Method to decorate.

Returns:

Decorated method

page_object#

Base implementation of the Page Object pattern. See SeleniumHQ/selenium and http://www.seleniumhq.org/docs/06_test_design_considerations.jsp#page-object-design-pattern

exception bok_choy.page_object.PageLoadError(msg=None, screen=None, stacktrace=None)[source]#

An error occurred while loading the page.

class bok_choy.page_object.PageObject(browser, *args, **kwargs)[source]#

Encapsulates user interactions with a specific part of a web application.

The most important thing is this: Page objects encapsulate Selenium.

If you find yourself writing CSS selectors in tests, manipulating forms, or otherwise interacting directly with the web UI, stop!

Instead, put these in a PageObject subclass :)

PageObjects do their best to verify that they are only used when the browser is on a page containing the object. To do this, they will call is_browser_on_page() before executing any of their methods, and raise a WrongPageError if the browser isn’t on the correct page.

Generally, this is the right behavior. However, at times it will be useful to not verify the page before executing a method. In those cases, the method can be marked with the unguarded() decorator. Additionally, private methods (those beginning with _) are always unguarded.

Class or instance properties are never guarded. However, methods marked with the property() are candidates for being guarded. To make them unguarded, you must mark the getter, setter, and deleter as unguarded() separately, and those decorators must be applied before the property() decorator.

Correct:

@property
@unguarded
def foo(self):
    return self._foo

Incorrect:

@unguarded
@property
def foo(self):
    return self._foo

Initialize the page object to use the specified browser instance.

Parameters:

browser (selenium.webdriver) – The Selenium-controlled browser.

Returns:

PageObject

a11y_audit()[source]#

Initializes the a11y_audit attribute.

handle_alert(confirm=True)[source]#

Context manager that ensures alerts are dismissed.

Example usage:

with self.handle_alert():
    self.q(css='input.submit-button').first.click()
Keyword Arguments:

confirm (bool) – Whether to confirm or cancel the alert.

Returns:

None

abstract is_browser_on_page()[source]#

Check that we are on the right page in the browser. The specific check will vary from page to page, but usually this amounts to checking the:

  1. browser URL

  2. page title

  3. page headings

Returns:

A bool indicating whether the browser is on the correct page.

q(**kwargs)[source]#

Construct a query on the browser.

Example usages:

self.q(css="div.foo").first.click()
self.q(xpath="/foo/bar").text
Keyword Arguments:
  • css – A CSS selector.

  • xpath – An XPath selector.

Returns:

BrowserQuery

scroll_to_element(element_selector, timeout=60)[source]#

Scrolls the browser such that the element specified appears at the top. Before scrolling, waits for the element to be present.

Example usage:

self.scroll_to_element('.far-down', 'Scroll to far-down')
Parameters:
  • element_selector (str) – css selector of the element.

  • timeout (float) – Maximum number of seconds to wait for the element to be present on the page before timing out.

Raises: BrokenPromise if the element does not exist (and therefore scrolling to it is not possible)

abstract property url#

Return the URL of the page. This may be dynamic, determined by configuration options passed to the page object’s constructor.

Some pages may not be directly accessible: perhaps the page object represents a “navigation” component that occurs on multiple pages. If this is the case, subclasses can return None to indicate that you can’t directly visit the page object.

classmethod validate_url(url)[source]#

Return a boolean indicating whether the URL has a protocol and hostname. If a port is specified, ensure it is an integer.

Parameters:

url (str) – The URL to check.

Returns:

Boolean indicating whether the URL has a protocol and hostname.

visit()[source]#

Open the page containing this page object in the browser.

Some page objects may not provide a URL, in which case a NotImplementedError will be raised.

Raises:
  • PageLoadError – The page did not load successfully.

  • NotImplementedError – The page object does not provide a URL to visit.

Returns:

PageObject

wait_for(promise_check_func, description, result=False, timeout=60)[source]#

Calls the method provided as an argument until the Promise satisfied or BrokenPromise. Retries if a WebDriverException is encountered (until the timeout is reached).

Parameters:
  • promise_check_func (callable) –

    • If result is False Then

      Function that accepts no arguments and returns a boolean indicating whether the promise is fulfilled

    • If result is True Then

      Function that accepts no arguments and returns a (is_satisfied, result) tuple, where is_satisfied is a boolean indicating whether the promise was satisfied, and result is a value to return from the fulfilled Promise

  • description (str) – Description of the Promise, used in log messages

  • result (bool) – Indicates whether we need result

  • timeout (float) – Maximum number of seconds to wait for the Promise to be satisfied before timing out

Raises:

BrokenPromise – the Promise was not satisfied

wait_for_ajax(timeout=30)[source]#

Wait for jQuery to be loaded and for all ajax requests to finish. Note that we have to wait for jQuery to load first because it is used to check that ajax requests are complete.

Important: If you have an ajax requests that results in a page reload, you will need to use wait_for_page or some other method to confirm that the page has finished reloading after wait_for_ajax has returned.

Example usage:

self.q(css='input#email').fill("foo")
self.wait_for_ajax()
Keyword Arguments:
  • timeout (int) – The number of seconds to wait before timing out with

  • exception. (a BrokenPromise) –

Returns:

None

Raises:
  • BrokenPromise – The timeout is exceeded before (1) jQuery is defined

  • and (2) all ajax requests are completed.

wait_for_element_absence(element_selector, description, timeout=60)[source]#

Waits for element specified by element_selector until it disappears from DOM.

Example usage:

self.wait_for_element_absence('.submit', 'Submit Button is not Present')
Parameters:
  • element_selector (str) – css selector of the element.

  • description (str) – Description of the Promise, used in log messages.

  • timeout (float) – Maximum number of seconds to wait for the Promise to be satisfied before timing out

wait_for_element_invisibility(element_selector, description, timeout=60)[source]#

Waits for element specified by element_selector until it disappears from the web page.

Example usage:

self.wait_for_element_invisibility('.submit', 'Submit Button Disappeared')
Parameters:
  • element_selector (str) – css selector of the element.

  • description (str) – Description of the Promise, used in log messages.

  • timeout (float) – Maximum number of seconds to wait for the Promise to be satisfied before timing out

wait_for_element_presence(element_selector, description, timeout=60)[source]#

Waits for element specified by element_selector to be present in DOM.

Example usage:

self.wait_for_element_presence('.submit', 'Submit Button is Present')
Parameters:
  • element_selector (str) – css selector of the element.

  • description (str) – Description of the Promise, used in log messages.

  • timeout (float) – Maximum number of seconds to wait for the Promise to be satisfied before timing out

wait_for_element_visibility(element_selector, description, timeout=60)[source]#

Waits for element specified by element_selector until it is displayed on web page.

Example usage:

self.wait_for_element_visibility('.submit', 'Submit Button is Visible')
Parameters:
  • element_selector (str) – css selector of the element.

  • description (str) – Description of the Promise, used in log messages.

  • timeout (float) – Maximum number of seconds to wait for the Promise to be satisfied before timing out

wait_for_page(timeout=30)[source]#

Block until the page loads, then returns the page. Useful for ensuring that we navigate successfully to a particular page.

Keyword Arguments:

timeout (int) – The number of seconds to wait for the page before timing out with an exception.

Raises:

BrokenPromise – The timeout is exceeded without the page loading successfully.

warning(msg)[source]#

Subclasses call this to indicate that something unexpected occurred while interacting with the page.

Page objects themselves should never make assertions or raise exceptions, but they can issue warnings to make tests easier to debug.

Parameters:

msg (str) – The message to log as a warning.

Returns:

None

exception bok_choy.page_object.WrongPageError(msg=None, screen=None, stacktrace=None)[source]#

The page object reports that we’re on the wrong page!

exception bok_choy.page_object.XSSExposureError[source]#

An XSS issue has been found on the current page.

bok_choy.page_object.no_selenium_errors(func)[source]#

Decorator to create an EmptyPromise check function that is satisfied only when func executes without a Selenium error.

This protects against many common test failures due to timing issues. For example, accessing an element after it has been modified by JavaScript ordinarily results in a StaleElementException. Methods decorated with no_selenium_errors will simply retry if that happens, which makes tests more robust.

Parameters:

func (callable) – The function to execute, with retries if an error occurs.

Returns:

Decorated function

bok_choy.page_object.pre_verify(method)[source]#

Decorator that calls self._verify_page() before executing the decorated method

Parameters:

method (callable) – The method to decorate.

Returns:

Decorated method

bok_choy.page_object.unguarded(method)[source]#

Mark a PageObject method as unguarded.

Unguarded methods don’t verify that the PageObject is on the current browser page before they execute

Parameters:

method (callable) – The method to decorate.

Returns:

Decorated method

accessibility#

A11yAudit and A11yAuditConfig (Abstract Classes)#

Interface for running accessibility audits on a PageObject.

class bok_choy.a11y.a11y_audit.A11yAudit(browser, url, config=None, *args, **kwargs)[source]#

Allows auditing of a page for accessibility issues.

The ruleset to use can be specified by the environment variable BOKCHOY_A11Y_RULESET. Currently, there are two ruleset implemented:

axe_core:

  • Ruleset class: AxeCoreAudit

  • Ruleset config: AxeCoreAuditConfig

  • This is default ruleset.

google_axs:

  • Ruleset class: AxsAudit

  • Ruleset config: AxsAuditConfig

Sets ruleset to be used.

Parameters:
  • browser – A browser instance

  • url – URL of the page to test

  • config – (optional) A11yAuditConfig or subclass of A11yAuditConfig

check_for_accessibility_errors()[source]#

Run an accessibility audit, parse the results, and raise a single exception if there are violations.

Note that an exception is only raised on errors, not on warnings.

Returns:

None

Raises:

AccessibilityError

abstract property default_config#

Return an instance of a subclass of A11yAuditConfig.

do_audit()[source]#

Audit the page for accessibility problems using the enabled ruleset.

Returns:

A list (one for each browser session) of results returned from the audit. See documentation of _check_rules in the enabled ruleset for the format of each result.

abstract static report_errors(audit, url)[source]#
Parameters:
  • audit – results of an accessibility audit.

  • url – the url of the page being audited.

Raises:
class bok_choy.a11y.a11y_audit.A11yAuditConfig(*args, **kwargs)[source]#

The A11yAuditConfig object defines the options available in an accessibility ruleset.

abstract customize_ruleset(custom_ruleset_file=None)[source]#

Allows customization of the ruleset. (e.g. adding custom rules, extending the implementation of an existing rule.)

Raises:

NotImplementedError – specific implementation.

abstract set_rules(rules)[source]#

Overrides the default rules to be run.

Raises:

NotImplementedError – specific implementation.

set_rules_file(path=None)[source]#

Sets self.rules_file to the passed file.

Parameters:

found. (A filepath where the JavaScript for the ruleset can be) –

This is intended to be used in the case of using an extended or modified version of the ruleset. The interface and response format are expected to be unmodified.

abstract set_scope(include=None, exclude=None)[source]#

Overrides the default scope (part of the DOM) to inspect.

Raises:

NotImplementedError – specific implementation.

exception bok_choy.a11y.a11y_audit.A11yAuditConfigError[source]#

An error in A11yAuditConfig.

exception bok_choy.a11y.a11y_audit.AccessibilityError[source]#

The page violates one or more accessibility rules.

AxsAudit and AxsAuditConfig#

Interface for using the google accessibility ruleset. See: GoogleChrome/accessibility-developer-tools

class bok_choy.a11y.axs_ruleset.AuditResults(errors, warnings)#

Create new instance of AuditResults(errors, warnings)

errors#

Alias for field number 0

warnings#

Alias for field number 1

class bok_choy.a11y.axs_ruleset.AxsAudit(browser, url, config=None, *args, **kwargs)[source]#

Use Google’s Accessibility Developer Tools to audit a page for accessibility problems.

See GoogleChrome/accessibility-developer-tools

Sets ruleset to be used.

Parameters:
  • browser – A browser instance

  • url – URL of the page to test

  • config – (optional) A11yAuditConfig or subclass of A11yAuditConfig

property default_config#

Returns an instance of AxsAuditConfig.

static get_errors(audit_results)[source]#
Parameters:

audit_results – results of AxsAudit.do_audit().

Returns: a list of errors.

static report_errors(audit, url)[source]#
Parameters:
  • audit – results of AxsAudit.do_audit().

  • url – the url of the page being audited.

Raises: AccessibilityError

class bok_choy.a11y.axs_ruleset.AxsAuditConfig(*args, **kwargs)[source]#

The AxsAuditConfig object defines the options available when running an AxsAudit.

customize_ruleset(custom_ruleset_file=None)[source]#

This has not been implemented for the google_axs ruleset.

Raises:

NotImplementedError

set_rules(rules)[source]#

Sets the rules to be run or ignored for the audit.

Parameters:

rules – a dictionary of the format {“ignore”: [], “apply”: []}.

See GoogleChrome/accessibility-developer-tools

Passing {“apply”: []} or {} means to check for all available rules.

Passing {“apply”: None} means that no audit should be done for this page.

Passing {“ignore”: []} means to run all otherwise enabled rules. Any rules in the “ignore” list will be ignored even if they were also specified in the “apply”.

Examples

To check only badAriaAttributeValue:

page.a11y_audit.config.set_rules({
    "apply": ['badAriaAttributeValue']
})

To check all rules except badAriaAttributeValue:

page.a11y_audit.config.set_rules({
    "ignore": ['badAriaAttributeValue'],
})
set_scope(include=None, exclude=None)[source]#

Sets scope, the “start point” for the audit.

Parameters:
  • include – A list of css selectors specifying the elements that contain the portion of the page that should be audited. Defaults to auditing the entire document.

  • exclude – This arg is not implemented in this ruleset.

Examples

To check only the div with id foo:

page.a11y_audit.config.set_scope(["div#foo"])

To reset the scope to check the whole document:

page.a11y_audit.config.set_scope()

AxeCoreAudit and AxeCoreAuditConfig#

Interface for using the axe-core ruleset. See: dequelabs/axe-core

class bok_choy.a11y.axe_core_ruleset.AxeCoreAudit(browser, url, config=None, *args, **kwargs)[source]#

Use Deque Labs’ axe-core engine to audit a page for accessibility issues.

Related documentation:

Sets ruleset to be used.

Parameters:
  • browser – A browser instance

  • url – URL of the page to test

  • config – (optional) A11yAuditConfig or subclass of A11yAuditConfig

property default_config#

Returns an instance of AxeCoreAuditConfig.

static format_errors(errors)[source]#
Parameters:

errors – results of AxeCoreAudit.get_errors().

Returns: The errors as a formatted string.

static get_errors(audit_results)[source]#
Parameters:

audit_results – results of AxeCoreAudit.do_audit().

Returns:

A dictionary with keys “errors” and “total”.

static report_errors(audit, url)[source]#
Parameters:
  • audit – results of AxeCoreAudit.do_audit().

  • url – the url of the page being audited.

Raises: AccessibilityError

class bok_choy.a11y.axe_core_ruleset.AxeCoreAuditConfig(*args, **kwargs)[source]#

The AxeCoreAuditConfig object defines the options available when running an AxeCoreAudit.

customize_ruleset(custom_ruleset_file=None)[source]#

Updates the ruleset to include a set of custom rules. These rules will be _added_ to the existing ruleset or replace the existing rule with the same ID.

Parameters:

custom_ruleset_file (optional) – The filepath to the custom rules. Defaults to None. If custom_ruleset_file isn’t passed, the environment variable BOKCHOY_A11Y_CUSTOM_RULES_FILE will be checked. If a filepath isn’t specified by either of these methods, the ruleset will not be updated.

Raises:

IOError

Examples

To include the rules defined in axe-core-custom-rules.js:

page.a11y_audit.config.customize_ruleset(
    "axe-core-custom-rules.js"
)

Alternatively, use the environment variable BOKCHOY_A11Y_CUSTOM_RULES_FILE to specify the path to the file containing the custom rules.

Documentation for how to write rules:

An example of a custom rules file can be found at openedx/bok-choy

set_rules(rules)[source]#

Set rules to ignore XOR limit to when checking for accessibility errors on the page.

Parameters:

rules

a dictionary one of the following formats. If you want to run all of the rules except for some:

{"ignore": []}

If you want to run only a specific set of rules:

{"apply": []}

If you want to run only rules of a specific standard:

{"tags": []}

Examples

To run only “bad-link” and “color-contrast” rules:

page.a11y_audit.config.set_rules({
    "apply": ["bad-link", "color-contrast"],
})

To run all rules except for “bad-link” and “color-contrast”:

page.a11y_audit.config.set_rules({
    "ignore": ["bad-link", "color-contrast"],
})

To run only WCAG 2.0 Level A rules:

page.a11y_audit.config.set_rules({
    "tags": ["wcag2a"],
})
To run all rules:

page.a11y_audit.config.set_rules({})

Related documentation:

set_scope(include=None, exclude=None)[source]#

Sets scope (refered to as context in ruleset documentation), which defines the elements on a page to include or exclude in the audit. If neither include nor exclude are passed, the entire document will be included.

Parameters:
  • include (optional) – a list of css selectors for elements that

  • By (should be included in the audit.) –

  • default

  • document (the entire) –

  • included. (is) –

  • exclude (optional) – a list of css selectors for elements that should not

  • audit. (be included in the) –

Examples

To include all items in #main-content except #some-special-elm:

page.a11y_audit.config.set_scope(
    exclude=["#some-special-elm"],
    include=["#main-content"]
)

To include all items in the document except #some-special-elm:

page.a11y_audit.config.set_scope(
    exclude=["#some-special-elm"],
)

To include only children of #some-special-elm:

page.a11y_audit.config.set_scope(
    include=["#some-special-elm"],
)

Context documentation:

dequelabs/axe-core

Note that this implementation only supports css selectors. It does not accept nodes as described in the above documentation resource.

promise#

Variation on the “promise” design pattern. Promises make it easier to handle asynchronous operations correctly.

exception bok_choy.promise.BrokenPromise(promise)[source]#

The promise was not satisfied within the time constraints.

Configure the broken promise error.

Parameters:

promise (Promise) – The promise that was not satisfied.

class bok_choy.promise.EmptyPromise(check_func, description, **kwargs)[source]#

A promise that has no result value.

Configure the promise.

Unlike a regular Promise, the check_func() does NOT return a tuple with a result value. That’s why the promise is “empty” – you don’t get anything back.

Example usage:

# This will block until `is_done` returns `True` or we reach the timeout limit.
EmptyPromise(lambda: is_done('test'), "Test operation is done").fulfill()
Parameters:
  • check_func (callable) – Function that accepts no arguments and returns a boolean indicating whether the promise is fulfilled.

  • description (str) – Description of the Promise, used in log messages.

Returns:

EmptyPromise

class bok_choy.promise.Promise(check_func, description, try_limit=None, try_interval=0.5, timeout=30)[source]#

Check that an asynchronous action completed, blocking until it does or timeout / try limits are reached.

Configure the Promise.

The Promise will poll check_func() until either:
  • The promise is satisfied

  • The promise runs out of tries (checks more than try_limit times)

  • The promise runs out of time (takes longer than timeout seconds)

If the try_limit or timeout is reached without success, then the promise is “broken” and an exception will be raised.

Note that if you specify a try_limit but not a timeout, the default timeout is still used. This is to prevent an inadvertent infinite loop. If you want to make sure that the try_limit expires first (and thus that many attempts will be made), then you should also pass in a larger value for timeout.

description is a string that will be included in the exception to make debugging easier.

Example:

# Dummy check function that indicates the promise is always satisfied
check_func = lambda: (True, "Hello world!")

# Check up to 5 times if the operation has completed
result = Promise(check_func, "Operation has completed", try_limit=5).fulfill()
Parameters:
  • check_func (callable) – A function that accepts no arguments and returns a (is_satisfied, result) tuple, where is_satisfied is a boolean indiating whether the promise was satisfied, and result is a value to return from the fulfilled Promise.

  • description (str) – Description of the Promise, used in log messages.

Keyword Arguments:
  • try_limit (int or None) – Number of attempts to make to satisfy the Promise. Can be None to disable the limit.

  • try_interval (float) – Number of seconds to wait between attempts.

  • timeout (float) – Maximum number of seconds to wait for the Promise to be satisfied before timing out.

Returns:

Promise

fulfill()[source]#

Evaluate the promise and return the result.

Returns:

The result of the Promise (second return value from the check_func)

Raises:

BrokenPromise – the Promise was not satisfied within the time or attempt limits.

query#

Tools for interacting with the DOM inside a browser.

class bok_choy.query.BrowserQuery(browser, **kwargs)[source]#

A Query that operates on a browser.

Generate a query over a browser.

Parameters:

browser (selenium.webdriver) – A Selenium-controlled browser.

Keyword Arguments:
  • css (str) – A CSS selector.

  • xpath (str) – An XPath selector.

Returns:

BrowserQuery

Raises:

TypeError – The query must be passed either a CSS or XPath selector, but not both.

attrs(attribute_name)[source]#

Retrieve HTML attribute values from the elements matched by the query.

Example usage:

# Assume that the query matches html elements:
# <div class="foo"> and <div class="bar">
>> q.attrs('class')
['foo', 'bar']
Parameters:

attribute_name (str) – The name of the attribute values to retrieve.

Returns:

A list of attribute values for attribute_name.

click()[source]#

Click each matched element.

Example usage:

# Click the first element matched by the query
q.first.click()
Returns:

None

fill(text)[source]#

Set the text value of each matched element to text.

Example usage:

# Set the text of the first element matched by the query to "Foo"
q.first.fill('Foo')
Parameters:

text (str) – The text used to fill the element (usually a text field or text area).

Returns:

None

property focused#

Checks that at least one matched element is focused. More specifically, it checks whether the element is document.activeElement. If no matching element is focused, this returns False.

Returns:

bool

property html#

Retrieve the inner HTML of each element matched by the query.

Example usage:

# Assume that the query matches html elements:
# <div><span>Foo</span></div> and <div>Bar</div>
>> q.html
['<span>Foo</span>', 'Bar']
Returns:

The inner HTML for each element matched by the query.

property invisible#

Check whether all matched elements are present, but not visible.

Returns:

bool

is_focused()[source]#

Checks that at least one matched element is focused. More specifically, it checks whether the element is document.activeElement. If no matching element is focused, this returns False.

Returns:

bool

property selected#

Check whether all the matched elements are selected.

Returns:

bool

property text#

Retrieve text from each matched element.

Example usage:

# Assume that the query matches html elements:
# <div>Foo</div> and <div>Bar</div>
>> q.text
['Foo', 'Bar']
Returns:

The text of each element matched by the query.

property visible#

Check whether all matched elements are visible.

Returns:

bool

class bok_choy.query.Query(seed_fn, desc=None)[source]#

General mechanism for selecting and transforming values.

Configure the Query.

Parameters:

seed_fn (callable) – Callable with no arguments that produces a list of values.

Keyword Arguments:

desc (str) – A description of the query, used in log messages. If not provided, defaults to the name of the seed function.

Returns:

Query

execute(try_limit=5, try_interval=0.5, timeout=30)[source]#

Execute this query, retrying based on the supplied parameters.

Keyword Arguments:
  • try_limit (int) – The number of times to retry the query.

  • try_interval (float) – The number of seconds to wait between each try (float).

  • timeout (float) – The maximum number of seconds to spend retrying (float).

Returns:

The transformed results of the query.

Raises:

BrokenPromise – The query did not execute without a Selenium error after one or more attempts.

filter(filter_fn=None, desc=None, **kwargs)[source]#

Return a copy of this query, with some values removed.

Example usages:

# Returns a query that matches even numbers
q.filter(filter_fn=lambda x: x % 2)

# Returns a query that matches elements with el.description == "foo"
q.filter(description="foo")
Keyword Arguments:
  • filter_fn (callable) – If specified, a function that accepts one argument (the element) and returns a boolean indicating whether to include that element in the results.

  • kwargs – Specify attribute values that an element must have to be included in the results.

  • desc (str) – A description of the filter, for use in log messages. Defaults to the name of the filter function or attribute.

Raises:

TypeError – neither or both of filter_fn and kwargs are provided.

property first#

Return a Query that selects only the first element of this Query. If no elements are available, returns a query with no results.

Example usage:

>> q = Query(lambda: list(range(5)))
>> q.first.results
[0]
Returns:

Query

is_present()[source]#

Check whether the query returns any results.

Returns:

Boolean indicating whether the query contains any results.

map(map_fn, desc=None)[source]#

Return a copy of this query, with the values mapped through map_fn.

Parameters:

map_fn (callable) – A callable that takes a single argument and returns a new value.

Keyword Arguments:

desc (str) – A description of the mapping transform, for use in log message. Defaults to the name of the map function.

Returns:

Query

nth(index)[source]#

Return a query that selects the element at index (starts from 0). If no elements are available, returns a query with no results.

Example usage:

>> q = Query(lambda: list(range(5)))
>> q.nth(2).results
[2]
Parameters:

index (int) – The index of the element to select (starts from 0)

Returns:

Query

property present#

Check whether the query returns any results.

Returns:

Boolean indicating whether the query contains any results.

replace(**kwargs)[source]#

Return a copy of this Query, but with attributes specified as keyword arguments replaced by the keyword values.

Keyword Arguments:

copy. (Attributes/values to replace in the) –

Returns:

A copy of the query that has its attributes updated with the specified values.

Raises:

TypeError – The Query does not have the specified attribute.

property results#

A list of the results of the query, which are cached. If you call results multiple times on the same query, you will always get the same results. Use reset() to clear the cache and re-run the query.

Returns:

The results from executing the query.

transform(transform, desc=None)[source]#

Create a copy of this query, transformed by transform.

Parameters:

transform (callable) – Callable that takes an iterable of values and returns an iterable of transformed values.

Keyword Arguments:

desc (str) – A description of the transform, to use in log messages. Defaults to the name of the transform function.

Returns:

Query

bok_choy.query.no_error(func)[source]#

Decorator to create a Promise check function that is satisfied only when func executes without a Selenium error.

This protects against many common test failures due to timing issues. For example, accessing an element after it has been modified by JavaScript ordinarily results in a StaleElementException. Methods decorated with no_error will simply retry if that happens, which makes tests more robust.

Parameters:

func (callable) – The function to execute, with retries if an error occurs.

Returns:

Decorated function

web_app_test#

Base class for testing a web application.

class bok_choy.web_app_test.WebAppTest(*args, **kwargs)[source]#

Base class for testing a web application.

Create an instance of the class that will use the named test method when executed. Raises a ValueError if the instance does not have a method with the specified name.

get_web_driver()[source]#

Override NeedleTestCases’s get_web_driver class method to return the WebDriver instance that is already being used, instead of starting up a new one.

quit_browser()[source]#

Terminate the web browser which was launched to run the tests.

setUp()[source]#

Start the browser for use by the test. You must call this in the setUp method of any subclasses before using the browser!

Returns:

None

classmethod setUpClass()[source]#

Override NeedleTestCase’s setUpClass method so that it does not start up the browser once for each testcase class. Instead we start up the browser once per TestCase instance, in the setUp method.

set_viewport_size(width, height)[source]#

Override NeedleTestCases’s set_viewport_size class method because we need it to operate on the instance not the class.

See the Needle documentation at http://needle.readthedocs.org/ for information on this feature. It is particularly useful to predict the size of the resulting screenshots when taking fullscreen captures, or to test responsive sites.

classmethod tearDownClass()[source]#

Override NeedleTestCase’s tearDownClass method because it would quit the browser. This is not needed as we have already quit the browser after each TestCase, by virtue of a cleanup that we add in the setUp method.

property unique_id#

Helper method to return a uuid.

Returns:

39-char UUID string