Skip to content

Commit

Permalink
Merge pull request #135 from ggozad/FIX-form-timeout-steps
Browse files Browse the repository at this point in the history
Fix form timeout steps
  • Loading branch information
ggozad authored Apr 3, 2023
2 parents cf10a44 + 9369cea commit 0718b43
Show file tree
Hide file tree
Showing 6 changed files with 70 additions and 34 deletions.
2 changes: 1 addition & 1 deletion .pre-commit-config.yaml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
repos:
- repo: https://github.com/charliermarsh/ruff-pre-commit
rev: v0.0.239
rev: v0.0.260
hooks:
- id: ruff
args: ["--fix"]
Expand Down
5 changes: 5 additions & 0 deletions CHANGES.txt
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
Changelog
=========
3.1.5 -
------------------

- Fix form steps to accept a timeout ("within X seconds").
[ggozad]

3.1.4 - 2023-03-31
------------------
Expand Down
39 changes: 20 additions & 19 deletions poetry.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ smsmock = "behaving.sms.mock:main"
gcmmock = "behaving.notifications.gcm.mock:main"

[tool.poetry.group.dev.dependencies]
ruff = "^0.0.190"
ruff = "^0.0.260"
black = "^23.1.0"
pdbpp = "^0.10.3"

Expand Down
45 changes: 37 additions & 8 deletions src/behaving/web/steps/forms.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,16 +7,17 @@
from splinter.exceptions import ElementDoesNotExist

from behaving.personas.persona import persona_vars
from behaving.web.steps.basic import _retry

# Selenium 3 does not account for base64 no longer using encodestring.
# Monkey patch base64 to make it compatible seems the easiest.
base64.encodestring = base64.encodebytes


def find_by_name_or_id(context, selector):
el = context.browser.find_by_name(selector)
def find_by_name_or_id(context, selector, timeout=None):
el = context.browser.find_by_name(selector, wait_time=timeout)
if not el:
el = context.browser.find_by_id(selector)
el = context.browser.find_by_id(selector, wait_time=timeout)
assert el, f"Element with name or id {selector} not found"
return el.first

Expand Down Expand Up @@ -195,21 +196,49 @@ def set_html_content_to_element_with_class(context, klass, contents):


@then('field "{name}" should have the value "{value}"')
@then('field "{name}" should have the value "{value}" within {timeout:d} seconds')
@persona_vars
def field_has_value_within_timeout(context, name, value, timeout=None):
def field_has_value_within_timeout(context, name, value, timeout=0):
def check():
try:
el = find_by_name_or_id(context, name)
return el and el.value == value
except AssertionError:
return False

if _retry(check, timeout):
return
el = find_by_name_or_id(context, name)
assert (
el.value == value
False
), f'Values for element {name} do not match, expected "{value}" but got "{el.value}"'


@then('the selection "{name}" should have the option "{values}" selected')
@then('the selection "{name}" should have the options "{values}" selected')
@then(
'the selection "{name}" should have the option "{values}" selected within {timeout:d} seconds'
)
@then(
'the selection "{name}" should have the options "{values}" selected within {timeout:d} seconds'
)
@persona_vars
def select_has_selected_within_timeout(context, name, values, timeout=None):
el = find_by_name_or_id(context, name)
assert el.tag_name == "select", f"Element {name} is not a <select/>"
def select_has_selected_within_timeout(context, name, values, timeout=0):
values = set([v.strip() for v in values.split(",")])

def check():
try:
el = find_by_name_or_id(context, name)
options = el.find_by_tag("option")
selected = set([o.value for o in options if o.selected])
return el and values == selected
except AssertionError:
return False

if _retry(check, timeout):
return

el = find_by_name_or_id(context, name)
options = el.find_by_tag("option")
selected = set([o.value for o in options if o.selected])
assert (
Expand Down
11 changes: 6 additions & 5 deletions tests/features/forms.feature
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,9 @@ Feature: Forms
When I visit "http://web/forms.html"
Then "disabled" should be disabled
And "name" should be enabled
When I fill in "name" with "Foo Bar"
Then field "name" should have the value "Foo Bar"

# Checking field values with timeout
When I execute the script "setTimeout(() => { document.getElementsByName('name')[0].value = 'Foo Bar'}, 2000)"
Then field "name" should have the value "Foo Bar" within 3 seconds
When I fill in "passwd" with "hax0r"
Then field "passwd" should have the value "hax0r"
When I choose "male" from "sex"
Expand All @@ -22,8 +22,9 @@ Feature: Forms
When I toggle "digest"
Then the field "digest" should be checked
When I select "no" from "countries"
And I select by text "Greece" from "countries"
Then the selection "countries" should have the options "gr, no" selected
Then the selection "countries" should have the options "no" selected
When I execute the script "setTimeout(() => { document.getElementsByName('countries')[0].options[0].selected = true}, 2000)"
Then the selection "countries" should have the options "gr, no" selected within 3 seconds
When I attach the file "test.txt" to "file"
And I press "register"
Then the browser's URL should contain "name=Foo+Bar"
Expand Down

0 comments on commit 0718b43

Please sign in to comment.