StaleElementReferenceException: Element not found in the cache

969 views
Skip to first unread message

SeleniuMaddog

unread,
Apr 14, 2011, 1:35:35 AM4/14/11
to webdriver
Hi,

I recently started using selenium-webdriver (dot net driver), it is
really a great tool and I'd like to extend my deepest admiration to
everyone involved in this awesome project.

I'm using the firefox driver to test our application.
I'm getting a stale element reference exception when I try to switch
to a frame inside another frame.

The application I'm testing uses an intricate iframe system to
communicate with the server, I'm getting
this exception while querying attributes of a child iframe (iframe
within an iframe) or when switching context to an iframe.

I went through hell and back and then found this way to properly drill
into iframes:

var oldContext = Browser.GetWindowHandle();

Browser.SwitchTo().Window(oldContext).SwitchTo().Frame(frameElem);

Switching context "through the main window" works maybe 95% of the
times, sometimes, out of the blue, usually
when I try to drill down into the iframe (if there's an iframe inside
the iframe), I get the stale element reference exception.

Note that in order to drill down into iframes, I'm *recursively*
switching context to an iframe and then process the inner iframes.

After each internal run, the recursive function restores the context
back before it starts processing the next iframe (like with the
oldContext example above), I found this to be necessary to get the
"src" of the next iframe in the iteration, but again - sometimes it
just fails.

It's really weird because there's seemingly no difference between the
failing iframes and the other ones (from what I was able to witness in
firebug).

I tried processing the iframes in javascript to avoid this exception
(I find them with browser.findElements, but process them with
executeScript - didn't work either, I got the same exception)

Any ideas on how approach this issue? It is possible that one of the
javascripts is doing /something/ to the iframe while I'm running my
test, but this recursive function usually runs within a second or two
- the chance of the iframe being modified in the DOM from the time I'm
finding it and until I reach it with my function is minimal.

Maybe it happens if it's not completely loaded or if the document is
not closed yet?

Thank you

QA_manager

unread,
Apr 18, 2011, 10:36:59 AM4/18/11
to webdriver
Good report with lots of details; thank you. Please add some
additional information:
- what OS (and version) are you using?
- which version of Webdriver?
- which version of Firefox?

Can you try this with the htmlunit driver or the IE driver and tell us
whether you see the same problem?

Can you give us a URL where the developers can run your test and
reproduce the problem?

SeleniuMaddog

unread,
Apr 18, 2011, 11:12:41 AM4/18/11
to webdriver
Hi, Thank you for your answer.

The OS is Windows 7 Ultimate x64 - fully patched. Firefox is 3.6.16.
WebDriver - the latest binary (2.0b3) - I tried to compile the master
with the batch build tools but it didn't work (I didn't have time to
investigate that yet)

Testing with HTMLUnit is only possible via the old selenium, right?
I'll try with IE, seems easier.

Unfortunately - no URL, I'll try to find a public website where my
code exhibits the same problem.

Is there anything I can try to pinpoint the problem myself? Does the
server (FF-plugin) has logging of some sort?

Thank you

SeleniuMaddog

unread,
Apr 18, 2011, 3:40:16 PM4/18/11
to webdriver
I tried to find a site with iframe ads and the second site I tried had
like 40 iframes in it.
In this site: http://www.failblog.org/

I get a stale element reference exception on this page while drilling
into the iframes.

Still working on getting the entire thing to work in IE.

Thanks

Jim Evans

unread,
Apr 18, 2011, 4:00:04 PM4/18/11
to webdriver
Since you've gone to the trouble of finding a site that exhibits the
failing behavior you describe, would you consider posting some code
that fails?

By the way, switching back to the main window context should be
accomplished by driver.SwitchTo().DefaultContent(), rather than
driver.SwitchTo().Window().
> > > > Thank you- Hide quoted text -
>
> - Show quoted text -

SeleniuMaddog

unread,
Apr 18, 2011, 5:24:13 PM4/18/11
to webdriver
Hi Jim,

I'm working on extracting the important bits, I'll post the code soon.

The documentation of SwitchTo().DefaultContent() scared me out of
using it, it says first window or first frame, I was afraid I'd end up
somewhere inside an iframe or a frameset child.

Thank you

SeleniuMaddog

unread,
Apr 19, 2011, 11:46:55 AM4/19/11
to webdriver
Ok, so here's the code.. on the http://failblog.org/ page I get 42
successes and 6 failures.

using System;
using System.Drawing.Imaging;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using OpenQA.Selenium.Firefox;
using OpenQA.Selenium;

