StaleElementException when using AjaxElementLocatorFactory

1,170 views
Skip to first unread message

mark

unread,
Aug 7, 2012, 3:40:01 PM8/7/12
to seleniu...@googlegroups.com
Hi,

I started using the PageFactory approach to my WebDriver testing as the application I'm testing against is pretty dynamic.
I thought that would eliminate the StaleElementExceptions scenario - is that an incorrect expectation?

I'm not sure what information would be useful to point me in the right direction?
I'm sure it will be something I've missed.

I have a base class which my test classes extend.

Here's an example Page Factory:-

public class DataPage {
   
    private WebDriver driver;
   
    @FindBy(id = "Header")
    private WebElement _pageTitle;

    public DataPage(WebDriver driver) {
        ElementLocatorFactory finder = new AjaxElementLocatorFactory(driver, 30);
        PageFactory.initElements(finder, this);
        this.driver = driver;
    }

    public String checkOnCorrectPage() {
        return _pageTitle.getText();
    }
}

Thanks,

Mark

Tarun Kumar

unread,
Aug 8, 2012, 1:28:23 AM8/8/12
to seleniu...@googlegroups.com
PageFactory does not eliminate StaleElementExceptions, PageFactory is a mechanism to encapsulate UI elements of page.


In long and short, you may have to find element again if dom is modified by your actions on page.

mark

unread,
Aug 8, 2012, 4:31:27 AM8/8/12
to seleniu...@googlegroups.com
Hi,
Thanks for the reply.

I think I may not have been clear enough in describing my issue?

I recognise the PageFactory captures the element just once, however, I thought the AjaxElementLocatorFactory (which I am using) retried until the timeout expires (in my case 30secs).

As as slight aside, in my example I showed use of an id to find the element whereas in reality the element I am having trouble with is an xpath - I don't know if that makes a difference.

Thanks,

Mark

Tarun Kumar

unread,
Aug 9, 2012, 1:47:40 AM8/9/12
to seleniu...@googlegroups.com
Hi Mark, Though I have never used AjaxElementLocatorFactory , its usage looks similar to implicit wait
That is, it would wait for given time out period before giving up on finding the element. But I might be wrong in my assumption.

Now consider that your UI object - _pageTitle has been found but by the time you use method - checkOnCorrectPage, some thing changes in dom and you lose the reference of element - _pageTitle
Hence you eventually end up with StaleElementExceptions. Looks like AjaxElementLocatorFactory will not do the job of finding this element again and you would have to induce some other mechanism to find it. Like - ExplicitWait -

WebDriverWait wait = new WebDriverWait(driver, 10);
WebElement element = wait.until(ExpectedConditions.elementToBeClickable(By.id("someid")));

I guess, these are the situations where page factory fails.

DongXiang

unread,
Aug 9, 2012, 4:51:53 AM8/9/12
to seleniu...@googlegroups.com
Hi
 
