Arquillian Warp and TomEE

Arquillian Warp is a great extension to the (now) well known Arquillian library allowing you to execute client code (web browsing for instance) and validating server state.

The last released version is the 1.0.0.Alpha1. I got some issues working with it so here some tips to make it work as fast as possible.

First (not mandatory but better) exclude slf4j-log4j from warp (that’s a transitive dependency which doesn’t bring back slf4j-api so it makes slf4j not usable in the webapp).


I used with warp graphene-webdriver 2 and (as usually tomee):



Now let say you have a servlet on “/hello” pattern/mapping.

Because it is warp Alpha1 we can’t get the request injected automatically so you can add a filter storing the request in a thread local if you need it:

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;

@WebFilter(urlPatterns = "/*")
public class RequestHolder implements Filter {
    public static final ThreadLocal<HttpServletRequest> REQUESTS = new ThreadLocal<HttpServletRequest>();

    public void init(final FilterConfig filterConfig) throws ServletException {
        // no-op

    public void doFilter(final ServletRequest request, final ServletResponse response, final FilterChain chain) throws IOException, ServletException {
        REQUESTS.set((HttpServletRequest) request);
        try {
        } finally {

    public void destroy() {
        // no-op

Here we are! We can write our Warp test.

Some elements are mandatory:

  • @WarpTest on the test class
  • @RunAsClient on test method
  • @Deployment(testable = true) (by default but don’t override it with testable = false)

The idea is to associte with “client actions” (go on page /hello for us) some server assertions (check the hello servlet added a name in the session for instance).

What to take care about:

  • Use static class for ServerAssertions (Alpha2 will support inner classes)
  • configure the scan.xml file to exclude (=include others) the test class otherwise you’ll need to enrich the war with all its needed dependencies (graphene, selenium…) to be able to load completely the test class

Here the test:

import org.jboss.arquillian.container.test.api.Deployment;
import org.jboss.arquillian.container.test.api.RunAsClient;
import org.jboss.arquillian.drone.api.annotation.Drone;
import org.jboss.arquillian.junit.Arquillian;
import org.jboss.arquillian.test.api.ArquillianResource;
import org.jboss.arquillian.warp.ClientAction;
import org.jboss.arquillian.warp.ServerAssertion;
import org.jboss.arquillian.warp.Warp;
import org.jboss.arquillian.warp.WarpTest;
import org.jboss.arquillian.warp.extension.servlet.AfterServlet;
import org.jboss.arquillian.warp.extension.servlet.BeforeServlet;
import org.jboss.arquillian.warp.server.filter.WarpFilter;
import org.jboss.shrinkwrap.api.ArchivePaths;
import org.jboss.shrinkwrap.api.ShrinkWrap;
import org.jboss.shrinkwrap.api.asset.StringAsset;
import org.jboss.shrinkwrap.api.spec.WebArchive;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.openqa.selenium.WebDriver;

import javax.servlet.http.HttpServletRequest;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNull;

public class WarpDemoTest {
    public static WebArchive jar() {
        return ShrinkWrap.create(WebArchive.class, "hello-warp.war")
                    // in this test we don't have a lot of JEE classes so simply list them
                    // in real world we'll use <packages> tag
                    .addAsWebInfResource(new StringAsset("<scan>" +
                            "   <classes>" +
                            "       <class>" + HelloWeb.class.getName() + "</class>" +
                            "       <class>" + WarpFilter.class.getName() + "</class>" +
                            "       <class>" + RequestHolder.class.getName() + "</class>" +
                            "   </classes>" +
                            "</scan>"), ArchivePaths.create("scan.xml"))
                    .addClasses(HelloWeb.class, RequestHolder.class);

    private URL contextRoot;

    private WebDriver driver;

    public void validSessionUpdate() throws IOException {
        Warp.execute(new ClientAction() {
            public void action() { // call our servlet which store hello as name in the session
                driver.navigate().to(contextRoot.toExternalForm() + "hello");
        }).verify(new NameSessionAttributeAssertion()); // valid the name is in the session

    // static class because in Warp Alpha1 the test will be serialized otherwise
    public static class NameSessionAttributeAssertion extends ServerAssertion {
        /* with next warp version (Alpha2) we'll be able to do (and remove RequestHolder):
        private HttpServletRequest request;

        public void beforeServlet() {

        public void afterServlet() {
            assertEquals("hello", name());

        private String name() {
            return (String) RequestHolder.REQUESTS.get().getSession().getAttribute("name");

I would like to thank (again) Aslask Knutsen for his help on this topic.


1 thought on “Arquillian Warp and TomEE

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s