Getting an element’s parent in WebDriver in C#

I was looking for an easy inbuilt way to access an element’s parent in WebDriver in C# today, similar to this method in watir-webdriver:

b.text_field( name: 'q').parent

but I couldn't find one. This is needed when you have two elements next to each other (siblings), and you want to access one via identifying the other. A classic case is where you have a label element which you use to identify, and then want to get its input sibling to enter some text.

sample html

The only way I could do this in WebDriver was to write a C# extension method that uses an xpath expression to locate the parent element

public static IWebElement GetParent(this IWebElement e)
{
return e.FindElement(By.XPath(".."));
}

I believe it would be useful to have this built into WebDriver but I won't be holding my breath for it to happen as according to Simon Stewart:

"It was left out because webdriver isn't a tool for doing random walks of a webpage and because there are already mechanisms to get hold of the parent element that don't add additional methods to one of the core interfaces."

So, I'm wondering. Is this xpath really the only way to get an element's parent? Is there a better way? Would you find this useful to be in built?

8 thoughts on “Getting an element’s parent in WebDriver in C#

  1. I usually use JavaScript for this. In C#, this looks like:

    ((IJavaScriptExecutor)driver).ExecuteScript(“return arguments[0].parentNode;”, element);

    1. Thanks Jim.
      Is there any way to execute javascript from an element without referring to the driver?
      Otherwise, I can’t write an extension method to do this (without passing in the driver as a parameter, which is kinda odd)

  2. I only know that there is a better way with xpath: matching the label element as a conditional of locating the parent. This way, you don’t need to travel upwards at all.

    //tr[*[@class='label'][text()='Name']]//*[@class='data']//input

    Hope this helps at least somewhat.

    1. This is the approach I’ve found to work: describing input fields in rows containing a label and an input column by referencing the input element relative to the row containing the desired label text. I have, however, found that text() sometimes works and sometimes fails to find the desired text — even if I do a contains or starts-with on the text. In the cases that text() didn’t work, the text was inside another wrapper I could reference.

      For example, I’ve used the following today:

      //tr[*[contains(strong,'Associated Accounts')]]//input

      //tr[*[contains(strong,'Notes')]]//textarea

      Ben

      1. Thanks for the suggestions. I actually try to avoid xpath selectors because they don’t work well in IE, so I tend to use direct methods (id, name, classname) followed by CSS selectors. This xpath was the last resort.

  3. You can use the CSS adjacent (“+”) or generic sibling (“~”) selectors to achieve this without needing to identify the parent:

    e.FindElement(By.CSS(“tr td.label + td.data > input”));
    or
    e.FindElement(By.CSS(“tr td.label ~ td.data > input”));

Comments are closed.