I can hear you ask why this should be a problem. It was because the link looked as follows:
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<a href="blah-location">BlahBlah<span>arbitrary text</span></a> |
It turns out the usual WebDriver incantations along the lines of findElement(By.xpath("arbitrary-xpath")).getText() was returning nothing for the link's text. I looked around for a while and found that the only solution I had was to look things up via Javascript seeing as there were no ids to fallback on.
In the end it worked out that document.evaluate became the saviour of the day, since it allowed me to make xpath queries on a document. The result is a java step definition and cucumber feature file that look as follows:
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Feature: Extracting a text node from a link | |
Scenario: A link has text | |
When I open abitrary page | |
Then my link must have the following text BlahBlah |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import cuke4duke.annotation.I18n.EN.Then; | |
import helpers.SeleniumWrapper; | |
import helpers.WebPageHelpers; | |
import org.openqa.selenium.By; | |
import org.openqa.selenium.WebElement; | |
import static helpers.SeleniumFactory.getSelenium; | |
import static org.junit.Assert.*; | |
public class linknodelookup { | |
private static final String JS_FIND_FIRST_TEXT_NODE_VALUE = "return arguments[0].firstChild.nodeValue"; | |
@Then("^my link must have the following text (.*)$") | |
public void linkMustHaveTextNodeWithSuppliedLabel(String label) { | |
JavascriptExecutor executor = (JavascriptExecutor)getSelenium(); | |
String linkXpath = "//div[@class='arbitrary-div']/ul/li[2]/a"; | |
WebElement element = driver.findElement(By.xpath(linkXpath); | |
String text = (String)executor.executeScript(JS_FIND_FIRST_TEXT_NODE_VALUE, element); | |
assertTrue(String.format("%s should be present in link",label), text.equals(label)); | |
} | |
} |
UPDATE: Changed the step definition file so that the xpath lookup is done in WebDriver instead of in the javascript seeing as xpath lookups cannot be relied upon in Internet Explorer.
I suppose you could argue that the html could be changed to be better. True, but atimes that might not be an option. The purists will argue as they do here that it isn't a feature that should be provided by WebDriver but I think it would help to have a way of traversing the DOM once you have looked up an element. I should like to read about other creative solutions to a problem of this nature.