clear reference cache

690 views
Skip to first unread message

Danny Guerrier

unread,
Jan 8, 2010, 10:40:34 AM1/8/10
to webd...@googlegroups.com
It appears that webdriver is caching references to elements.
I have a button in my application which can use the same xpath while navigating and it fails when I attempt the click a second button using the same xpath.  Is there a way to clear all element references?  I am also using webdriver backed selenium driver so I would like to know if there's a way to do this using this as well as a standard webdriver. 

Thanks

Daniel Wagner-Hall

unread,
Jan 8, 2010, 11:14:30 AM1/8/10
to webd...@googlegroups.com
What xpath are you executing? If you're replacing the element in the
page with a new one and getting that, you should be able to get it.
If there are multiple elements with the same xpath, then you should
findElements rather than findElement, which will return a list of all
elements, which you can iterate through as you please.

> --
> You received this message because you are subscribed to the Google Groups
> "webdriver" group.
> To post to this group, send email to webd...@googlegroups.com.
> To unsubscribe from this group, send email to
> webdriver+...@googlegroups.com.
> For more options, visit this group at
> http://groups.google.com/group/webdriver?hl=en.
>
>

Danny Guerrier

unread,
Jan 8, 2010, 11:22:27 AM1/8/10
to webd...@googlegroups.com
Here's what is going on.  Using a webdriver backed selenium driver.
I have a wizard that is used to register something
Page 1 has a button titled Register which I find and click with this.
selenium.click("xpath=//button[contains(text(),'Register')]");

Page 2 has some imput fields and a next button
Page 3 Has a confirmation page with another Register button which I again click, or try to with:
selenium.click("xpath=//button[contains(text(),'Register')]");

This is where it fails with this exception:
org.openqa.selenium.ElementNotVisibleException: You may not click an element that is not displayed System info: os.name: 'Windows XP', os.arch: 'x86', os.version: '5.1', java.version: '1.6.0_10' Driver info: driver.version: ie

There are two other buttons on Page 3 that I am able to click using that same path with the text change for the respective button. i.e Cancel and Back

Daniel Wagner-Hall

unread,
Jan 8, 2010, 11:33:00 AM1/8/10
to webd...@googlegroups.com
Would it be possible to assign each button a unique ID, and get the ID
rather than click the element, just to make sure that it is looking at
the old element, rather than something else going on?

Danny Guerrier

unread,
Jan 8, 2010, 11:55:06 AM1/8/10
to webd...@googlegroups.com
That is unfortunately not possible.  I am not in control of the web application code in anyway.

Jason Leyba

unread,
Jan 8, 2010, 12:52:21 PM1/8/10
to webd...@googlegroups.com
On Fri, Jan 8, 2010 at 8:22 AM, Danny Guerrier <dgue...@gmail.com> wrote:
> Here's what is going on.  Using a webdriver backed selenium driver.
> I have a wizard that is used to register something
> Page 1 has a button titled Register which I find and click with this.
> selenium.click("xpath=//button[contains(text(),'Register')]");
>
> Page 2 has some imput fields and a next button
> Page 3 Has a confirmation page with another Register button which I again
> click, or try to with:
> selenium.click("xpath=//button[contains(text(),'Register')]");
> This is where it fails with this exception:
> org.openqa.selenium.ElementNotVisibleException: You may not click an element
> that is not displayed System info: os.name: 'Windows XP', os.arch: 'x86',
> os.version: '5.1', java.version: '1.6.0_10' Driver info: driver.version: ie

1) In order to click on an element, it must not be hidden by CSS
(style.display != 'none' && style.visibility != 'hidden'), and it must
have width and height. This is a key difference from the Selenium 1.0
API - if the user can't interact with the element, WebDriver won't let
you either.

2) When you search for an element on the page by XPath, WebDriver
should return the first match. So this begs the question, are page 1-3
truly separate pages, or is it just one page that dynamically changes
the visibility of various forms as the user moves through the wizard?
If it's the latter, WebDriver could be picking up a "Register" button
specified earlier in the DOM, which is not visible.

3) WebDriver does not cache the results of element searches - it will
re-execute the search each time you send the command. What we do cache
is an internal ID assigned to each element found after a search. This
ID is used when you act upon the element:

// Find element and store its internal ID in a WebElement object
WebElement element =
driver.findElement(By.xpath("//button[contains(text(),'Register')]"));
// Click command sends internal ID for quick element retrieval
element.click();
// Still not searching again, just sending same internal ID
element.click();
// Search for the element again. Create and return a new ID for the result:
element = driver.findElement(By.xpath("//button[contains(text(),'Register')]"));

Since this is different from Selenium 1, which does search for the
element every time you use it, the selenium.click() command is mapped
as:

selenium.click("xpath=//button[contains(text(),'Register')]");

WebElement element =
driver.findElement(By.xpath("//button[contains(text(),'Register')]"));
element.click();

So each time your test issues a click(), WebDriver will re-search for
the element before clicking on it. This is why I brought up point (2)
- your xpath is probably picking up a different Register button on the
page than the one you expect, which is why you got the error.

I hope this helps,

Jason

Danny Guerrier

unread,
Jan 8, 2010, 1:02:48 PM1/8/10
to webd...@googlegroups.com
Your findElements sent me in the right direction.  I listed out all buttons the driver has and it is indeed holding on to stale button references.  Is there a way to pick out the visible button?

Danny Guerrier

unread,
Jan 8, 2010, 1:34:29 PM1/8/10
to webd...@googlegroups.com
Thanks Jason.  That is what was happening, sort of.
While going through the wizard only a portion of the page is updated.  It's a complete replacement of the contents of the div but i guess since it wasn't a total page refresh that the original reference is still there.  The subsequent search for the register button returned the first and the new button.

I'm hoping there's a clean way to pick out the visible button reference.  I have it working by getting a list of button elements that match that xpath and hardcoded the test to click the second instance.  I don't really like doing this way.

Jason Leyba

unread,
Jan 8, 2010, 1:51:07 PM1/8/10
to webd...@googlegroups.com
This assumes the first Register button is the ancestor of a hidden div
like: <div style="display:none;">

//div[not(contains(@style, "display:none"))]//button[contains(text(),
'Register')]

I haven't tested this and my XPath is a bit rusty, so the above
expression may need some tweaking.

-- Jason

Tomás Pollak

unread,
Jan 8, 2010, 3:40:39 PM1/8/10
to webd...@googlegroups.com
You can also iterate through the list of elements and ask if it's rendered to find the one you want:

((RenderedWebElement)element).isDisplayed();

Cheers,
Tomás
Reply all
Reply to author
Forward
0 new messages