Skip to content

Commit 7204ac2

Browse files
committed
A bit more modeling ...
- Started to model the ElementFinder as a Protocol class - Moved _is_web_element and _disallow_webelement_parent to utitilies file
1 parent 58e0dea commit 7204ac2

File tree

2 files changed

+40
-36
lines changed

2 files changed

+40
-36
lines changed

src/SeleniumLibrary/locators/elementfinder.py

Lines changed: 16 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -27,35 +27,20 @@
2727
from SeleniumLibrary.utils import escape_xpath_value, events, is_falsy
2828

2929
from .customlocator import CustomLocator
30+
from .utilities import is_webelement, disallow_webelement_parent
3031

31-
32-
class Finder():
32+
class ElementFinder(Protocol):
3333
def __int__(self):
3434
"""Placeholder to Finder class instantiation method """
35-
pass
35+
...
3636

3737
def pre_find_action(self):
3838
"""Placeholder for the pre_find_action method"""
39-
pass
39+
...
4040

4141
def find(self):
4242
"""Placeholder for the find method"""
43-
pass
44-
45-
def _is_webelement(self, element):
46-
# Hook for unit tests
47-
return isinstance(element, (WebElement, EventFiringWebElement))
48-
49-
50-
def _parse_locator(self, locator):
51-
if re.match(r"\(*//", locator):
52-
return "xpath", locator
53-
index = self._get_locator_separator_index(locator)
54-
if index != -1:
55-
prefix = locator[:index].strip()
56-
if prefix in self._strategies:
57-
return prefix, locator[index + 1 :].lstrip()
58-
return "default", locator
43+
...
5944

6045

6146
class FinderList():
@@ -68,14 +53,17 @@ def __getitem__(self, item):
6853
def __len__(self):
6954
pass
7055

71-
class DefaultFinder(Finder):
56+
class DefaultElementFinder:
57+
def pre_find_action(self):
58+
pass
59+
7260
def find(self, locator, tag=None, first_only=True, required=True, parent=None):
7361
element_type = "Element" if not tag else tag.capitalize()
74-
if parent and not self._is_webelement(parent):
62+
if parent and not is_webelement(parent):
7563
raise ValueError(
7664
f"Parent must be Selenium WebElement but it was {type(parent)}."
7765
)
78-
if self._is_webelement(locator):
66+
if is_webelement(locator):
7967
return locator
8068
prefix, criteria = self._parse_locator(locator)
8169
strategy = self._strategies[prefix]
@@ -133,14 +121,6 @@ def _get_tag_and_constraints(self, tag):
133121
tag = "textarea"
134122
return tag, constraints
135123

136-
def _is_webelement(self, element):
137-
# Hook for unit tests
138-
return isinstance(element, (WebElement, EventFiringWebElement))
139-
140-
def _disallow_webelement_parent(self, element):
141-
if _is_webelement(element):
142-
raise ValueError("This method does not allow WebElement as parent")
143-
144124

145125
class LocatorElementEngine(ContextAware):
146126
def __init__(self, ctx):
@@ -186,11 +166,11 @@ def _split_locator(self, locator: Union[str, list]) -> list:
186166

187167
def _find(self, locator, tag=None, first_only=True, required=True, parent=None):
188168
element_type = "Element" if not tag else tag.capitalize()
189-
if parent and not self._is_webelement(parent):
169+
if parent and not is_webelement(parent):
190170
raise ValueError(
191171
f"Parent must be Selenium WebElement but it was {type(parent)}."
192172
)
193-
if self._is_webelement(locator):
173+
if is_webelement(locator):
194174
return locator
195175
prefix, criteria = self._parse_locator(locator)
196176
strategy = self._strategies[prefix]
@@ -351,7 +331,7 @@ def _find_by_xpath(self, criteria, tag, constraints, parent):
351331
)
352332

353333
def _find_by_dom(self, criteria, tag, constraints, parent):
354-
self._disallow_webelement_parent(parent)
334+
disallow_webelement_parent(parent)
355335
result = self.driver.execute_script(f"return {criteria};")
356336
if result is None:
357337
return []
@@ -360,7 +340,7 @@ def _find_by_dom(self, criteria, tag, constraints, parent):
360340
return self._filter_elements(result, tag, constraints)
361341

362342
def _find_by_jquery_selector(self, criteria, tag, constraints, parent):
363-
self._disallow_webelement_parent(parent)
343+
disallow_webelement_parent(parent)
364344
criteria = criteria.replace("'", "\\'")
365345
js = f"return jQuery('{criteria}').get();"
366346
return self._filter_elements(self.driver.execute_script(js), tag, constraints)
@@ -404,7 +384,7 @@ def _find_by_data_locator(self, criteria, tag, constraints, parent):
404384
return self._find_by_xpath(local_criteria, tag, constraints, parent)
405385

406386
def _find_by_sc_locator(self, criteria, tag, constraints, parent):
407-
self._disallow_webelement_parent(parent)
387+
disallow_webelement_parent(parent)
408388
criteria = criteria.replace("'", "\\'")
409389
js = f"return isc.AutoTest.getElement('{criteria}')"
410390
return self._filter_elements([self.driver.execute_script(js)], tag, constraints)
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
# Copyright 2008-2011 Nokia Networks
2+
# Copyright 2011-2016 Ryan Tomac, Ed Manlove and contributors
3+
# Copyright 2016- Robot Framework Foundation
4+
#
5+
# Licensed under the Apache License, Version 2.0 (the "License");
6+
# you may not use this file except in compliance with the License.
7+
# You may obtain a copy of the License at
8+
#
9+
# http://www.apache.org/licenses/LICENSE-2.0
10+
#
11+
# Unless required by applicable law or agreed to in writing, software
12+
# distributed under the License is distributed on an "AS IS" BASIS,
13+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
# See the License for the specific language governing permissions and
15+
# limitations under the License.
16+
17+
def is_webelement(self, element):
18+
# Hook for unit tests
19+
return isinstance(element, (WebElement, EventFiringWebElement))
20+
21+
def disallow_webelement_parent(self, element):
22+
if is_webelement(element):
23+
raise ValueError("This method does not allow WebElement as parent")
24+

0 commit comments

Comments
 (0)