4

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.

7
  • 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, 2011 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, 2011 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, 2011 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, 2011 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, 2011 at 20:27

1 Answer 1

2

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.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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