Fields

class stere.fields.Field

Field objects represent individual pieces on a web page. Conceptually, they’re modelled after general behaviours, not specific HTML elements.

Parameters:
  • strategy (str) – The type of strategy to use when locating an element.
  • locator (str) – The locator for the strategy.
  • workflows (list) – Any workflows the Field should be included with.

Example:

>>> from stere.fields import Field
>>> my_field = Field('xpath', '//*[@id="js-link-box-pt"]/small/span')
includes()

Will search every element found by the Field for a value property that matches the given value. If an element with a matching value is found, it’s then returned.

Useful for when you have non-unique elements and know a value is in one of the elements, but don’t know which one.

Parameters:value (str) – A text string inside an element you want to find.
Returns:element

Example:

>>> class PetStore(Page):
>>>     def __init__(self):
>>>         self.inventory_list = Link('xpath', '//div')
>>>
>>> pet_store = PetStore()
>>> pet_store.inventory_list.includes("Kittens").click()
before()

Called automatically before methods with the @use_before decorator are called.

By default it does nothing. Override this method if an action must be taken before the method has been called.

In this example, Dropdown has been subclassed to hover over the Dropdown before clicking.

from stere.fields import Dropdown

class CSSDropdown(Dropdown):
    """A Dropdown that's customized to hover over the element before attempting
    a select.
    """
    def before(self):
        self.element.mouse_over()
after()

Called automatically before methods with the @use_after decorator are called.

By default it does nothing. Override this method if an action must be taken after the method has been called.

Performer method

A Field can have a single method be designated as a performer. This causes the method to be called when the Field is inside an Area and that Area’s perform() method is called.

For example, Input’s performer is the fill() method, and Button’s performer is the click() method. Given the following:

self.search = Area(
    query=Input('id', 'xsearch'),
    submit=Button('id', 'xsubmit'),
)

When search.perform() is called, query.fill() is called, followed by submit.click().

See the documentation for Area for more details.

Assigning the performer method

When creating a new type of Field, the stere_performer class decorator can be used to assign a performer method.

from stere.fields.field import stere_performer

@stere_performer('philosophize', consumes_arg=False)
class DiogenesButton(Field):
    def philosophize(self):
        print("As a matter of self-preservation, a man needs good friends or ardent enemies, for the former instruct him and the latter take him to task.")

The consumes arg argument should be used to specify if the method should use an argument provided by Area.perform() or not.

Subclassing Field

Field can be subclassed to suit your own requirements.

If the __init__() method is overwritten, make sure to call super() before your own code.

If your class needs specific behaviour when interacting with Areas, it must implement the perform() method.

Splinter Fields

Fields that rely on Splinter being connected to Stere.

The following Fields are available with the default Splinter implementation:

  • Button: Clickable object.
  • Checkbox: Object with a set and unset state.
  • Dropdown: Object with multiple options to choose from.
  • Input: Object that accepts keyboard input.
  • Link: Clickable text.
  • Root: Parent container.
  • Text: Non-interactive text.
class stere.fields.Button

Convenience Class on top of Field, it implements click() as its performer.

Button.click()

Uses Splinter’s click method.

class stere.fields.Checkbox

By default, the Checkbox field works against HTML inputs with type=”checkbox”.

Can be initialized with the default_checked argument. If True, the Field assumes the checkbox’s default state is checked.

It implements opposite() as its performer.

Checkbox.set_to()

Set a checkbox to the desired state.

Parameters:state (bool) – True for check, False for uncheck
Checkbox.toggle()

If the checkbox is checked, uncheck it. If the checkbox is unchecked, check it.

Checkbox.opposite()

Switches the checkbox to the opposite of its default state. Uses the default_checked attribute to decide this.

class stere.fields.Dropdown

By default, the Dropdown field works against HTML Dropdowns. However, it’s possible to extend Dropdown to work with whatever implementation of a CSS Dropdown you need.

It implements select() as its performer.

The option argument can be provided to override the default implementation. This argument expects a Field. The Field should be the individual options in the dropdown you wish to target.

self.languages = Dropdown('id', 'langDrop', option=Button('xpath', '/h4/a/strong'))
Dropdown.options()

Searches for all the elements that are an option in the dropdown.

Returns:list
Dropdown.select()

Searches for an option by its html content, then clicks the one that matches.

Parameters:value (str) – The option value to select.
Raises:ValueError – The provided value could not be found in the dropdown.
class stere.fields.Input

A simple wrapper over Field, it implements fill() as its performer.

Input.fill()

Fills the element with value.

A simple wrapper over Field, it implements click() as its performer.

Link.click()

Clicks the element.

class stere.fields.Root

A simple wrapper over Field, it does not implement a performer method.

class stere.fields.Text

A simple wrapper over Field, it does not implement a performer method.

Location Strategies

These represent the way a locator will be searched for.

By default, the strategies available are:

  • css
  • xpath
  • tag
  • name
  • text
  • id
  • value

These all use Splinter. If you’re using a different automation tool, you must create your strategies. These can override the default strategies. (ie: You can create a custom css strategy to replace the default)

Custom Locator Strategies

Custom strategies can be defined using the @strategy decorator on top of a Class.

Any class can be decorated with @strategy, as long as the _find_all and _find_all_in_parent methods are implemented.

In the following example, the ‘data-test-id’ strategy is defined. It wraps Splinter’s find_by_xpath method to simplify the locator required on the Page Object.

from stere.strategy import strategy


@strategy('data-test-id')
class FindByDataTestId():
    def is_present(self, *args, **kwargs):
        return self.browser.is_element_present_by_xpath(f'.//*[@data-test-id="{self.locator}"]')

    def is_not_present(self, *args, **kwargs):
        return self.browser.is_element_not_present_by_xpath(f'.//*[@data-test-id="{self.locator}"]')

    def _find_all(self):
        """Find from page root."""
        return self.browser.find_by_xpath(f'.//*[@data-test-id="{self.locator}"]')

    def _find_all_in_parent(self):
        """Find from inside parent element."""
        return self.parent_locator.find_by_xpath(f'.//*[@data-test-id="{self.locator}"]')

With this implemented, Fields can now be defined like so:

my_button = Button('data-test-id', 'MyButton')