Skip to content

Commit

Permalink
QE-11613 Add helper for ensuring state; use for checkboxes (#329)
Browse files Browse the repository at this point in the history
These steps will allow us to have idempotent steps for things like
configuration.
  • Loading branch information
ddl-kgarton authored May 15, 2023
1 parent c792cc2 commit 5a3252a
Show file tree
Hide file tree
Showing 5 changed files with 141 additions and 2 deletions.
4 changes: 4 additions & 0 deletions data/www/checkboxes.html
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,10 @@
<br/>
<input onclick="update('disabled checkbox')" disabled type="checkbox"><label>disabled checkbox</label></input>
<br/>
<input onclick="update('default checked checkbox')" type="checkbox" checked><label>default checked checkbox</label></input>
<br/>
<input onclick="update('default unchecked checkbox')" type="checkbox"><label>default unchecked checkbox</label></input>
<br/>

<label class="container">
<input type="checkbox">
Expand Down
14 changes: 14 additions & 0 deletions features/browser/helpers.feature
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,20 @@ Feature: Helpers
Then I should see the checkbox "checkbox with inner label" is checked
"""

Scenario: User can ensure a checkbox is in a desired state
Given I start a webserver at directory "data/www" and save the port to the variable "PORT"
And I open a browser at the url "http://{HOST_ADDRESS}:{PORT}/checkboxes.html"
When I ensure the checkbox "default checked checkbox" is checked
Then I should see the checkbox "default checked checkbox" is checked
When I uncheck the checkbox "default checked checkbox"
And I ensure the checkbox "default checked checkbox" is checked
Then I should see the checkbox "default checked checkbox" is checked
When I ensure the checkbox "default unchecked checkbox" is not checked
Then I should see the checkbox "default unchecked checkbox" is not checked
When I check the checkbox "default unchecked checkbox"
And I ensure the checkbox "default unchecked checkbox" is not checked
Then I should see the checkbox "default unchecked checkbox" is not checked

Scenario: User gets appropriate error when waiting to see a checkbox is not in the expected state
Given I set the variable "CUCU_STEP_WAIT_TIMEOUT_S" to "5"
And I start a webserver at directory "data/www" and save the port to the variable "PORT"
Expand Down
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[tool.poetry]
name = "cucu"
version = "0.128.0"
version = "0.129.0"
license = "MIT"
description = ""
authors = ["Rodney Gomes <[email protected]>"]
Expand Down
115 changes: 115 additions & 0 deletions src/cucu/helpers.py
Original file line number Diff line number Diff line change
Expand Up @@ -371,6 +371,121 @@ def action_the_nth(ctx, seconds, nth, name):
)


def define_ensure_state_on_thing_with_name_steps(
thing, state, find_func, state_func, action_func, with_nth=False
):
"""
defines steps with with the following signatures:
I ensure the {thing} "{name}" is {state}
I wait to ensure the {thing} "{name}" is {state}
I wait up to "{seconds}" seconds to ensure the {thing} "{name}" is {state}
when with_nth=True we also define:
I ensure the "{nth}" {thing} "{name}" is {state}
I wait to ensure the "{nth}" {thing} "{name}" is {state}
I wait up to "{seconds}" seconds to ensure the "{nth}" {thing} "{name}" is {state}
parameters:
thing(string): name of the thing we're creating the steps for such
as button, dialog, etc.
state(stirng): the name of the state we want to ensure, such as:
filled, checked, empty, not empty, etc.
find_func(function): function that returns the desired element:
def find_func(ctx, name, index=):
'''
ctx(object): behave context object
name(string): name of the thing to find
index(int): when there are multiple elements
with the same name and you've
specified with_nth=True
'''
state_func(function): function that returns True if the element is in
the desired state and False otherwise:
def state_func(element):
'''
element(object): the element found
'''
action_func(function): action that will set the desired state on the
element if state_func returns False:
def action_func(ctx, element):
'''
ctx(object): behave context object
element(object): the element found
'''
with_nth(bool): when set to True we'll define the expanded set of
"nth" steps. default: False
"""

# undecorated def for reference below
def base_ensure_the(ctx, thing, name, index=0):
prefix = nth_to_ordinal(index)
element = find_func(ctx, name, index=index)

if element is None:
raise RuntimeError(f'unable to find the {prefix}{thing} "{name}"')

if not state_func(element):
action_func(ctx, element)

@step(f'I immediately ensure the {thing} "{{name}}" is {state}')
def immediately_ensure_the(ctx, name, state):
base_ensure_the(ctx, thing, name)

@step(f'I ensure the {thing} "{{name}}" is {state}')
def ensure_the(ctx, name):
retry(
base_ensure_the,
retry_after_s=float(CONFIG["CUCU_SHORT_UI_RETRY_AFTER_S"]),
wait_up_to_s=float(CONFIG["CUCU_SHORT_UI_WAIT_TIMEOUT_S"]),
)(ctx, thing, name)

@step(f'I wait to ensure the {thing} "{{name}}" is {state}')
def wait_to_ensure_the(ctx, name):
retry(base_ensure_the)(ctx, thing, name)

@step(
f'I wait up to "{{seconds}}" seconds to ensure the {thing} "{{name}}" is {state}'
)
def wait_up_to_seconds_to_ensure_the(ctx, seconds, name):
seconds = float(seconds)
retry(base_ensure_the, wait_up_to_s=seconds)(ctx, thing, name)

if with_nth:

@step(
f'I immediately ensure the "{{nth:nth}}" {thing} "{{name}}" is {state}'
)
def immediately_ensure_the_nth(ctx, nth, name):
base_ensure_the(ctx, thing, name, index=nth)

@step(f'I ensure the "{{nth:nth}}" {thing} "{{name}}"')
def ensure_the_nth(ctx, nth, name):
retry(
base_ensure_the,
retry_after_s=float(CONFIG["CUCU_SHORT_UI_RETRY_AFTER_S"]),
wait_up_to_s=float(CONFIG["CUCU_SHORT_UI_WAIT_TIMEOUT_S"]),
)(ctx, thing, name, index=nth)

@step(
f'I wait to ensure the "{{nth:nth}}" {thing} "{{name}}" is {state}'
)
def ensure_the_nth(ctx, nth, name):
retry(base_ensure_the)(ctx, thing, name, index=nth)

@step(
f'I wait up to "{{seconds}}" seconds to ensure the "{{nth:nth}}" {thing} "{{name}}" is {state}'
)
def ensure_the_nth(ctx, seconds, nth, name):
seconds = float(seconds)
retry(base_ensure_the, wait_up_to_s=seconds)(
ctx, thing, name, index=nth
)


def define_thing_with_name_in_state_steps(
thing, state, find_func, is_in_state_func, with_nth=False
):
Expand Down
8 changes: 7 additions & 1 deletion src/cucu/steps/checkbox_steps.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
from cucu import helpers, fuzzy
from cucu import helpers, fuzzy, step
from . import base_steps


Expand Down Expand Up @@ -97,3 +97,9 @@ def uncheck_checkbox(ctx, checkbox):
helpers.define_run_steps_if_I_can_see_element_with_name_steps(
"checkbox", find_checkbox
)
helpers.define_ensure_state_on_thing_with_name_steps(
"checkbox", "checked", find_checkbox, is_checked, check_checkbox
)
helpers.define_ensure_state_on_thing_with_name_steps(
"checkbox", "not checked", find_checkbox, is_not_checked, uncheck_checkbox
)

0 comments on commit 5a3252a

Please sign in to comment.