简体   繁体   中英

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()

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

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.

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;

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM