6

I am having a very funny issue. I am having a xpath through which i am retrieving value.

Ex.

System.out.print(driver.findElement(By.xpath("//*[@id='error-box']/ul/li")).getText().toString());

In firefox and Chrome it is giving same text while in IE it is giving different text.

Is there any difference between xpath of various browser or it is some other issue which i am not getting.

DebanjanB
  • 118,661
  • 30
  • 168
  • 217
OPTIMUS
  • 542
  • 2
  • 10
  • 24
  • 4
    Well the answer isn't quite yes and isn't quite no. IE doesn't have a native XPath engine so a Javascript-based one is used by Selenium in it's place - called Wicked Good XPath. Therefore you *may* get inconsistencies - after all it's a JS implementation of something most other browsers have natively. The other thing is the different support for elements that browsers have. A common one is the `placeholder` property in some elements (HTML5) - – Arran Apr 14 '14 at 18:22
  • getText() should a return a string as per docs (https://selenium.googlecode.com/svn/trunk/docs/api/java/org/openqa/selenium/WebElement.html). So you probably don't need .toString() at the end – Andrejs Feb 20 '16 at 19:33

5 Answers5

7

Read up on how Selenium handles Xpaths here.

In Chrome and Firefox, I right-clicked on the same DOM element (as described here), selected "copy Xpath" and this is what I got:

Chrome: //*[@id="js-pjax-container"]/div2/div2/form/button

Firefox (with Firebug): /html/body/div[4]/div2/div2/div2/form/button

(one is with attribute value and the other (FF) is the absolute path, which demonstrates that FF doesn't understand Crhome generated Xpath)

So for Selenium test purposes, it matters between browsers. (I didn't test on IE)

I ran this

 @Test
        public void testGitHubButton(){
        WebDriver driver = new FirefoxDriver();
        driver.get("https://github.com/");
       String signup = driver.findElement(By.xpath("/html/body/div[4]/div[1]/div[1]/div[1]/form/button")).getText();
           Assert.assertEquals("Testing for string equality", "Sign up for GitHub", signup );
        driver.close();
        driver.quit();
        }

And the test passes. If I copy paste Chrome's Xpath in there, it will fail.

Community
  • 1
  • 1
Andrejs
  • 8,412
  • 4
  • 38
  • 42
0

To start with 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 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());
DebanjanB
  • 118,661
  • 30
  • 168
  • 217
-1

They are different per browser. Some are case sensitive, some are not. Per w3schools.com "Unfortunately, there are different ways of dealing with XPath in Internet Explorer and other browsers."

Jeff White
  • 21
  • 1
-1

Difference is only in [Index] numbers in Xpaths between IE and Chrome. In IE index starts with 0 but in chrome Index starts with 1.
Example:

if Xpath you got from chrome is

/html/body/div[4]/div[3]/div[3]/div[1]/form/button 

the same Xpath in Internet Explorer(IE) will be

/html/body/div[3]/div[2]/div[2]/div/form/button

(Note: div is same as div[0])

As there is no native Xpath engine in IE so you may copy the Xpath from chrome and decrease index by one as mentioned above, it works perfectly for me in HTMLDocument by using my own method of converting xpath to tags of IHTMLElement of IE.

Navarasu
  • 5,221
  • 2
  • 17
  • 29
vktn108
  • 1
  • 1
-2

No. XPaths are interpreted in the same way everywhere.

You might want to check the getText() method.

OR You might want to check whether you are logged into some account in IE ( and not in chrome/FF) or vice versa. EG: you would get a different DOM for google.com as opposed to google.com (logged into google account)

bit
  • 4,139
  • 1
  • 25
  • 44