Reputation: 1452
My code is like as following, the code is to get the elements set via xpath, and generate a list<String>
with the texts of each element in the elements set. But it always throws exception during the process of adding each element's text to the new List<String>
.
protected List<String> getHeaders(String path){
List<String> headers = new ArrayList<String>();
int count = 0;
List<WebElement> elements = findAllByXpath(path);
LOG.info("The length is : " + String.valueOf(elements.size()));
for (WebElement c: elements) {
LOG.info("->> " + String.valueOf(count));
count++;
headers.add(c.getText());
}
return headers;
}
The result is:
INFO com.xxx.test - The length is: 13
INFO com.xxx.test ->> 0
INFO com.xxx.test ->> 1
INFO com.xxx.test ->> 2
INFO com.xxx.test ->> 3
INFO com.xxx.test ->> 4
INFO com.xxx.test ->> 5
com.xxx.test -> getHeaders FAILED org.openqa.selenium.StableElementReferenceException:Element not found in the cache - perhaps the page has changed since it was looked up
Can someone help in this case? Thanks!
Upvotes: 3
Views: 541
Reputation: 42528
I see 3 ways to handle your issue.
The first solution and probably the most reliable would be to find the elements once the page has reached a stable state. It could be done either by waiting for the presence of an element or by waiting for the count of elements.
A second solution would be to list again the elements when StableElementReferenceException is raised :
List<String> headers = new ArrayList<String>();
List<WebElement> elements = findAllByXpath(path);
for(int i = 0; i < elements.size(); ) {
try {
headers.add(elements.get(i).getText());
i++;
} catch (StableElementReferenceException ex) {
elements = findAllByXpath(path);
}
}
return headers;
And a third solution would be to get the text for all the elements with a piece of Javascript:
List<WebElement> elements = findAllByXpath(path);
ArrayList headers = (ArrayList)((JavascriptExecutor)driver).executeScript(
"var arr = [], elements = arguments[0];" +
"for(var i=0; i<elements.length; i++)" +
" arr.push(elements[i].textContent);" +
"return arr;", elements);
return headers;
Upvotes: 3
Reputation: 163
Try getAttribute("innerText") or getAttribute("value")
protected List<String> getHeaders(String path){
List<String> headers = new ArrayList<String>();
int count = 0;
List<WebElement> elements = findAllByXpath(path);
LOG.info("The length is : " + String.valueOf(elements.size()));
for (WebElement c: elements) {
LOG.info("->> " + String.valueOf(count));
count++;
headers.add(c.getAttribute("innerText"));
}
return headers;
}
Upvotes: 0
Reputation: 4683
Ok here's the trick.
1. Get size of the list of elements u want using elements.size();
2. Next write down a dynamic XPath such that only the indexes in the XPATH should change and that should give you the individual element.
3. Start a For Loop with i=0 to i < elements.size and in the for loop using the dynamic XPath with indexes retrieve individual elements one by one and then their text subsequently and add them to the List
Other Approach can be to explicitly wait till the page has loaded completely using WebDriverWait or other approaches of Waiting in selenium
Upvotes: 2