Fields

Field

class stere.fields.Field

The representation of individual page components.

Conceptually, they’re modelled after general behaviours, not specific HTML tags.

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')
element

The result of a search operation on the page. All attribute calls on the Field that fail are then tried on the element.

This allows classes inheriting from Field to act as a proxy to the underlying automation library.

Using Splinter’s visible attribute as an example, the following methods are analogous:

>>> Field.visible == Field.find().visible == Field.element.visible
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 = Link('xpath', '//li[@class="inv"]')
>>>
>>> pet_store = PetStore()
>>> pet_store.inventory_list.includes("Kittens").click()
before()

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

Performer methods are decorated with @use_before.

By default it does nothing. Override this method if an action must be taken before a method is called.

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

Example

>>> from stere.fields import Dropdown
>>>
>>> class CSSDropdown(Dropdown):
>>>     def before(self):
>>>         self.element.mouse_over()
after()

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

Performer methods are decorated with @use_after.

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

value_contains()

Check if the value of the Field contains an expected value.

Parameters:
  • expected (str) – The expected value of the Field
  • wait_time (int) – The number of seconds to search. Default is Stere.retry_time.
Returns:

Object with the boolean result of the comparison.

Return type:

ValueComparator

Example

>>> class PetStore(Page):
>>>     def __init__(self):
>>>         self.price = Link('xpath', '//li[@class="price"]')
>>>
>>> pet_store = PetStore()
>>> assert pet_store.price.value_contains("19.19", wait_time=6)
value_equals()

Check if the value of the Field equals an expected value.

Parameters:
  • expected (str) – The expected value of the Field
  • wait_time (int) – The number of seconds to search. Default is Stere.retry_time.
Returns:

Object with the boolean result of the comparison.

Return type:

ValueComparator

Example

>>> class PetStore(Page):
>>>     def __init__(self):
>>>         self.price = Link('xpath', '//li[@class="price"]')
>>>
>>> pet_store = PetStore()
>>> assert pet_store.price.value_equals("$19.19", wait_time=6)

Root

class stere.fields.Root

A simple wrapper over Field, it does not implement a performer method. Although Root has no specific behaviour, it can be useful when declaring a root for an Area or RepeatingArea.

Example

>>> from stere.areas import RepeatingArea
>>> from stere.fields import Root
>>>
>>>
>>> collections = RepeatingArea(
>>>     root=Root('xpath', '//table/tr'),
>>>     quantity=Text('css', '.collection_qty'),
>>> )

Text

class stere.fields.Text

A simple wrapper over Field, it does not implement a performer method. Although Text has no specific behaviour, it can be useful when declaring that a Field should just be static Text.

Example

>>> from stere.fields import Text
>>>
>>>
>>> self.price = Text('id', 'item_price')

Performer method

A Field can have a single method be designated as a performer. This method will 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 Area:

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

and the following script:

search.perform('Orange')

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

See the documentation for Area for more details.

Calling the performer method explicitly

The performer method is available as Field.perform(). Calling it will run the performer method, but they are not aliases.

No matter what the return value of the performer method is, the return value from calling Field.perform() will always be the Field.returns attribute.

Using the splinter Button Field as an example, the only difference between Button.click() and Button.perform() is that perform will return the object set in the Field.returns attribute. See Returning Objects for more details.

Calling the performer method implicitly

When a page instance is called directly, the perform() method will be executed.

The following code will produce the same results:

button = Button()
button.perform()
button = Button()
button()

Events

Fields inherit from an EventEmitter class.

By default, they emit the following events:

  • before: Before methods with the @use_before decorator are called.
  • after: After methods with the @use_after decorator are called.
Field.on()

Register a new listener to an event.

If the event does not exist, it will be created.

Parameters:
  • event (str) – The name of the event to register a listener to.
  • listener (Callable) – The function to run when the event is emitted.
Returns:

The list of listeners for the event.

Return type:

list

Example

>>> def my_event_function(emitter):
>>>    pass
>>>
>>> my_field = Field()
>>> my_field.on('before', my_event_function)
Field.emit()

Emit an event.

Every listener registered to the event will be called with the emitter class as the first argument.

Listeners are called in the order of registration.

Parameters:event (str) – The name of the event to emit.
Raises:ValueError – If the event has not been registered.
Field.events

Get the names of every registered event.

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 be wrapped with the @stere_performer decorator to specify a performer method.

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

Field Decorators

decorators.stere_performer()

Wrap a class to associate method_name with the perform() method.

Associating a method with perform allows the class to be fully used by Area objects via Area.perform().

Parameters:
  • method_name (str) – The name of the method to perform
  • consumes_args (bool) – True if the method takes an argument, else False

In the following example, when Philosophers().diogenes_area.perform() is called, DiogenesButton.philosophize() is called.

Example

>>> @stere_performer('philosophize', consumes_arg=False)
>>> class DiogenesButton(Field):
>>>     def philosophize(self):
>>>         print("As a matter of self-preservation, ")
>>>         print("a man needs good friends or ardent enemies, ")
>>>         print("for the former instruct him and the latter ")
>>>         print("take him to task.")
>>>
>>>
>>> class Philosophers(Page):
>>>     def __init__(self):
>>>         self.diogenes_area = Area(
>>>             quote_button=DiogenesButton('id', 'idDio'),
>>>             next_button=Button('id', 'idNext'),
>>>         )
>>>
>>>
>>> Philosophers().diogenes_area.perform()
decorators.use_before()

When used on a method in a Field, the following will occur before the decorated method is called: - The Field’s before() method will be called. - Any listeners registered to the ‘before’ event will be called.

Example

>>> class TransformingButton(Field):
>>>     def before(self):
>>>         print('Autobots! Transform and...')
>>>
>>>     @use_before
>>>     def roll_out(self):
>>>         print('roll out!')
>>>
>>> tf = TransformingButton()
>>> tf.roll_out()
>>>
>>> "Autobots! Transform and..."
>>> "roll out!"
decorators.use_after()

When used on a method in a Field, the following will occur after the decorated method is called: - The Field’s after() method will be called. - Any listeners registered to the ‘after’ event will be called.

Example

>>> class TransformingButton(Field):
>>>     def after(self):
>>>         print('rise up!')
>>>
>>>     @use_after
>>>     def transform_and(self):
>>>         print('Decepticons, transform and...')
>>>
>>> tf = TransformingButton()
>>> tf.transform_and()
>>>
>>> "Decepticons, transform and..."
>>> "rise up!"