Use CSS Selectors with HtmlUnit
- by kerry
HtmlUnit is a great library for performing web integration tests in Java. But sometimes node traversal can be somewhat cumbersome. Fear not fellow automated tester (good for you!). I found a great little project on Github that will allow you to query your document for elements via css selectors similar to jQuery.
The project is located at https://github.com/chrsan/css-selectors. You can use Maven to build it, or download 1.0.2 here. Beware. I will not be updating this link so I suggest you download the latest code.
In any case, you can use it like so:
// from HtmlUnit getting started
final WebClient webClient = new WebClient();
final HtmlPage page = webClient.getPage("http://htmlunit.sourceforge.net");
final DOMNodeSelector cssSelector = new DOMNodeSelector(page.getDocumentElement());
final Set elements = cssSelector.querySelectorAll("div.section h2");
final Node first = elements.iterator().next();
assertThat(first.getTextContent(), equalTo("HtmlUnit"));
The only problem here is that the querySelectAll returns a Set<Node>. Not HtmlElement like we may want in some cases. However, if you were to reflect on the Set, you would find that it is indeed a Set of HtmlElement objects.
Typically, I like to create a base class for my web tests. Just for fun, I am using the $ method similar to jQuery.
public class WebTestBase {
protected WebClient webClient;
protected HtmlPage htmlPage;
protected void goTo(final String url){
return (HtmlPage)webClient.getPage(url);
}
protected List $(final String cssSelector) {
final DOMNodeSelector cssSelector = new DOMNodeSelector(htmlPage.getDocumentElement());
final Set nodes = cssSelector.querySelectorAll("div.section h2");
// for some reason Set cannot be cast to Set?
final List elements = new ArrayList(nodes.size());
for (final Node node : nodes) {
elements.add((HtmlElement)node);
}
return elements;
}
}
Now we can write tests like this:
public class LoginWebTest extends WebTestBase {
@Test
public void login_page_has_instructions() throws Exception {
goTo(baseUrl + "/login")
assertThat( $("p.instructions").size(), equalTo(1) );
}
}