import os.path
import capybara
from capybara.exceptions import ElementNotFound, FileNotFound
from capybara.queries.base_query import BaseQuery
[docs]class ActionsMixin(object):
"""
If the driver is capable of executing JavaScript, actions will wait for a set amount of time and
continuously retry finding the element until either the element is found or the time expires.
The length of time :meth:`find` will wait is controlled through
:data:`capybara.default_max_wait_time`.
"""
[docs] def attach_file(self, locator_or_path, path=None, **kwargs):
"""
Find a file field on the page and attach a file given its path. The file field can be found
via its name, id, or label text. ::
page.attach_file(locator, "/path/to/file.png")
Args:
locator_or_path (str): Which field to attach the file to, or the path of the file that
will be attached.
path (str, optional): The path of the file that will be attached. Defaults to
``locator_or_path``.
**kwargs: Arbitrary keyword arguments for :class:`SelectorQuery`.
Raises:
FileNotFound: No file exists at the given path.
"""
if path is None:
locator, path = None, locator_or_path
else:
locator = locator_or_path
if not os.path.isfile(path):
raise FileNotFound("cannot attach file, {0} does not exist".format(path))
self.find("file_field", locator, **kwargs).set(path)
[docs] def check(self, locator=None, allow_label_click=None, **kwargs):
"""
Find a check box and mark it as checked. The check box can be found via name, id, or label
text. ::
page.check("German")
Args:
locator (str, optional): Which check box to check.
allow_label_click (bool, optional): Attempt to click the label to toggle state if
element is non-visible. Defaults to :data:`capybara.automatic_label_click`.
**kwargs: Arbitrary keyword arguments for :class:`SelectorQuery`.
"""
self._check_with_label(
"checkbox", True, locator=locator, allow_label_click=allow_label_click, **kwargs)
[docs] def choose(self, locator=None, allow_label_click=None, **kwargs):
"""
Find a radio button and mark it as checked. The radio button can be found via name, id, or
label text. ::
page.choose("Male")
Args:
locator (str, optional): Which radio button to choose.
allow_label_click (bool, optional): Attempt to click the label to toggle state if
element is non-visible. Defaults to :data:`capybara.automatic_label_click`.
**kwargs: Arbitrary keyword arguments for :class:`SelectorQuery`.
"""
self._check_with_label(
"radio_button", True, locator=locator, allow_label_click=allow_label_click, **kwargs)
[docs] def click_link(self, locator=None, **kwargs):
"""
Finds a link by id, text, or title and clicks it. Also looks at image alt text inside the
link.
Args:
locator (str, optional): Text, id, title, or nested image's alt attribute.
**kwargs: Arbitrary keyword arguments for :class:`SelectorQuery`.
"""
return self.find("link", locator, **kwargs).click()
click_on = click_link_or_button
""" Alias for :meth:`click_link_or_button`. """
[docs] def fill_in(self, locator=None, current_value=None, value=None, fill_options=None, **kwargs):
"""
Locate a text field or text area and fill it in with the given text. The field can be found
via its name, id, or label text. ::
page.fill_in("Name", value="Bob")
Args:
locator (str, optional): Which field to fill in.
current_value (str, optional): The current value of the field.
value (str, optional): The value to fill in. Defaults to None.
fill_options (Dict, optional): Driver-specific options regarding how to fill fields.
**kwargs: Arbitrary keyword arguments for :class:`SelectorQuery`.
"""
if current_value is not None:
kwargs["value"] = current_value
fill_options = fill_options or {}
self.find("fillable_field", locator, **kwargs).set(value, **fill_options)
[docs] def select(self, value=None, field=None, **kwargs):
"""
If the ``field`` argument is present, ``select`` finds a select box on the page and selects
a particular option from it. Otherwise it finds an option inside the current scope and
selects it. If the select box is a multiple select, ``select`` can be called multiple times
to select more than one option. The select box can be found via its name, id, or label text.
The option can be found by its text. ::
page.select("March", field="Month")
Args:
value (str, optional): Which option to select.
field (str, optional): The id, name, or label of the select box.
**kwargs: Arbitrary keyword arguments for :class:`SelectorQuery`.
"""
if field:
self.find("select", field, **kwargs).find("option", value, **kwargs).select_option()
else:
self.find("option", value, **kwargs).select_option()
[docs] def uncheck(self, locator=None, allow_label_click=None, **kwargs):
"""
Find a check box and uncheck it. The check box can be found via name, id, or label text. ::
page.uncheck("German")
Args:
locator (str, optional): Which check box to uncheck.
allow_label_click (bool, optional): Attempt to click the label to toggle state if
element is non-visible. Defaults to :data:`capybara.automatic_label_click`.
**kwargs: Arbitrary keyword arguments for :class:`SelectorQuery`.
"""
self._check_with_label(
"checkbox", False, locator=locator, allow_label_click=allow_label_click, **kwargs)
[docs] def unselect(self, value=None, field=None, **kwargs):
"""
Find a select box on the page and unselect a particular option from it. If the select box is
a multiple select, ``unselect`` can be called multiple times to unselect more than one
option. The select box can be found via its name, id, or label text. ::
page.unselect("March", field="Month")
Args:
value (str, optional): Which option to unselect.
field (str, optional): The id, name, or label of the select box.
**kwargs: Arbitrary keyword arguments for :class:`SelectorQuery`.
"""
if field:
self.find("select", field, **kwargs).find("option", value, **kwargs).unselect_option()
else:
self.find("option", value, **kwargs).unselect_option()
def _check_with_label(self, selector, checked, locator=None, allow_label_click=None, visible=None, wait=None,
**kwargs):
"""
Args:
selector (str): The selector for the type of element that should be checked/unchecked.
checked (bool): Whether the element should be checked.
locator (str, optional): Which element to check.
allow_label_click (bool, optional): Attempt to click the label to toggle state if
element is non-visible. Defaults to :data:`capybara.automatic_label_click`.
visible (bool | str, optional): The desired element visibility. Defaults to
:data:`capybara.ignore_hidden_elements`.
wait (int | float, optional): The number of seconds to wait to check the element.
Defaults to :data:`capybara.default_max_wait_time`.
**kwargs: Arbitrary keyword arguments for :class:`SelectorQuery`.
"""
if allow_label_click is None:
allow_label_click = capybara.automatic_label_click
@self.synchronize(wait=BaseQuery.normalize_wait(wait))
def check_with_label():
element = None
try:
element = self.find(selector, locator, visible=visible, **kwargs)
element.set(checked)
except Exception as e:
if not allow_label_click or not self._should_catch_error(e):
raise
try:
if not element:
element = self.find(selector, locator, visible="all", **kwargs)
label = self.find("label", field=element, visible=True)
if element.checked != checked:
label.click()
except Exception:
raise e
check_with_label()