The best way for us to help you is to trim down the code to a bare
minimum and point it to a web site we can access. This is not always
possible. For example, the application I am currently testing is web
based but we deploy it internally and behind a firewall. So I trim the
code to a bare minimum and see if I can find another website which
exhibits the same problem. Often, as I'm doing this I find the problem
goes away. I then have to look at what is different from my
environment and the external website.
When something happens occasionally I know it is intermittent and
probably a timing issue. If it happens on IE but not Firefox (or vice
versa) then I'm pretty sure it is a timing problem. If for example you
have:
- get web element
- do something
- do another thing
- get text
- StaleElementReferenceException
I would change the code to:
- get web element
- print System.currentTimeMillis()
- do something
- do another thing
- print System.currentTimeMillis()
- get text
- StaleElementReferenceException
If I get the problem on IE but not Firefox I can look at the time
between the getting of the web element and the call to get text. If it
takes 1.2 second on Firefox and 2.1 seconds on IE I would suspect the
delay of 0.9 seconds is enough for the DOM to change and the web
element reference to go stale. If it wasn't my web code I'd talk to
the developers and see if there is something which alters the web
page. I can also see it in things like Chrome's inspect window. I have
one page which if I inspect an element using Chrome's built-in
equivalent to Friebug and leave it for a while, I can see the DOM
refresh in the inspect window.
I then need to either update the reference to the web element then use
it right away or talk to the developer and see if I can disable
whatever is refreshing the DOM.
If you post the actual code, even if we don't have access to the
website being tested (alter the URL and navigation code) we might be
able to point out ways to make the code more efficient.
Another possibly is you are causing the reference to go stale. For
example, you want to get all the anchors on a page, click them to make
sure they go to some valid page, i.e. not a 404 error. You might do
something like:
List<WebElement> anchors = driver.findElements(By.tagName("a"));
Iterator<WebElement> i = anchors.iterator();
while(i.hasNext()) {
WebElement a = i.next();
a.click();
// check for valid page
driver.navigate().back();
}
This will throw a StaleElementReferenceException. The moment you click
the first anchor all the other references become stale. So when you
navigate back and try clicking the second anchor it throws the
exception. You have to find some alternative solution, e.g.
List<WebElement> anchors = driver.findElements(By.tagName("a"));
int numAnchors = anchors.size();
for(int i = 1; i <= numAnchors; i++) {
WebElement a = driver.findElement(By.xpath("//a[" + i + "]");
a.click();
// check for valid page
driver.navigate().back();
}
The body of the loop is pretty much the same except I get each web
element as I need it.
Bottom line, you need to figure out what is changing the DOM
(javascript code, meta refresh, your code) and find some way to deal
with it. The most important thing to remember is if you give us what
you think is the equivalent code you are probably leaving out
something important. If you knew what you are leaving out, you
probably wouldn't need to post your question. That is what often
happens to me. In my attempt to create an equivalent code snippet I
realize what the real problem is (it is never what I thought it was).
Darrell