alyn000r
alyn000r

Reputation: 566

How to use XPATH to search for a span with a class for Selenium Testing in JAVA

I am working on a piece of code which wants me to select the span with the class amountCharged and get the value of that span to test it against the mock value. The problem that I am facing is that I cannot seem to select that span using XPath. I have tried multiple ways and still fail, I went on W3Schools and Stackoverflow questions but was unable to nail the syntax.

Below is the error I am facing:

org.openqa.selenium.TimeoutException: Timed out after 60 seconds waiting for text ('£163.06') to be present in element found by `By.xpath:`

 //span[contains(@class, 'amountCharged')]

As you can see I am trying to use //span[contains(@class,'amountCharged')] as the XPATH, same issue with using "

/descendant::span[contains(@class, 'amountCharged')]

THE HTML STARTING FROM A PARENT DIV IS:

    <div class="panelMessage instructional" params="">    Total:         
 <span class="amountCharged">£163.06</span> quoted on          
<span class="reservationTime">Tue, 29 Nov 2011 15:46 GMT</span> . </div>
    </div>        
<div class="panelContent hideFocus noneBlock  " tabindex="-1" data-  context="panelContent">

The JAVA code is:

   private static void elementShouldContain(String locator, String value, String errorMessage, long timeout) {
    String xpath = buildLocator(locator, "");
    WebDriverWait customWait = new WebDriverWait(webDriverInstance, timeout / 1000);
    try {
    customWait.until(ExpectedConditions.textToBePresentInElement(By.xpath(xpath), value));
    } catch (Exception e) {
        // Handles the specific exception, except that the message is null, in which case throws a regular SeleniumException
        if (errorMessage != null)
            throw new CustomSeleniumException(errorMessage, e);
        else
            throw new SeleniumException(e);
    }
}

what am I missing please help.

Thank You

Upvotes: 1

Views: 30583

Answers (2)

Subh
Subh

Reputation: 4424

From the error you've mentioned, I suppose you are using textToBePresentInElement or textToBePresentInElementLocated or something related method under the ExpectedConditions class.

You can alternatively do this:
1- Wait for the visibility of the element using Explicit Wait
2- Retrieve the text
3- Assert/Compare the text with the value: '£163.06'.

You can try the below code that comprises of all above in order:

    String text_in_panel=null;
    try{
        //waiting 20 seconds for the visibility of the element
        WebDriverWait wait = new WebDriverWait(driver, 20);
        WebElement element = wait.until(ExpectedConditions.visibilityOfElementLocated(By.xpath("//div[contains(@class, 'panelMessage')]/span[1]")));

        //Retrieving the text from the element
        text_in_panel = element.getText();
    }catch(Throwable e){
        System.err.println("Element is not visible: "+e.getMessage());
    }

    //Comparing the text with the hard-coded value
    if(text_in_panel.equals("£163.06"))
        System.out.println("Text matches");
    else
        System.err.println("Text doesn't match");

[OR You can assert the values instead of comparing them, using the Assert class by importing import junit.framework.Assert;]

    //Assert the text with the hard-coded value
    try{
        Assert.assertEquals(text_in_panel, "£163.06");
        System.out.println("Text matches");
    }catch(Throwable e){
        System.err.println("Text doesn't match");
    }

Upvotes: 2

Saifur
Saifur

Reputation: 16201

Couple of things to keep that in mind:

  1. Testing the xpath on Chrome debugger of Firebug does not necessarily mean that the selector is going to return the target element uniquely. There might be some other elements hidden with same selector and webdriver will fail to find the target element in that case. For debugging purpose use findElements a see how many elements it returns.
  2. Element loading issue such as: visibility can also be another issue. That's why you need to make sure the element is present and visible. Use explicit wait

Try following xpaths

//span[@class='amountCharged']

If the class is not unique and you want to find the span depending on the div you can do the following:

//div[contains(@class,'panelMessage ')]//span[@class='amountCharged']

Upvotes: 6

Related Questions