Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Find next sibling of any given element with Selenium WebDriver

I'm trying to create a method that given a WebElement finds and returns the very next element. I have found a lot of examples for what should work using XPath with "following" or "following-sibling" but I can't get it to work. For the purpose of the question here I will show the html, but the element types are irrelevant for what I need as I want a generic method that given any element of any type (a/ul/div/whatever) it will return the next sibling regardless of type.

<a id="blah" href="#" class="stuff">"My Label"</a>
<ul class="some-class">
    <li>...</li>
    <li>...</li>
</ul>

My buggy debugging code:

IWebElement element = driver.FindElement(By.Id("blah"));
IWebElement nextElement = element.FindElement(By.XPath("//following-sibling::ul[@class='some-class']"));

I suspect my xpath syntax is wrong... and I am frankly clueless. Does the "//" mean relative to element or to the DOM itself? Is there a way of doing this without knowing what the tag of the next element is? I would like to just get the next element no matter what type it is. I'd just like to figure out the simplest and most generic way to do this. What I would like to have:

public IWebElement NextSibling(IWebElement element) 
{
    IWebElement nextSibling = element.FindElement(By.?("magical string to find next sibling"));
    return nextSibling;
}

...which is exactly what you can already do in javascript with element.nextSibling()

like image 536
jibbs Avatar asked Jan 17 '17 20:01

jibbs


Video Answer


3 Answers

Try with .// in your xpath because that is relative path, you were using absolute path so it's not working as you expected.

like image 105
acikojevic Avatar answered Sep 18 '22 19:09

acikojevic


In xpath you wouldn't need the double slash, which actually means any decendants of the current context (which is not what you want). You can specify the current context by doing nothing i.e.

following-sibling::ul[@class='some-class']
like image 28
VilladsR Avatar answered Sep 17 '22 19:09

VilladsR


The best, and possibly only, solution I see is to just use javascript (element.nextSibling;) as I mentioned in the end of my question. I never even considered that I could use IJavaScriptExecutor to return an IWebElement until I found this: https://stackoverflow.com/a/11320472/2246511

Again, I do not want to have to provide anything about the sibling like what type it is or class or anything. The js nextSibling is exactly what I want.

like image 40
jibbs Avatar answered Sep 21 '22 19:09

jibbs