17 from robot.api
import logger
18 from robot.utils
import NormalizedDict
19 from selenium.webdriver.remote.webelement
import WebElement
25 from .customlocator
import CustomLocator
31 ContextAware.__init__(self, ctx)
48 self.
_strategies_strategies = NormalizedDict(initial=strategies, caseless=
True,
52 None: [
'@id',
'@name'],
53 'a': [
'@id',
'@name',
'@href',
54 'normalize-space(descendant-or-self::text())'],
55 'img': [
'@id',
'@name',
'@src',
'@alt'],
56 'input': [
'@id',
'@name',
'@value',
'@src'],
57 'button': [
'@id',
'@name',
'@value',
58 'normalize-space(descendant-or-self::text())']
61 def find(self, locator, tag=None, first_only=True, required=True,
63 element_type =
'Element' if not tag
else tag.capitalize()
65 raise ValueError(
'Parent must be Selenium WebElement but it '
66 'was {}.'.format(type(parent)))
72 elements = strategy(criteria, tag, constraints,
74 if required
and not elements:
76 % (element_type, locator))
83 def register(self, strategy_name, strategy_keyword, persist=False):
86 raise RuntimeError(
"The custom locator '%s' cannot be registered. "
87 "A locator of that name already exists."
89 self.
_strategies_strategies[strategy.name] = strategy.find
92 events.on(
'scope_end',
'current', self.
unregisterunregister, strategy.name)
96 raise RuntimeError(
"Cannot unregister the default strategy '%s'."
98 if strategy_name
not in self.
_strategies_strategies:
99 raise RuntimeError(
"Cannot unregister the non-registered strategy '%s'."
105 return isinstance(element, WebElement)
109 raise ValueError(
'This method does not allow WebElement as parent')
112 elements = self.
_normalize_normalize(parent.find_elements_by_id(criteria)) \
113 + self.
_normalize_normalize(parent.find_elements_by_name(criteria))
117 return self.
_filter_elements_filter_elements(parent.find_elements_by_id(criteria),
121 return self.
_filter_elements_filter_elements(parent.find_elements_by_name(criteria),
125 return self.
_filter_elements_filter_elements(parent.find_elements_by_xpath(criteria),
130 result = self.
driverdriverdriver.execute_script(
"return %s;" % criteria)
133 if not isinstance(result, list):
139 js =
"return jQuery('%s').get();" % criteria.replace(
"'",
"\\'")
146 parent.find_elements_by_link_text(criteria),
151 parent.find_elements_by_partial_link_text(criteria),
156 parent.find_elements_by_css_selector(criteria),
161 parent.find_elements_by_class_name(criteria),
166 parent.find_elements_by_tag_name(criteria),
170 logger.warn(
'scLocator is deprecated.')
172 js =
"return isc.AutoTest.getElement('%s')" % criteria.replace(
"'",
"\\'")
182 xpath_tag = tag
if tag
is not None else '*'
184 xpath_searchers = [
"%s=%s" % (attr, xpath_criteria)
for attr
in key_attrs]
186 xpath =
"//%s[%s%s(%s)]" % (
188 ' and '.join(xpath_constraints),
189 ' and ' if xpath_constraints
else '',
190 ' or '.join(xpath_searchers)
192 return self.
_normalize_normalize(parent.find_elements_by_xpath(xpath))
196 for name, value
in constraints.items()]
197 return xpath_constraints
200 if isinstance(value, list):
201 return "@%s[. = '%s']" % (name,
"' or . = '".join(value))
203 return "@%s='%s'" % (name, value)
212 if tag ==
'partial link':
218 elif tag ==
'radio button':
220 constraints[
'type'] =
'radio'
221 elif tag ==
'checkbox':
223 constraints[
'type'] =
'checkbox'
224 elif tag ==
'text field':
226 constraints[
'type'] = [
'date',
'datetime-local',
'email',
'month',
227 'number',
'password',
'search',
'tel',
228 'text',
'time',
'url',
'week',
'file']
229 elif tag ==
'file upload':
231 constraints[
'type'] =
'file'
232 elif tag ==
'text area':
234 return tag, constraints
237 if locator.startswith((
'//',
'(//')):
238 return 'xpath', locator
241 prefix = locator[:index].strip()
243 return prefix, locator[index+1:].lstrip()
244 return 'default', locator
247 if '=' not in locator:
248 return locator.find(
':')
249 if ':' not in locator:
250 return locator.find(
'=')
251 return min(locator.find(
'='), locator.find(
':'))
254 if not element.tag_name.lower() == tag:
256 for name
in constraints:
257 if isinstance(constraints[name], list):
258 if element.get_attribute(name)
not in constraints[name]:
260 elif element.get_attribute(name) != constraints[name]:
265 elements = self.
_normalize_normalize(elements)
268 return [element
for element
in elements
275 for attr
in [
'@src',
'@href']:
276 if attr
in key_attrs:
277 if url
is None or xpath_url
is None:
280 attrs.append(
"%s=%s" % (attr, xpath_url))
286 url =
'/'.join(url.split(
'/')[:-1])
293 if not isinstance(elements, list):
294 logger.debug(
"WebDriver find returned %s" % elements)
def _get_locator_separator_index(self, locator)
def __init__(self, ctx)
Base class exposing attributes from the common context.
def _find_by_id(self, criteria, tag, constraints, parent)
def _disallow_webelement_parent(self, element)
def _is_webelement(self, element)
def _find_by_class_name(self, criteria, tag, constraints, parent)
def _find_by_xpath(self, criteria, tag, constraints, parent)
def _get_xpath_constraints(self, constraints)
def _parse_locator(self, locator)
def _filter_elements(self, elements, tag, constraints)
def find(self, locator, tag=None, first_only=True, required=True, parent=None)
def _element_matches(self, element, tag, constraints)
def _get_attrs_with_url(self, key_attrs, criteria)
def _find_by_name(self, criteria, tag, constraints, parent)
def register(self, strategy_name, strategy_keyword, persist=False)
def _find_by_default(self, criteria, tag, constraints, parent)
def _find_by_identifier(self, criteria, tag, constraints, parent)
def _find_by_dom(self, criteria, tag, constraints, parent)
def _get_tag_and_constraints(self, tag)
def _normalize(self, elements)
def _find_by_link_text(self, criteria, tag, constraints, parent)
def _get_xpath_constraint(self, name, value)
def _find_by_jquery_selector(self, criteria, tag, constraints, parent)
def _find_by_partial_link_text(self, criteria, tag, constraints, parent)
def _find_by_css_selector(self, criteria, tag, constraints, parent)
def unregister(self, strategy_name)
def _find_by_sc_locator(self, criteria, tag, constraints, parent)
def _find_by_tag_name(self, criteria, tag, constraints, parent)
def escape_xpath_value(value)