Take the 2-minute tour ×
Software Quality Assurance & Testing Stack Exchange is a question and answer site for software quality control experts, automation engineers, and software testers. It's 100% free, no registration required.

I'm automating a part of the User Profile UI we have using WebDriver Selenium 2, I'm coding in Visual Studio so I am using the .Net version as I am more comfortable in C#, and I am testing this with IE8. Part of the problem I am having is that the User Profile page using tabs to actively display User Address information or User Interests - the flow that happens when going through the page is that the User Address information appears then after a Save Changes button is selected the User Interests tab is then made active. I'd like to make a small change in the User Address information, get to the User Interests and just save all changes by selecting the button on the User Interests page. Since its all one page, and just the active tabs change what information is displayed, the problem I am encountering with Web Driver is that the Elements become stale by the time I get to User Interests.

Basically the page is set up so that Tab1 - User Address, Tab2 - User Interests. Only one is actively displayed at one time.

Is there a way to refresh the elements? I am already doing FindElements when the page updates to pull in the Page Elements, I thought this would do a DOM refresh but that does not seem to be happening. Originally I thought this was a JQuery problem, as the Interests page has three Taxonomy drop downs that are populated, but I've finally isolated it to the button being unable to be selected, even through FindElements seems to return something. When I go to use Sendkeys on the button I usually get an Element is no longer valid error.

I believe if I was able to refresh the DOM then this would go away.

The code I am using is:

        while (!((IJavaScriptExecutor)driver).ExecuteScript("return jQuery.active;").ToString().Equals("0"));
        Assert.True(driver.PageSource.Contains("Topics of Interest"));
        wait.Until(webDriver => driver.FindElement(By.Id("ctl00_PlaceHolderMain_SavePersonalizationButton")));
        IWebElement saveButton2 = driver.FindElement(By.Id("ctl00_PlaceHolderMain_SavePersonalizationButton"));
        wait.Until(webDriver => saveButton2.Displayed);
        Assert.IsTrue(saveButton2.Displayed);
        saveButton2.SendKeys(Keys.Enter);

The while is my JQuery check to make sure nothing is running on the page. Then I added the Assert to make sure that the User Interests header is appearing so that I can be sure it's displayed (although since the text is on the source anyway regardless of which tab displays it passes). The waits were to make sure the elements are appearing on the page, not sure if I need this though. Edit: So my problem comes down to being able to detect the change from:

<div class="RoundedBox Tab inactive" onclick="toggleActiveTab (this, 'ctl00_PlaceHolderMain_PersonalizationTab')">

to

<div class="RoundedBox Tab" onclick="toggleActiveTab(this, 'ctl00_PlaceHolderMain_PersonalizationTab')">

Then I believe this will be resolved.

share|improve this question
    
Have you verified that the way you identify the elements in either tab is the same both before and after the tab is clicked? For example, if you're using xpath and the xpath references a classname that has changed after the click? As far as I know any time you call FindElement it is working with the most up to date version of the DOM. –  Sam Woods Sep 27 '11 at 23:02
    
Well I'm using the same FindElements syntax when working on Tab1 and on Tab2, which as far as I know should get the current DOM. I avoid XPath whenever I can and am using the ID's of the fields which don't change, so even on intial load the ID's should be the same as any further refreshes. Using Firebug I have verified this is true. –  MichaelF Sep 28 '11 at 14:44
    
Is this mitigated if you just put a sleep for a few seconds before clicking the calling FindElement and clicking "Save All"? Not suggesting that as the final solution, but just curious and trying to narrow down the possible causes. –  Sam Woods Sep 28 '11 at 16:16
    
Is there a sleep for Web Driver? I've seen wait and used that but haven't found a sleep - or a pause, that would allow me to wait until the second tab fully displays before looking for objects there. –  MichaelF Sep 29 '11 at 20:09
    
I wrapped all of my functions that find an element in a loop that polls for the existence of an element. Basically this: for (int i=0;i<3;i++) {try {driver.FindElement(...)} catch{if i=2 throw ...} System.Threading.Thread.Sleep(10000)} –  Sam Woods Sep 29 '11 at 20:27
show 2 more comments

1 Answer 1

up vote 0 down vote accepted

What I ended up doing was looking for an html source change in the page itself, there was no ID or Name to link to and pull it in as an object to detect the change - unless I am unaware of something that might do this. If so please let me know, I'd like to improve my coding skills if I can.

What I ended up doing was just look for the page source to know when the page updated at the second tab was active:

wait.Until(webDriver => (driver.PageSource.Contains("class=\"RoundedBox Tab\" onclick=\"toggleActiveTab(this, 'ctl00_PlaceHolderMain_PersonalizationTab')")));

Once I did that then the script proceeded as I wanted.

share|improve this answer
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.