To start with xpath are constructed by the development/test engineers (SDET). So constructing an effective xpath by and large depends on the development/test engineers. An optimized xpath should work identically in case of cross browser as well as cross platform tests.
getText()
getText()
gets the visible (i.e. not hidden by CSS) text of this element, including sub-elements, i.e. returns the visible text of the element.
java.lang.String getText()
Hence, you don't have to explicitly cast the returned result through toString()
and you can remove it. So your effective line of code will be:
System.out.print(driver.findElement(By.xpath("//*[@id='error-box']/ul/li")).getText());
Specification
As per the WebDriver-W3C Editor's Draft:
The Get Element Text command intends to return an element’s text “as rendered”. An element’s rendered text is also used for locating a elements by their link text and partial link text.
One of the major inputs to this specification was the open source Selenium project. This was in wide-spread use before this specification written, and so had set user expectations of how the Get Element Text command should work. As such, the approach presented here is known to be flawed, but provides the best compatibility with existing users.
Why does element xpath changes?
All browsers doesn't use the same rendering engine or rendering rules which turns out to be a major source of hurdle for web developers, and it's not something that seems to be going away anytime soon.
Solution
A blanket solution to this problem would be to make use of css whenever possible, as browsers tend to comply best when under strict stylesheet rules. A couple of examples:
Using the HTML <!DOCTYPE> Declaration: All HTML documents must start with a <!DOCTYPE> declaration. The declaration is not an HTML tag. It is an information
to the browser about what document type to expect. In HTML 5, the declaration is:
Using Reset CSS: The goal of a reset stylesheet is to reduce browser inconsistencies in things like default line heights, margins and font sizes of headings, and so on.
Using a clearfix : A useful method of clearing floats.
This usecase
Ideally, to extract the desired text you need to induce WebDriverWait for the visibilityOfElementLocated()
and you can use the following Locator Strategy:
System.out.println(new WebDriverWait(driver, 20).until(ExpectedConditions.visibilityOfElementLocated(By.xpath("//*[@id='error-box']/ul/li"))).getText());