I use following codes to handle such exception, it is so common in dynamic page.
while (true) {
   try {
    locateUIElements(testStep, context, testStepMonitor,
      stepLocatesInfo);
    if(context.isNeedScreen()){
     LoadTestCaseExecutorHelper.getExecutorHelper().capatureScreen(context);
    }
    result = executeOperation(testStep, context);
    break;
   } catch (StaleElementReferenceException ex) {
    Thread.sleep(1000);
    System.out.println("StaleElementReferenceException error, sleep one seconds and re-execute operation");
    if (count > 5) {
     break;
    }
    count++;
   }
 
   I am not sure does WebDriver already provide a good solution for this issue. Sounds re-locate the elements is the recommend solution from Selenium.
 

Date: Wed, 8 Aug 2012 22:47:40 -0700
From: tku...@gmail.com
To: seleniu...@googlegroups.com
Subject: [selenium-users] Re: StaleElementException when using AjaxElementLocatorFactory
--
You received this message because you are subscribed to the Google Groups "Selenium Users" group.
To post to this group, send email to seleniu...@googlegroups.com.
To unsubscribe from this group, send email to selenium-user...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msg/selenium-users/-/eNYfG-d3YkgJ.
For more options, visit https://groups.google.com/groups/opt_out.
 
 

mark

unread,
Aug 9, 2012, 4:19:14 PM8/9/12
to seleniu...@googlegroups.com
Hi,

Thanks for the replies, I appreciate the time taken.

I was aware of the dynamic nature of the elements and had in the past written my own staleElementException handler.
My thinking was that using the already provided factory would do the job for me.

I can't seem to find a concrete example of usage on a really dynamic page.

Thanks again for your time and answers.

Mark

anemuday

unread,
Jul 26, 2016, 1:23:48 PM7/26/16
to Selenium Users, south...@gmail.com
Hi,

Can somebody tell me how to handle this?

We define our page objects with @FindBy annotation like:
@FindBy(name="foo")
WebElement fooElement;

Whenever i invoke this object "fooElement", which needs to try identify with above "name=foo", right?

Then why i will get StaleElementReferenceException?

How to overcome this?

I dont want to follow another approach again here(other than page factory) whenever i see StaleElement like:
WebElement fooElement=driver.findElement(By.name("foo"))

Can somebody help me on this?

Thanks,
Uday
Message has been deleted

anemuday

unread,
Sep 1, 2016, 11:32:00 AM9/1/16
to Selenium Users, south...@gmail.com
Can somebody help me to find the right pointers?

How can i overcome StaleElementException when using with PageFactory?

Thanks,
Uday

Krishnan Mahadevan

unread,
Sep 1, 2016, 11:37:37 AM9/1/16
to Selenium Users

Please feel free to add more context.

What does your code look like ?
What does your html look like ?
Browser flavor and version ?
Complete stack trace ?

Thanks & Regards
Krishnan Mahadevan

"All the desirable things in life are either illegal, expensive, fattening or in love with someone else!"
My Scribblings @ http://wakened-cognition.blogspot.com/

My Technical Scribbings @ http://rationaleemotions.wordpress.com/




To unsubscribe from this group and stop receiving emails from it, send an email to selenium-user...@googlegroups.com.

To post to this group, send email to seleniu...@googlegroups.com.

anemuday

unread,
Sep 1, 2016, 1:08:48 PM9/1/16
to Selenium Users
Krishnan,

This is a general discussion which happened with my colleague.

He told me that, he has seen StaleElementException when he used PageFactory. He dont know how to over come that. Does it happen is my question?

As per your question, this(StaleElement) could happen in any browser or any application.

I suggested him a work around to capture StaleElement in try catch block, and re-identify with normal approach like driver.findElement().

Then i ask myself how to handle that also with pageFactory, should i be using two different approaches(PageFactory and another one is findElement)? Is there any other way.

In a similar way, how can i pass dynamic value to a element in PageFactory?
@FindBy("xpath=//[text(),'"+somevar+"']")
WebElement ele;

Thanks,
Uday

⇜Krishnan Mahadevan⇝

unread,
Sep 2, 2016, 2:19:21 PM9/2/16
to Selenium Users
Uday,

To the best of my knowledge if you make use of the AjaxElementLocatorFactory
PageFactory.initElements(new AjaxElementLocatorFactory(driver, 10), myPage);
then you shouldn't see any StaleElementReferenceException because every invocation of findElement() gets proxied such that it would be queried with enough delay.

But you may still get this if you decorate your WebElement with the @org.openqa.selenium.support.CacheLookup annotation because this will cause the PageFactory implementation to not bother about querying the DOM everytime a web element is accessed but instead return back what was already cached (it gets cached after the first time it is queried on the DOM).

For the second question viz., How do I make my locator dynamic when using the @FindsBy annotation, here's one way of doing it (THIS IS JUST A THEORY AND I DON'T KNOW IF THIS THEORY WILL WORK).

You first define your element as below :

@FindBy(using = "xpath=//[text(), '${replaceMe}']")
private WebElement foo;
Here as you can see, you are only defining place holders for your web element.

You now go forward and instantiate your Page Class's object.
You then follow the approach defined in this blog post of mine to replace the placeholder with an actual value of your annotation.
You now invoke PageFactory.initElements() with the object of your page class that you instantiated.

If at any point in time you again want to change the place holder with a different value, you would need to change the annotation value and again invoke initElements() once again.

All said and done, I think its not the right way of using PageFactory annotations.

If you have an element whose locator is dynamic, then you should explicitly write code to find that element and then interact with it.

That way your code is less complex and easier to maintain.

Annotations were created in Java to be read only representations of meta data at runtime and which can be set only when you are writing the code. 

Also leveraging on reflection a lot [ PageFactory already resorts to reflection] kind of slows down things.

Thanks & Regards
Krishnan Mahadevan

"All the desirable things in life are either illegal, expensive, fattening or in love with someone else!"
My Scribblings @ http://wakened-cognition.blogspot.com/
My Technical Scribbings @ http://rationaleemotions.wordpress.com/

To unsubscribe from this group and stop receiving emails from it, send an email to selenium-users+unsubscribe@googlegroups.com.
To post to this group, send email to selenium-users@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/selenium-users/a2490677-7cdd-4e90-89c0-fac7101ae8f9%40googlegroups.com.
Reply all
Reply to author
Forward
0 new messages