How to test Jakarta Faces with HTMLUnit and Arquillian

In this article we will walk through the HTMLUnit library to learn how to test Web applications. You can combine HTMLUnit with Arquillian to test Jakarta Faces applications with ease.

What is HTML Unit?

HTMLUnit is a Java-based testing tool that allows developers to automate testing of web applications. It simulates a web browser, allowing users to test the functionality and behavior of a web application as if it were being accessed through a web browser.

One of the main benefits of using HTMLUnit is that it is lightweight and easy to use. It requires no installation and you can run it from the command line or integrated into a build tool such as Maven or Gradle. You can also use HTMLUnit in conjunction with other testing frameworks. For example with JUnit and Arquillian, to create more comprehensive test suites.

To use HTMLUnit for testing a web application, the developer first needs to create a Java project and add HTMLUnit as a dependency. Once the project is set up, the developer can use the HTMLUnit API to navigate to a web page, fill out forms, and interact with elements on the page. For example, the following code navigates to the Google homepage and searches for the term “HTMLUnit”:

WebClient webClient = new WebClient();

HtmlPage page = webClient.getPage("http://www.google.com");
HtmlForm form = page.getFormByName("f");
HtmlTextInput textField = form.getInputByName("q");

textField.setValueAttribute("HTMLUnit");
HtmlButton button = form.getButtonByName("btnK");
page = button.click();

HTMLUnit also allows developers to test the rendering and layout of web pages by providing a DOM (Document Object Model) representation of the page. This allows developers to verify that the page is rendered correctly and that elements are positioned as expected.

One of the limitations of HTMLUnit is that it does not support JavaScript, which can be a problem for web applications that rely heavily on JavaScript for their functionality. However, HTMLUnit does provide a way to enable JavaScript support by using the Rhino engine, which is a JavaScript implementation written in Java.

Besides, if you are developing server-based applications using Jakarta Server Faces you won’t need to mess up with Javascript code. As proof of concept, in the next section we will show how to test an application using Jakarta Server Faces using HTMLUnit and Arquillian.

Tesing a JSF Application

To test HTMLUnit we will reuse a simple Jakarta Faces application from one of our tutorials. This application csontains a Form with input text fields. By submitting the Form, the CDI Beans will add a row to a DataTable element that is in the same page.

For the sake of simplicity, we will show here just the index.xhtml page. The full source code is available at the end of this article.

Here is the index.xhtml page:

<html xmlns="http://www.w3.org/1999/xhtml"
		xmlns:f="jakarta.faces.core" xmlns:ui="jakarta.faces.facelets"
		xmlns:h="jakarta.faces.html" >
<h:head>
	<h:outputStylesheet name="style.css" />
</h:head>

<h:body>
	<h2>JSF Basic demo</h2>

	<h:form id="formpanel">

		<h:panelGrid columns="2" styleClass="default">

			<h:outputLabel for="name" value="Name: " />
			<h:inputText id="name" value="#{user.name}" />

			<h:outputLabel for="name" value="Surname: " />
			<h:inputText id="surname" value="#{user.surname}" />

			<h:outputLabel for="name" value="Email: " />
			<h:inputText id="email" value="#{user.email}" />

			<h:commandButton id="submit" actionListener="#{manager.save}"
							 styleClass="buttons" value="Save" />
			<h:messages errorStyle="color: red" infoStyle="color: green"  />
			<br/>
			<ui:debug/>
		</h:panelGrid>
	</h:form>
	<br/>
	<h:form id="datatableform" >
		<h:dataTable id="mytable" name="mytable" value="#{userList}" var="item" styleClass="table"
					 headerClass="table-header"
					 rowClasses="table-odd-row,table-even-row">
			<h:column>
				<f:facet name="header">Name</f:facet>
				<h:outputText value="#{item.name}" />
			</h:column>
			<h:column>
				<f:facet name="header">Surname</f:facet>
				<h:outputText value="#{item.surname}" />
			</h:column>

			<h:column>
				<f:facet name="header">Email</f:facet>
				<h:outputText value="#{item.email}" />
			</h:column>
			<h:column>
				<f:facet name="header">Delete</f:facet>
				<h:commandButton actionListener="#{manager.delete(item)}"
								 styleClass="buttons" value="Delete" />
			</h:column>
		</h:dataTable>
	</h:form>

