Arjun
Arjun

Reputation: 361

WebElement.findElement is not finding child element

I am trying to get child element (Card Number) from an html codes where html tags and class names are same. Below is the html code snippet

<li class="paymentMethods-stored">  
    <li class="paymentMethod">
        <div class="stored-card-details">
            <span class="body-2">Name: </span>
            <span class="body-2 body-2-md"> VISA</span>
        <p>
            <span class="body-2">Number:</span>
            <span class="body-2 body-2-md"> ************4305</span>
        </p>
        <p>
            <span class="body-2">Expiry:</span>
            <span class="body-2 body-2-md"> 03/2030</span>
        </p>
        </div>
    </li>
    <li class="paymentMethod">
        <div class="stored-card-details">
            <span class="body-2">Name: </span>
            <span class="body-2 body-2-md"> VISA</span>
        <p>
            <span class="body-2">Number:</span>
            <span class="body-2 body-2-md"> ************4111</span>
        </p>
        <p>
            <span class="body-2">Expiry:</span>
            <span class="body-2 body-2-md"> 04/2031</span>
        </p>
        </div>
    </li>
</li>

Below is the identifiers I tried. But both returned first card number "************4305".

@FindBy(xpath = "//li[@class='paymentMethods-stored']//li[@class='paymentMethod']")
private WebElement firstSavedCard;
        
@FindBy(xpath = "(//li[@class='paymentMethods-stored']//li[@class='paymentMethod'])[2]")
private WebElement secondSavedCard; 
        
String firstCard=firstSavedCard.findElement(By.xpath("//*[@class='stored-card-details']/p[1]/span[2]")).getText();
String secondCard=secondSavedCard.findElement(By.xpath("//*[@class='stored-card-details']/p[1]/span[2]")).getText();

        

Other options tried: this also returned first card number "************4305".

secondSavedCard.findElement(By.xpath("/p[1]/span[2]")).getText();
secondSavedCard.findElement(By.xpath(".//*[@class='stored-card-details']/p[1]/span[2]")).getText()

Upvotes: 2

Views: 671

Answers (3)

undetected Selenium
undetected Selenium

Reputation: 193308

As @Robbie Wareham mentioned in his answer //* would initiate the search from the root element, but as as your code block you need to search from the already found relative element.

To find the cardnumber as an alternative you can use the following locator strategies:

@FindBy(xpath = "//li[@class='paymentMethods-stored']//following::li[1]//p//span[contains(., 'Number')]//following-sibling::span[1]")
private WebElement firstSavedCardNumber;

@FindBy(xpath = "(//li[@class='paymentMethods-stored']//following::li[2]//p//span[contains(., 'Number')]//following-sibling::span[1]")
private WebElement secondSavedCardNumber;

Upvotes: 0

Robbie Wareham
Robbie Wareham

Reputation: 3448

The use of "//" at the start of the XPATH will always look at the root of the DOM and ignore the fact you have called "findElement" in the context of a parent element.

Using ".//" should fix this so you may want to double check that.

Alternatively, you can use "self::*" as a more verbose and obvious way

Upvotes: 2

Swaroop Humane
Swaroop Humane

Reputation: 1836

Try the below xpath to select all the numbered tag -

//li[@class="paymentMethod"]/descendant::span[4]

For selecting first element use -

(//li[@class="paymentMethod"]/descendant::span[4])[1]

for selecting second element use -

(//li[@class="paymentMethod"]/descendant::span[4])[2]

and so on.

Moreover you can use findelements instead of findelement which will find all the elements. Collect all the elements in a list and then iterate over and extract the text.

Upvotes: 1

Related Questions