Skip to content

Commit

Permalink
Add Repeating.has_children() method (#240)
Browse files Browse the repository at this point in the history
  • Loading branch information
jsfehler authored Nov 16, 2019
1 parent a5f0e25 commit 70300d7
Show file tree
Hide file tree
Showing 6 changed files with 69 additions and 59 deletions.
18 changes: 18 additions & 0 deletions stere/areas/repeating.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
import copy
import typing

from ..utils import _retry


class Repeating:
Expand Down Expand Up @@ -114,3 +117,18 @@ def children(self):
container.append(copy_items)

return container

def has_children(self, retry_time: typing.Optional[int] = None) -> bool:
"""Check if any children can be found.
Arguments:
retry_time: Number of seconds to check for.
Returns:
bool
"""
return _retry(
lambda: len(self.children()) > 0,
retry_time=retry_time,
)
31 changes: 7 additions & 24 deletions stere/fields/field.py
Original file line number Diff line number Diff line change
@@ -1,23 +1,6 @@
import time

from .decorators import stere_performer
from .element_builder import build_element


def _try_until_timeout(func=None, wait_time=0):
"""Try to get a True value from a function and return it. Once the
timeout is hit, then return False instead.
Arguments:
func (function): The function to try to execute
wait_time (int): Number of seconds to wait
"""
end_time = time.time() + wait_time
while time.time() < end_time:
if func():
return True

return False
from ..utils import _retry


@stere_performer('null_action', consumes_arg=False)
Expand Down Expand Up @@ -179,9 +162,9 @@ def value_contains(self, expected, wait_time=2):
>>> assert pet_store.price.value_contains("19.19", wait_time=6)
"""
return _try_until_timeout(
func=lambda: expected in self.value,
wait_time=wait_time,
return _retry(
lambda: expected in self.value,
retry_time=wait_time,
)

def value_equals(self, expected, wait_time=2):
Expand All @@ -204,9 +187,9 @@ def value_equals(self, expected, wait_time=2):
>>> assert pet_store.price.value_equals("$19.19", wait_time=6)
"""
return _try_until_timeout(
func=lambda: expected == self.value,
wait_time=wait_time,
return _retry(
lambda: expected == self.value,
retry_time=wait_time,
)

def find(self):
Expand Down
25 changes: 1 addition & 24 deletions stere/strategy/splinter.py
Original file line number Diff line number Diff line change
@@ -1,31 +1,8 @@
import copy
import time
import typing

from stere import Stere

from .strategy import strategy


def _retry(fn, retry_time: typing.Optional[int] = None) -> bool:
"""Retry a function for a specific amount of time.
Returns:
True if the function returns a truthy value, else False
Arguments:
fn: Function to retry
retry_time: Number of seconds to retry. If not specified,
Stere.retry_time will be used.
"""
retry_time = retry_time or Stere.retry_time
end_time = time.time() + retry_time

while time.time() < end_time:
if fn():
return True
return False
from ..utils import _retry


class SplinterBase:
Expand Down
25 changes: 25 additions & 0 deletions stere/utils.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,33 @@
import time
import typing
from functools import reduce

from stere import Stere


def rgetattr(obj, attr, *args):
"""A nested getattr"""
def _getattr(obj, attr):
return getattr(obj, attr, *args)
return reduce(_getattr, [obj] + attr.split('.'))


def _retry(fn, retry_time: typing.Optional[int] = None) -> bool:
"""Retry a function for a specific amount of time.
Returns:
True if the function returns a truthy value, else False
Arguments:
fn (function): Function to retry
retry_time: Number of seconds to retry. If not specified,
Stere.retry_time will be used.
"""
retry_time = retry_time or Stere.retry_time
end_time = time.time() + retry_time

while time.time() < end_time:
if fn():
return True
return False
22 changes: 11 additions & 11 deletions tests/splinter/test_field.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,35 +6,35 @@
from selenium.webdriver.remote.remote_connection import LOGGER

from stere.fields import Field
from stere.fields.field import _try_until_timeout
from stere.utils import _retry

LOGGER.setLevel(logging.WARNING)


def test_try_until_timeout():
"""When I call _try_until_timeout
def test_retry():
"""When I call _retry
Then a function is called until it returns a True value
"""
now = time.time()

result = _try_until_timeout(
func=lambda: True if time.time() >= (now + 6) else False,
wait_time=8,
result = _retry(
lambda: True if time.time() >= (now + 6) else False,
retry_time=8,
)

assert result


def test_try_until_timeout_fails():
"""When I call _try_until_timeout
def test_retry_fails():
"""When I call _retry
And the timeout is hit
Then it returns False
"""
now = time.time()

result = _try_until_timeout(
func=lambda: True if time.time() == (now + 6) else False,
wait_time=4,
result = _retry(
lambda: True if time.time() == (now + 6) else False,
retry_time=4,
)

assert not result
Expand Down
7 changes: 7 additions & 0 deletions tests/splinter/test_repeating.py
Original file line number Diff line number Diff line change
Expand Up @@ -60,3 +60,10 @@ def test_all_roots_not_found(test_page):
'Could not find any RepeatingArea using the root: '
'.repeatingRepeating',
)


def test_has_children(test_page):
test_page.navigate()

r = test_page.repeating
assert r.has_children()

0 comments on commit 70300d7

Please sign in to comment.