</h:body>
</html>

The index.xhtml view should look like that when you deploy it on WildFly and add an entry:

How to test JSF applications

Next, we will build a simple test with HTMLUnit and Arquillian to do exactly the same thing.

Coding our Arquillian Test with HTMLUnit

  • Firstly, we need to define our test as ArquillianTest.
  • Then, we will add a @Deployment method which creates a WebArchive by importing it from the target folder of the Maven application
  • Finally, we will add @Before and @After methods to bootstrap and stop the WebClient interface, which is represent the browser when you work with HtmlUnit:
@RunWith(Arquillian.class)

public class CustomerIT {

	@ArquillianResource
	private URL webUrl;
	private WebClient webClient;

	@Deployment(testable = false)
	public static WebArchive createDeployment() {
		return create(ZipImporter.class, "jsf-demo.war")
				.importFrom(new File("target/jsf-demo.war"))
				.as(WebArchive.class);
	}

	@Before
	public void setUp() {
		webClient = new WebClient();
	}

	@After
	public void tearDown() {
		webClient.close();
	}
  
   // test here
}

Next, let’s add a Test method in our Class:

@Test
public void test() {	 
	try {

		// Navigate to the Home page 
		HtmlPage page = webClient.getPage(webUrl + "index.xhtml");

		// Get input text 'name' and set a value 
		HtmlInput name = (HtmlInput) page.getElementById("formpanel:name");
		name.setValueAttribute("john");

		// Get input text 'surname' and set a value 
		HtmlInput surname = (HtmlInput) page.getElementById("formpanel:surname");
		surname.setValueAttribute("smith");

		// Get input text 'email' and set a value 
		HtmlInput email = (HtmlInput) page.getElementById("formpanel:email");
		email.setValueAttribute("[email protected]");

		HtmlSubmitInput submit = (HtmlSubmitInput) page.getElementById("formpanel:submit");

		// Get a new HtmlPage after submitting
		HtmlPage page2 = submit.click();

		// Iterate on the Table
		final HtmlTable table = page2.getHtmlElementById("datatableform:mytable");
		for (final HtmlTableRow row : table.getRows()) {
			System.out.println("Found row");
			for (final HtmlTableCell cell : row.getCells()) {
				System.out.println("   Found cell: " + cell.asNormalizedText());
			}
		}


	} catch (Exception e) {
		System.out.println(e.getClass());
		e.getMessage();
	}  
}

In order to interact with our Web page, we can use the HTML Components which are available under the package com.gargoylesoftware.htmlunit.html. For example, the HtmlInput component represents an Input Text.

In the first part of our Test, we are setting some values in the Text fields.

Next, we are clicking the Submit button to send the data to the Server-Side CDI Beans. Please notice that the click() method returns a new HtmlPage with the updated DOM.

Finally, we are iterating over the DataTable JSF Component. Behind the hoods, the DataTable is an HTML Table. Therefore, we can use the HtmlTable Class to fetch the content of it.

The example includes two Arquillian Profiles to test our application. Make sure you have configured your JBOSS_HOME in the src/test/resources/arquillian.xml file:

<arquillian xmlns="http://jboss.org/schema/arquillian" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
			xsi:schemaLocation="http://jboss.org/schema/arquillian
    http://jboss.org/schema/arquillian/arquillian_1_0.xsd">

	<!-- Example configuration for a managed WildFly instance -->
	<container qualifier="jboss" default="true">
		<configuration>
			<property name="jbossHome">/home/francesco/jboss/wildfly-27.0.0.Final</property>
			<property name="managementPort">9990</property>
			<property name="managementAddress">localhost</property>
		</configuration>
	</container>
</arquillian>

Finally, test the application. To run a remote Test:

mvn clean package verify -Parq-wildfly-remote

You should see the Datatable output from the Arquillian Test:

   Found cell: Name
   Found cell: Surname
   Found cell: Email
   Found cell: Delete
Found row
   Found cell: john
   Found cell: smith
   Found cell: [email protected]
   Found cell: Delete

Conclusion

This article was a quickstart to learn how to use HTMLUnit as testing framework for Web application. HTMLUnit provides a simple way to test server-side application such as Jakarta Faces.

Source code: https://github.com/fmarchioni/mastertheboss/tree/master/web/test-jsf

Found the article helpful? if so please follow us on Socials