<s> from AppiumLibrary import utils <EOL> from robot . api import logger <EOL> class ElementFinder ( object ) : <EOL> def __init__ ( self ) : <EOL> self . _strategies = { <EOL> '<STR_LIT>' : self . _find_by_identifier , <EOL> '<STR_LIT:id>' : self . _find_by_id , <EOL> '<STR_LIT:name>' : self . _find_by_name , <EOL> '<STR_LIT>' : self . _find_by_xpath , <EOL> '<STR_LIT:class>' : self . _find_by_class_name , <EOL> '<STR_LIT>' : self . _find_element_by_accessibility_id , <EOL> '<STR_LIT>' : self . _find_by_android , <EOL> '<STR_LIT>' : self . _find_by_ios , <EOL> '<STR_LIT>' : self . _find_by_css_selector , <EOL> None : self . _find_by_default <EOL> } <EOL> def find ( self , browser , locator , tag = None ) : <EOL> assert browser is not None <EOL> assert locator is not None and len ( locator ) > <NUM_LIT:0> <EOL> ( prefix , criteria ) = self . _parse_locator ( locator ) <EOL> strategy = self . _strategies . get ( prefix ) <EOL> if strategy is None : <EOL> raise ValueError ( "<STR_LIT>" + prefix + "<STR_LIT>" ) <EOL> ( tag , constraints ) = self . _get_tag_and_constraints ( tag ) <EOL> return strategy ( browser , criteria , tag , constraints ) <EOL> def _find_by_identifier ( self , browser , criteria , tag , constraints ) : <EOL> elements = self . _normalize_result ( browser . find_elements_by_id ( criteria ) ) <EOL> elements . extend ( self . _normalize_result ( browser . find_elements_by_name ( criteria ) ) ) <EOL> return self . _filter_elements ( elements , tag , constraints ) <EOL> def _find_by_id ( self , browser , criteria , tag , constraints ) : <EOL> return self . _filter_elements ( <EOL> browser . find_elements_by_id ( criteria ) , <EOL> tag , constraints ) <EOL> def _find_by_name ( self , browser , criteria , tag , constraints ) : <EOL> return self . _filter_elements ( <EOL> browser . find_elements_by_name ( criteria ) , <EOL> tag , constraints ) <EOL> def _find_by_xpath ( self , browser , criteria , tag , constraints ) : <EOL> return self . _filter_elements ( <EOL> browser . find_elements_by_xpath ( criteria ) , <EOL> tag , constraints ) <EOL> def _find_by_dom ( self , browser , criteria , tag , constraints ) : <EOL> result = browser . execute_script ( "<STR_LIT>" % criteria ) <EOL> if result is None : <EOL> return [ ] <EOL> if not isinstance ( result , list ) : <EOL> result = [ result ] <EOL> return self . _filter_elements ( result , tag , constraints ) <EOL> def _find_by_sizzle_selector ( self , browser , criteria , tag , constraints ) : <EOL> js = "<STR_LIT>" % criteria . replace ( "<STR_LIT:'>" , "<STR_LIT>" ) <EOL> return self . _filter_elements ( <EOL> browser . execute_script ( js ) , <EOL> tag , constraints ) <EOL> def _find_by_link_text ( self , browser , criteria , tag , constraints ) : <EOL> return self . _filter_elements ( <EOL> browser . find_elements_by_link_text ( criteria ) , <EOL> tag , constraints ) <EOL> def _find_by_css_selector ( self , browser , criteria , tag , constraints ) : <EOL> return self . _filter_elements ( <EOL> browser . find_elements_by_css_selector ( criteria ) , <EOL> tag , constraints ) <EOL> def _find_by_tag_name ( self , browser , criteria , tag , constraints ) : <EOL> return self . _filter_elements ( <EOL> browser . find_elements_by_tag_name ( criteria ) , <EOL> tag , constraints ) <EOL> def _find_by_class_name ( self , browser , criteria , tag , constraints ) : <EOL> return self . _filter_elements ( <EOL> browser . find_elements_by_class_name ( criteria ) , <EOL> tag , constraints ) <EOL> def _find_element_by_accessibility_id ( self , browser , criteria , tag , constraints ) : <EOL> elements = browser . find_elements_by_accessibility_id ( criteria ) <EOL> return elements <EOL> def _find_by_android ( self , browser , criteria , tag , constraints ) : <EOL> """<STR_LIT>""" <EOL> return self . _filter_elements ( <EOL> browser . find_elements_by_android_uiautomator ( criteria ) , <EOL> tag , constraints ) <EOL> def _find_by_ios ( self , browser , criteria , tag , constraints ) : <EOL> """<STR_LIT>""" <EOL> return self . _filter_elements ( <EOL> browser . find_elements_by_ios_uiautomation ( criteria ) , <EOL> tag , constraints ) <EOL> def _find_by_default ( self , browser , criteria , tag , constraints ) : <EOL> if criteria . startswith ( '<STR_LIT>' ) : <EOL> return self . _find_by_xpath ( browser , criteria , tag , constraints ) <EOL> return self . _find_by_key_attrs ( browser , criteria , tag , constraints ) <EOL> def _find_by_key_attrs ( self , browser , criteria , tag , constraints ) : <EOL> key_attrs = self . _key_attrs . get ( None ) <EOL> if tag is not None : <EOL> key_attrs = self . _key_attrs . get ( tag , key_attrs ) <EOL> xpath_criteria = utils . escape_xpath_value ( criteria ) <EOL> xpath_tag = tag if tag is not None else '<STR_LIT:*>' <EOL> xpath_constraints = [ "<STR_LIT>" % ( name , constraints [ name ] ) for name in constraints ] <EOL> xpath_searchers = [ "<STR_LIT>" % ( attr , xpath_criteria ) for attr in key_attrs ] <EOL> xpath_searchers . extend ( <EOL> self . _get_attrs_with_url ( key_attrs , criteria , browser ) ) <EOL> xpath = "<STR_LIT>" % ( <EOL> xpath_tag , <EOL> '<STR_LIT>' . join ( xpath_constraints ) + '<STR_LIT>' if len ( xpath_constraints ) > <NUM_LIT:0> else '<STR_LIT>' , <EOL> '<STR_LIT>' . join ( xpath_searchers ) ) <EOL> return self . _normalize_result ( browser . find_elements_by_xpath ( xpath ) ) <EOL> _key_attrs = { <EOL> None : [ '<STR_LIT>' , '<STR_LIT>' ] , <EOL> '<STR_LIT:a>' : [ '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' ] , <EOL> '<STR_LIT>' : [ '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' ] , <EOL> '<STR_LIT:input>' : [ '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' ] , <EOL> '<STR_LIT>' : [ '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' ] <EOL> } <EOL> def _get_tag_and_constraints ( self , tag ) : <EOL> if tag is None : <EOL> return None , { } <EOL> tag = tag . lower ( ) <EOL> constraints = { } <EOL> if tag == '<STR_LIT>' : <EOL> tag = '<STR_LIT:a>' <EOL> elif tag == '<STR_LIT:image>' : <EOL> tag = '<STR_LIT>' <EOL> elif tag == '<STR_LIT:list>' : <EOL> tag = '<STR_LIT>' <EOL> elif tag == '<STR_LIT>' : <EOL> tag = '<STR_LIT:input>' <EOL> constraints [ '<STR_LIT:type>' ] = '<STR_LIT>' <EOL> elif tag == '<STR_LIT>' : <EOL> tag = '<STR_LIT:input>' <EOL> constraints [ '<STR_LIT:type>' ] = '<STR_LIT>' <EOL> elif tag == '<STR_LIT>' : <EOL> tag = '<STR_LIT:input>' <EOL> constraints [ '<STR_LIT:type>' ] = '<STR_LIT:text>' <EOL> elif tag == '<STR_LIT>' : <EOL> tag = '<STR_LIT:input>' <EOL> constraints [ '<STR_LIT:type>' ] = '<STR_LIT:file>' <EOL> return tag , constraints <EOL> def _element_matches ( self , element , tag , constraints ) : <EOL> if not element . tag_name . lower ( ) == tag : <EOL> return False <EOL> for name in constraints : <EOL> if not element . get_attribute ( name ) == constraints [ name ] : <EOL> return False <EOL> return True <EOL> def _filter_elements ( self , elements , tag , constraints ) : <EOL> elements = self . _normalize_result ( elements ) <EOL> if tag is None : <EOL> return elements <EOL> return filter ( <EOL> lambda element : self . _element_matches ( element , tag , constraints ) , <EOL> elements ) <EOL> def _get_attrs_with_url ( self , key_attrs , criteria , browser ) : <EOL> attrs = [ ] <EOL> url = None <EOL> xpath_url = None <EOL> for attr in [ '<STR_LIT>' , '<STR_LIT>' ] : <EOL> if attr in key_attrs : <EOL> if url is None or xpath_url is None : <EOL> url = self . _get_base_url ( browser ) + "<STR_LIT:/>" + criteria <EOL> xpath_url = utils . escape_xpath_value ( url ) <EOL> attrs . append ( "<STR_LIT>" % ( attr , xpath_url ) ) <EOL> return attrs <EOL> def _get_base_url ( self , browser ) : <EOL> url = browser . get_current_url ( ) <EOL> if '<STR_LIT:/>' in url : <EOL> url = '<STR_LIT:/>' . join ( url . split ( '<STR_LIT:/>' ) [ : - <NUM_LIT:1> ] ) <EOL> return url <EOL> def _parse_locator ( self , locator ) : <EOL> prefix = None <EOL> criteria = locator <EOL> if not locator . startswith ( '<STR_LIT>' ) : <EOL> locator_parts = locator . partition ( '<STR_LIT:=>' ) <EOL> if len ( locator_parts [ <NUM_LIT:1> ] ) > <NUM_LIT:0> : <EOL> prefix = locator_parts [ <NUM_LIT:0> ] . strip ( ) . lower ( ) <EOL> criteria = locator_parts [ <NUM_LIT:2> ] . strip ( ) <EOL> return ( prefix , criteria ) <EOL> def _normalize_result ( self , elements ) : <EOL> if not isinstance ( elements , list ) : <EOL> logger . debug ( "<STR_LIT>" % elements ) <EOL> return [ ] <EOL> return elements </s>
