Skip to content

Commit

Permalink
Standardize how parent_locator is set in Field, Area, Repeating. Fixe…
Browse files Browse the repository at this point in the history
…s issues with nested Areas and Repeating. (#327)
  • Loading branch information
jsfehler authored Jan 18, 2021
1 parent 1642f49 commit a16a1c7
Show file tree
Hide file tree
Showing 6 changed files with 41 additions and 18 deletions.
8 changes: 8 additions & 0 deletions stere/areas/area.py
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,14 @@ def __init__(self, root=None, **kwargs):

self._workflow = None

def _set_parent_locator(self, element):
"""For every item in the Area, set a parent_locator."""
if self.root is not None:
self.root._set_parent_locator(element)
else:
for _, v in self._items.items():
v._set_parent_locator(element)

def workflow(self, value: str):
"""Set the current workflow for an Area.
Expand Down
11 changes: 5 additions & 6 deletions stere/areas/repeating.py
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,10 @@ def __init__(self, root, repeater):
self.repeater = repeater
self.repeater_name = type(self.repeater).__name__

def _set_parent_locator(self, element):
"""Set the parent_locator of the root."""
self.root._element.parent_locator = element

def new_container(self) -> typing.Any:
"""Must return an object to contain results from Repeater.children()
Expand Down Expand Up @@ -115,12 +119,7 @@ def children(self) -> typing.Any:
for root in all_roots:
copy_repeater = copy.deepcopy(self.repeater)
# Set the repeater's parent locator to the found root instance
try:
copy_repeater.root._element.parent_locator = root
except AttributeError:
# Repeater has no 'root' attribute, eg: It's an Area
for _, v in copy_repeater._items.items():
v._element.parent_locator = root
copy_repeater._set_parent_locator(root)

container.append(copy_repeater)

Expand Down
13 changes: 1 addition & 12 deletions stere/areas/repeating_area.py
Original file line number Diff line number Diff line change
Expand Up @@ -102,18 +102,7 @@ def children(self) -> Areas:
for field_name in copy_items.keys():
child = copy_items[field_name]

# Every Field in the Area gets the root set here.
if isinstance(child, Field):
child._element.parent_locator = root
# Area inside an Area
elif isinstance(child, Area):
# Has root
if child.root:
child.root._element.parent_locator = root
# Has no root
else:
for _, v in child._items.items():
v._element.parent_locator = root
child._set_parent_locator(root)

new_area = self.repeater(**copy_items)
container.append(new_area)
Expand Down
4 changes: 4 additions & 0 deletions stere/fields/field.py
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,10 @@ def __repr__(self):
f'{self.__class__.__name__} - '
f'Strategy: {self.strategy}, Locator: {self.locator}')

def _set_parent_locator(self, element):
"""Set the parent locator of this Field's element."""
self._element.parent_locator = element

@property
def element(self):
"""Tries to find the element, then returns the results."""
Expand Down
11 changes: 11 additions & 0 deletions tests/splinter/pages/dummy.py
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,17 @@ def __init__(self):
),
)

# Repeating with an Area with a RepeatingArea with no root
self.repeating_area_repeatingarea = Repeating(
root=Root('css', '.repeatingRepeating'),
repeater=Area(
it_repeats=RepeatingArea(
root=Root('css', '.test_repeating_area_root'),
text=Text('css', '.test_repeating_area_test'),
),
),
)

# Area with a RepeatingArea inside
self.area_repeating_area = Area(
root=Root('xpath', '/html/body/div[10]'),
Expand Down
12 changes: 12 additions & 0 deletions tests/splinter/test_repeating.py
Original file line number Diff line number Diff line change
Expand Up @@ -78,3 +78,15 @@ def test_repeating_plus_area(test_page):
listings = test_page.repeating_with_area.children()
assert listings[0].link.text == "Repeating Link 1"
assert listings[1].link.text == "Repeating Link 2"


def test_repeating_plus_area_with_repeatingarea(test_page):
"""When Repeating has an Area as the repeater
And the Area has no root
And the Area has a RepeatingArea
Then the RepetingArea should get the root from the Repeating
"""
test_page.navigate()

listings = test_page.repeating_area_repeatingarea.children()
assert listings[0].it_repeats.areas[0].text.text == "Repeating Area A1"

0 comments on commit a16a1c7

Please sign in to comment.