0

I have a TestNG Selenium Script that will run in Chrome and Firefox, but fails when its run in Safari. I'm using an Assert to verify a name and Safari is having none of it. I'm still a noob so I'm not sure where to go from here. Thanks for any help

HTML:

<a href="https://xxxxxx/users/show/733981" target="_blank" xpath="1">Jeff Smith</a>

Safari Error:

java.lang.AssertionError: expected [JEFF SMITH] but found [Jeff Smith]

Code trial:

@Test(priority = 4)
public void VerifyGuest() {
    WebElement guestName = driver.findElement(By.xpath("//a[contains(text(),'Jeff Smith')]"));
    String expectedName = "JEFF SMITH";
    String actualName = guestName.getText();
    Assert.assertEquals(actualName, expectedName);
    System.out.println("Reservation Code Belongs to " + actualName);
}
undetected Selenium
  • 183,867
  • 41
  • 278
  • 352
Java Noob
  • 33
  • 4

2 Answers2

0

UPDATE, with the actual answer.

The getText() method (or "getElementText" webdriver command) returns the text as rendered (at least according to the specs it should).
The page obviously applies some css transforms on the text - the node value is capitalized (Jeff Smith), but it is returned as JEFF SMITH (that is what you also see in the browser, right?); that's quite easy to do - with a style like text-transform: uppercase;.

So Chrome & Firefox are following the webdriver specs, while Safari obviously isn't yet - it doesn't return the rendered form, but the one that is in the source.

So if you need to just verify the content of the element, I'd suggest normalizing its textual value - removing excessive whitespace, and converting it to lowercase.
In Java that's done with st.trim().toLowerCase() where st is your string variable's name.

Todor Minakov
  • 19,097
  • 3
  • 55
  • 60
  • How would I do that? – Java Noob Jan 25 '19 at 17:45
  • How to strip white space and lowercase? `st.trim().toLowerCase()` where `st` is your string variable. – Todor Minakov Jan 25 '19 at 18:07
  • @JavaNoob found your problem, see the update of the answer. – Todor Minakov Jan 25 '19 at 18:18
  • Thanks, I'll the "trimming" solution and let you know how it works out. Thanks for all the help you guys rule! – Java Noob Jan 25 '19 at 19:28
  • 1
    I changed the expected Name to "jeff smith" and add String actualName = guestName.getText().trim().toLowerCase(); and it worked like a charm. – Java Noob Jan 25 '19 at 20:28
  • Glad it did! Strictly for the trimming - have in mind html rendering substitutes multiple spaces with a single one - e.g. "JavaNoob" is shown as "JavaNoob" (except when ` ` is used). So you have to accommodate for that if your desired string has them. – Todor Minakov Jan 26 '19 at 08:28
0

Apparently there is no error in your code block but there is a Catch-22 sitution due to WebDriver using Browser’s Native XPath capabilities.

Browser’s Native XPath capabilities

At a high level, WebDriver uses a browser’s native XPath capabilities wherever possible. On those browsers that don’t have native XPath support, Selenium have provided their own implementation. This can lead to some unexpected behaviour due to the differences in the various XPath engines.

Browser_Native_Xpath_Capabilities

As an example, for the following piece of HTML:

<input type="text" name="example" />
<INPUT type="text" name="other" />

If your line of code is:

List<WebElement> inputs = driver.findElements(By.xpath("//input"));

The following number of matches will be found:

Xpath_Native_Support

Solution

As the element was identified based on the text as Jeff Smith you need to match with the rendered text which is Jeff Smith. So your effective code block will be:

@Test(priority = 4)
public void VerifyGuest() {
    WebElement guestName = driver.findElement(By.xpath("//a[contains(text(),'Jeff Smith')]"));
    String expectedName = "Jeff Smith";
    String actualName = guestName.getText();
    Assert.assertEquals(actualName, expectedName);
    System.out.println("Reservation Code Belongs to " + actualName);
}

Note: Identifying an element with XPath's text() and retriving the text through getText() isn't a proper way to Assert any text. Perhaps the desired element should be identified with some other effective Locator Strategy.

undetected Selenium
  • 183,867
  • 41
  • 278
  • 352
  • I've tried using "Jeff Smith" (instead of JEFF SMITH). Safari will Pass, but that causes Chrome and Safari to fail – Java Noob Jan 25 '19 at 17:43
  • Can I use ".getAttribute " to get the "Jeff Smith" info instead? – Java Noob Jan 25 '19 at 17:48
  • @JavaNoob That is what I exactly explained through an example quoting from the documentation. Safari and Chrome behavior is not documented. That's on my to-do list :) – undetected Selenium Jan 25 '19 at 17:50
  • The DOM for Safari and Chrome are slightly Different. Would the Style Attribute be causing the issue? Safari DOM: Jeff Smith Chrome DOM: Jeff Smith – Java Noob Jan 25 '19 at 18:07
  • @JavaNoob Now you have hit the right chord. Of-coarse different browser will render the [HTML DOM](https://www.w3schools.com/js/js_htmldom.asp) differently. See: [Getting Difference in count of “Total Number of links” on webpage through Selenium and Browser Development Tools](https://stackoverflow.com/questions/47955774/getting-difference-in-count-of-total-number-of-links-on-webpage-through-seleni/47956061#47956061). `style` and `xpath="1"` attribute makes the difference here. – undetected Selenium Jan 25 '19 at 19:05