How to get All Text in robot framework ?
Solution 1
You could iterate over the elements as below:
${xpath}= Set Variable //div[@id='groupContainer']//li[@class='contactNameItemContainer']//span
${count}= Get Matching Xpath Count ${xpath}
${names}= Create List
:FOR ${i} IN RANGE 1 ${count} + 1
\ ${name}= Get Text xpath=(${xpath})[${i}]
\ Append To List ${names} ${name}
This works but is rather slow when there are many matches.
Solution 2
You could extend Selenium2Library
and write your own keyword for this purpose. Save the following as Selenium2LibraryExt.py
from Selenium2Library import Selenium2Library
class Selenium2LibraryExt(Selenium2Library):
def get_all_texts(self, locator):
"""Returns the text value of elements identified by `locator`.
See `introduction` for details about locating elements.
"""
return self._get_all_texts(locator)
def _get_all_texts(self, locator):
elements = self._element_find(locator, False, True)
texts = []
for element in elements:
if element is not None:
texts.append(element.text)
return texts if texts else None
Then you can use your new Get All Texts
keyword in your tests like this:
*** Settings ***
library Selenium2LibraryExt
*** Test Cases ***
Get All Texts Test
Open Browser http://www.example.com chrome
@{texts} Get All Texts css=.name
Log Many ${texts}
Solution 3
Though the top-rated answer is fully working - and the most xpath-ish :), let me add an option I don't see proposed yet - using the Get Webelements
keyword. E.g.:
@{locators}= Get Webelements xpath=//div[@id='groupContainer']//li[@class='contactNameItemContainer']//span
${result}= Create List
:FOR ${locator} in @{locators}
\ ${name}= Get Text ${locator}
\ Append To List ${result} ${name}
It'll generate and return a list of all matching elements, on which you just iterate on. It might be a tad faster than xpath's [index]
reference because the dom is evaluated once - but don't hold me accountable if that's not fully true :)
Solution 4
@Velapanur
I had another similar requirement where in i have to enter the texts into textareas in a page. The below i wrote with the idea in reference to what Todor had suggested, and it worked. Many thanks to Todor, Velapanur
@{Texts}= Get WebElements ${AllTextboxes}
:FOR ${EachTextarea} in @{Texts}
\ Input Text ${EachTextarea} ${RandomTextdata}
Solution 5
Get Text will return content of the first element that matches the locator. When using XPATH you can specify the index of the element you want to get, like this:
${name1} Get Text xpath=//div[@id='groupContainer']//li[@class='contactNameItemContainer'][0]//span
${name2} Get Text xpath=//div[@id='groupContainer']//li[@class='contactNameItemContainer'][1]//span
@{names} Create List ${name1} ${name2}
Comments
-
velapanur over 3 years
Consider the following source code,
<div id="groupContainer" class="XXXXXX"> <ul id="GroupContactListWrapper" class="list-wrapper"> <li class="contactNameItemContainer"> <div class="contactNameItem"> <span class="name">Name1</span> </div> </li> <li class="contactNameItemContainer"> <div class="contactNameItem"> <span class="name">Name2</span> </div> </li> </ul> </div>
How do i retreive the two names (Name1,Name2) in a list variable ? I tried the following xpath for a "Get Text" keyword, but only returns the first one.
//div[@id='groupContainer']//li[@class='contactNameItemContainer']//span
Please suggest
-
velapanur almost 10 yearsThis would work for the above case, but i was looking for a more generic one where there could be more than 2 inner LI containers
-
velapanur almost 10 yearsThanks but was looking for the equivalent in Robot Framework.
-
velapanur almost 10 yearsThanks I already know the logic, just wanted a robot framework implementation.
-
Yu Zhang over 8 yearsCan I please ask why you used "${name}" as the list name instead of "@{name}"?
-
Yu Zhang over 8 yearsI think there is a typo, xpath=(${xpath})[${i}] should have been xpath=(${xpath})
-
Jcyrss almost 7 yearsThat's why I think RF sucks when a test case is a little complex. It creates a new language, but make it more complecated and way less powerful than python. Why doesn't It just let us just use python, and RF, as a framework, just provides functions like machanism of setup, teardown, control test cases scripts running, generator report. That's enough and good. Now it does more but does bad. Keyword development sucks.