DavidH
DavidH

Reputation: 75

Selenium WebDriver- WebElement.FindElements returns more elements then expected

I have an image gallery containing different "rows", with a particular amount of "columns" (images) in it. I want to create a method, where I can select a particular image based on x,y.

So I search for the section containing the gallery by using pageObjects.

@FindBy(how = How.XPATH, using = "//section[@id='gallery']")
private WebElement sectionGallery;

Then, I create a small method which will return all the rows for this gallery

public List<WebElement> getGalleryRows(){
        return sectionGallery.findElements(By.xpath("//div[@class='gallery-horizontal-row']"));
    }

And this is where the issue lies. I'm getting every Webelement which has the xpath expression "//div[@class='gallery-horizontal-row']" and not only the the webelements underneath the "sectiongallery" webelement.

Am I'm misinterpreting this functionality? For the underneath HTML source, I expect 3 Webelements returned, but I get 4.

When I do a Driver.FindElements on the complete Xpath expression it returns only 3 elements.

public List<WebElement> getGalleryRows(){
        return DriverManager.getDriver().findElements(By.xpath("//section[@id='gallery']//div[@class='gallery-horizontal-row']"));
    }

My HTML obscured source:

    <section data-section-title="Galerie" id="gallery">
<header>
    <h1>Galerie</h1>
</header>
<div>
    <div >  
        <div class="gallery-horizontal-row" style="height: 220px;">
            <div>
                <article class="gallery-item"></article>
                <article class="gallery-item"></article>
                <article class="gallery-item"></article>
                <article class="gallery-item"></article>
                <article class="gallery-item"></article>
            </div>
        </div>
        <div class="gallery-horizontal-row" style="height: 220px;">
            <div>
                <article class="gallery-item"></article>
                <article class="gallery-item"></article>
                <article class="gallery-item"></article>
            </div>
        </div>
        <div class="gallery-horizontal-row" style="height: 220px;">
            <div>
                <article class="gallery-item"></article>
                <article class="gallery-item"></article>
                <article class="gallery-item"></article>
                <article class="gallery-item"></article>
            </div>
        </div>
    </div>
</div>
</section>
<section id="other">
    ....
</section>  
<section id="other2">
    ....
</section>  
<section id="other3">
    ....
</section>  
<section data-section-title="other4" id="other4">
<header>
    <h1>Other4</h1>
</header>
<div>
    <div >  
        <div class="gallery-horizontal-row" style="height: 220px;">
            <div>
....

Upvotes: 4

Views: 3288

Answers (1)

Mathias M&#252;ller
Mathias M&#252;ller

Reputation: 22617

Add . in front of // (descendant-or-self:: axis) in the second expression:

return sectionGallery.findElements(By.xpath(".//div[@class='gallery-horizontal-row']"));

Am I misinterpreting this functionality?

Not completely, but an expression that starts with // selects elements anywhere in the input document, even if you have selected a subset of the input as the starting point for a second expression. Avoid // whenever possible - it is an axis that is heavily overused - especially by XPath beginners.

On the other hand, an expression that starts with .// really takes the context node as the starting point.

Upvotes: 7

Related Questions