How to get all matching elements without scrolling using robot framework and python?

Viewed 2572

I need to get ALL elements matching an xpath to list without need of scrolling to all the elements, because I can never know whether scrolling is really needed (depends on monitor resolution and the width of columns can be also changed by devs) and I would not know where to scroll, because I am checking the existence of the columns and in some cases the correct result is also that the column is not there...

I use these functions in the test to get the list of column headers:

Get all columns of table ${table}
    ${columns_loc}=  replace substring placeholder ${GRID_HEADERS}  ${table}
    @{locators}=   Get Webelements    ${columns_loc}
    ${result}=       Create List
    :FOR   ${locator}   in    @{locators}
    \       ${name}=    Get Text    ${locator}
    \       Append To List  ${result}  ${name}
    [Return]   ${result}

Check column ${column} is visible
   ${headers2}=  Get all values
   ${res}=  value is in list   ${headers2}   ${column}
   run keyword if    ${res}==False  fail  wrong columns displayed
...                  else  pass execution

I also tried to use this:

def dict_elements(self, xpath):
    elements = self.get_library_instance()._element_find(xpath, False, True)
    headers_map = {}
    if elements is not None:
        for index, element in enumerate(elements):
            headers_map[element.text] = index
        return headers_map
    return None

def list_elements(self, xpath):
    dict = self.dict_elements(xpath)
    return dictionary_keys_to_list(dict)

Get all columns of table ${table}
    ${columns_loc}=  replace substring placeholder ${GRID_HEADERS}  ${table}
    @{cols}=  list elements  ${columns_loc}

But both variants return 9 columns - which is correct, there is really 9 columns, but the last one is EMPTY (returned just u'') instead of actual text of the element (like u'last column name'). This last column header is not visible directly, it must be horizontally scrolled to get to it... The table is dynamically generated by angular.

Thanks for any advice!

2 Answers

You can use Get Matching Xpath Count Refer to the Get Matching Xpath Count keyword in the documentation for more info.

If the app really needs an element to be visualized in the browser's viewport to fill in it's textual value, there's a "trick" working for me to do just that - to use the Selenium2Library keyword Mouse Over.

Calling it physically scrolls the page in the browser so the element is visible; I've tried the other usual solutions - calculating the absolute/relative positions of the element and calling js scrollTo(), etc., but they were unreliable - working on some elements, not for others, different browser behavior, and so in. Mouse Over surprisingly (for me at least :) just works.

So in your code sample:

:FOR   ${locator}   in    @{locators}
\       Mouse Over  ${locator}
\       ${name}=    Get Text    ${locator}
\       Append To List  ${result}  ${name}

Hope this'll help.


By the way, your question is very context specific, in general please include/link some screenshots, html source, the source of relevant keywords (value is in list - is this the same as the built-in Should Contain?) - so we can understand the issue better. My 2 ç. ;)

Related