Best approach to find nested elements with WebDriver :When Xpath becomes your best friend

Most of the time, browser automation using WebDriver is all about finding html elements: find a button and click it to perform any action, find an user input text box and set a specific text, find a link and click that links.

But sometimes, even when sounds contradictory, your test is about don’t find an element, for instance that some actions designated to an admin user are not available for a standard user.

There is a significant behavior when you are facing scenarios with nested elements (for instance divs inside divs). It seems like there is a small issue related to nesting. Let me put an example : Given the following HTML output this are the nesting observations:

<div class = "ui-dialog-buttonpane">
    <div class = "ui-dialog-buttonset">
        <button
            role = "button"
            class = "ui-button"
            type = "button">
            <span class = "ui-button-text">No</span>
        </button>
        <button
            role = "button"
            class = "ui-button"
            type = "button">
            <span class = "ui-button-text">Yes</span>
        </button>
    </div>
</div>

If you want to access Yes/No buttons, you first need to find the div identified by the class ui-dialog-buttonpane, then using that IWebElement, you need to find the other div with a class ui-dialog-buttonset. Coding this search, it should be something like :

//Finding modal dialog
var modalDialog = driver.FindElement(By.ClassName("ui-dialog-buttonpane"));

//finding the div that holds the buttons, but finding it within modal dialog
var buttonsDiv = modalDialog.FindElement(By.ClassName("ui-dialog-buttonset"));
//Now you can easily find the buttons within the button
Assert.IsTrue(buttonsDiv.FindElements(By.TagName("button")).count() == 2);

But this way becomes exponentially complex depending with the nesting levels, if you have 5 level nesting, you will need to follow this approach, because the WebDriver won’t find the element from the first level.

XPath becomes your best friend.

Even when there might be some hit to the performance, see Webdriver Xpath Performance, when the XPath expression becomes too long, it helps a lot to find nested elements. Following with our example to find the Yes/No buttons and using Firebug’s FirePah, see First steps with FirePath : What a useful tool , this tool helps me to get the Xpath expression to be used with WebDriver :

FirePath

And if you are looking for the Xpath expression that returns the two buttons, then just edit the expression to something like this:

Xpath

Note how the two buttons become  selected.

One more time it’s easy to see how important is to use tools to make things easy 🙂

Advertisements

About Michael Hidalgo

Michael is a Software Developer Engineer based on San José, Costa Rica. He leads the OWASP Chapter from Costa Rica. You can take a look at my blog at http://blog.michaelhidalgo.info/
This entry was posted in Architecture, Browser Automation, FirePath, Selenium WebDriver, Tools and tagged , , . Bookmark the permalink.

4 Responses to Best approach to find nested elements with WebDriver :When Xpath becomes your best friend

  1. Dinis Cruz says:

    That C# code sample is still far to complex and harder to read. We need to add some extension methods to it, to make it simpler.

    Btw, every time you use a code sample from TM, please link to its sourcecode location in GitHub

  2. Dinis Cruz says:

    Also, why don’t you use jQuery to find that element?

  3. Michael Hidalgo says:

    I was trying to use it but sometimes objects became undefined in Internet Explorer, I was thinking to create a wrapper around it and make it easier, We have some customs methods that makes it easy to read, for instance Click_Link(“Your Link”).

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s