namespace ConsoleApplication2
{
class Program
{
public static int failures = 0;
public static int successes = 0;
static void Main(string[] args)
{
var profile = new FirefoxProfile();
var browser = new FirefoxDriver(profile);
browser.Navigate().GoToUrl("http://www.failblog.org/");

var dictionary = BuildIframeTree(browser, null);
var maddog = 0;
}
public static Dictionary<string, object>
BuildIframeTree(FirefoxDriver browser, IWebElement startElem)
{
var dict = new Dictionary<string, object>();
if (startElem != null)
{
dict["src"] = startElem.GetAttribute("src");
browser.SwitchTo().Frame(startElem);
}

var iframes = browser.FindElements(By.TagName("IFRAME"));
if (iframes.Count > 0)
{
var childrenDoc = new List<Dictionary<string,
object>>();

foreach (var ifr in iframes)
{
Dictionary<string, object> ifrDoc = null;

try
{
ifrDoc = BuildIframeTree(browser, ifr);
successes++;
}
catch (Exception e)
{
failures++;
}
finally
{
if (ifrDoc != null)
childrenDoc.Add(ifrDoc);

if (startElem != null)
{

browser.SwitchTo().DefaultContent().SwitchTo().Frame(startElem);
}
else
{
browser.SwitchTo().DefaultContent();
}
}
}
dict["children"] = childrenDoc;
}
return dict;

SeleniuMaddog

unread,
Apr 19, 2011, 7:44:16 PM4/19/11
to webdriver
Yeah, System.Drawing should not be there..

Anyway, I tried to play around with the context changing (like
changing "through" the main context), the above code produces the
least amount of stale element exceptions on that page.

On Apr 19, 11:46 am, SeleniuMaddog <madd0g.co...@gmail.com> wrote:
> Ok, so here's the code.. on thehttp://failblog.org/page I get 42

SeleniuMaddog

unread,
Apr 27, 2011, 1:58:31 PM4/27/11
to webdriver
bump?

On Apr 19, 7:44 pm, SeleniuMaddog <madd0g.co...@gmail.com> wrote:
> Yeah, System.Drawing should not be there..
>
> Anyway, I tried to play around with the context changing (like
> changing "through" the main context), the above code produces the
> least amount of stale element exceptions on that page.
>
> On Apr 19, 11:46 am, SeleniuMaddog <madd0g.co...@gmail.com> wrote:
>
> > Ok, so here's the code.. on thehttp://failblog.org/pageI get 42

Jim Evans

unread,
Apr 27, 2011, 5:28:13 PM4/27/11
to webdriver
I believe the below code will get you where you want to go. I've added
appropriate comments for the clever (read: hacky) bits. Note that I've
removed the exception handling; I haven't seen any exceptions using
this method, but that's not to say there might not be some conditions
that would cause them.

Regards,
--Jim

namespace ConsoleApplication2
{
class Program
{
private static List<IWebElement> framePath = new
List<IWebElement>();
static void Main(string[] args)
{
var driver = new FirefoxDriver();
driver.Navigate().GoToUrl("http://www.failblog.org/");

driver.SwitchTo().DefaultContent();
var dictionary = BuildIframeTree(driver);
}

public static Dictionary<string, object>
BuildIframeTree(IWebDriver browser)
{
Dictionary<string, object> dict = new Dictionary<string,
object>();
ReadOnlyCollection<IWebElement> frameElements =
browser.FindElements(By.TagName("iframe"));
if (frameElements.Count > 0)
{
var childrenDoc = new List<Dictionary<string,
object>>();
foreach (var ifr in frameElements)
{
// We have to start at the root of the document.
WebDriver
// has no mechanism for walking up the frame tree.
driver.SwitchTo().DefaultContent();
foreach (IWebElement frame in framePath)
{
driver.SwitchTo().Frame(frame);
}

string frameSrc = ifr.GetAttribute("src");

// Switch to the frame and add it to the frame
path so
// that when we recurse, we will switch to the
correct
// sequence of frames.
driver.SwitchTo().Frame(ifr);
framePath.Add(ifr);

// Recursion! Yay!
Dictionary<string, object> ifrDoc =
BuildIframeTree(browser);
ifrDoc["src"] = frameSrc;
if (ifrDoc != null)
{
childrenDoc.Add(ifrDoc);
}

// Remove the current child from the frame path so
we
// don't try to switch to it again.
framePath.Remove(ifr);
}

dict["children"] = childrenDoc;
}

return dict;
}
}
}


On Apr 19, 11:46 am, SeleniuMaddog <madd0g.co...@gmail.com> wrote:
> Ok, so here's the code.. on thehttp://failblog.org/page I get 42
> > > > - Show quoted text -- Hide quoted text -

SeleniuMaddog

unread,
Apr 28, 2011, 12:42:37 AM4/28/11
to webdriver
Thanks a lot for taking the time Jim, I'll test this and report the
results.

I think I understand the problem (I need to switch /through/ all the
iframes in the tree on each iteration). It is pretty similar to what I
was thinking when I added the switching to the main context before
switching to the iframe (it did solve almost all occurrences of this
problem, this code went successfully 4-5 levels deep on this site, so
it's not like it always failed on the second iteration or something.

Ahhh.. so it must have failed the second internal iframe... that's why
it was so rare. It rarely happens.

I guess it was stupid of me to pass the iframe element around if it
was just a matter of context, hehe, this code evolved along with my
understanding of webdriver (I'm really new at this).

Thank you
> > Ok, so here's the code.. on thehttp://failblog.org/pageI get 42
> ...
>
> read more »

SeleniuMaddog

unread,
Apr 30, 2011, 5:32:47 PM4/30/11
to webdriver
Thank you Jim, looks like this does solve my problem, I don't see any
stale element reference exceptions :)
> > > Ok, so here's the code.. on thehttp://failblog.org/pageIget 42
> ...
>
> read more »
Reply all
Reply to author
Forward
0 new messages