Warp 1.0.0.Alpha2 Released
January 15, 2013
It has been a pretty long road from Alpha1 to this release, focused primarily on polishing the user experience.
So without any further ado, let’s look at the new shiny features!
Highlighted Features
- Renaming Warp API methods
The API methods were renamed according to the results of our public survey. (read more)
In the simplest scenario you want to inspect the first request after performing a given client activity. For this purpose, you can use a basic Warp API known from Alpha1:
Warp
.initiate(Activity)
.inspect(Inspection);
This will intercept the first request coming from the client and ignore the rest of the potential requests.
Additionally, Warp will ignore requests for favicon.ico which could fail your test unexpectadly.
You can find more samples for this API in a source .
- Anonymous and Inner Classes
It’s now much easier to define a verification code, which is also more readable.
In Alpha1, you had to use a top-level or a static inner classes to define inspections.
In Alpha2, you can provide non-static inner class or even anonymous class.
Warp // first you need to initiate activity which triggers HTTP request .initiate(new Activity() { public void perform() { ajaxButton.click(); } })
// and then specify what behavior should be inspected on the server .inspect(new Inspection() {
// don't forget to specify serialVerionUID to allow serialization private static final long serialVersionUID = 1L;
// bring JSF context via dependency injection @ArquillianResource FacesContext facesContext;
// verify expected behavior in given request phase @AfterPhase(RESTORE_VIEW) public void beforeServlet() { assertTrue(facesContext.isPostback()); } });
This example showed how to use the new API together with anonymous inspections
- Multiple Requests / Request Groups
It is possible to intercept several requests during one Warp execution.
Warp allows you to verify more than one request triggered by a single client activity. This allows you to verify e.g. a request for HTML page and all its resources (JS, CSS, images) separately. This feature is called Request Groups.
// Request Group execution will return WarpResult WarpResult result = Warp .initiate(Activity) // a group specification without name - the name will be generated .group() .observe(HttpRequestFilter) .inspect(Inspection1) // a named group specification - the result can be easily accessed .group("second") .observe(HttpRequestFilter) .inspect(Inspection2) // you need to execute whole Request Group once it is completely specified .execute();
// you can access details of finished execution result.getGroup("second").getInspection();
The Request Groups execution returns a WarpResult
which contains details about the finished execution. In order to access the results related to a specific group, you can give the group a name
- Request Observers & Fluent API
The new API for observing the correct request allows you to select which request should be verified on a server.
When using Request Groups, all of the requests will be inspected by the inspections defined in that group. There might be one or more requests verified by each group.
Since multiple request can be triggered, you might want to choose the correct request to observe. For this purpose, we have the HttpRequestFilter
interface, where you specify which HttpRequest
should matches the current group.
import static org.jboss.arquillian.warp.client.filter.http.HttpFilters.request;
// will accept only requests for HTML ...group() .observe(request().uri().contains(".html"))
// will accept only REST requests for JSON ...group() .observe(request().header().containsValue("Accept", "application/json"))
// will accept only POST requests ...group() .observe(request().method().equal(POST))
In order to simplify writing the Warp specifications, you can define the observer using a fluent API and static factory methods.
- Dependency Injection for Servlets and JSF
Test enrichers now allow the the injection of Servlet and JSF resources. (read more)
- Renaming Phaser to Warp JSF
The JSF specific extension was renamed from Phaser to Warp JSF. (read more)
- Introduction of Dependency Chain
The dependency chain was introduced to bring in all necessary dependencies by specifying just one dependency. (read more)
- Warp Extensions for REST and Spring MVC
Thanks to Jakub Narloch, we have two new additions to Arquillian Galaxy. (read more)
Under the Hood
- Usability and Debugging Improvements
A focus of Alpha2 was to polishing the way Warp behave in case of failures and on debuggability of Warp execution.
- Validation of Warp Specification
Warp now validates that the number of observed requests match a number of expected requests. It also makes sure that all of defined lifecycle callbacks are executed on the server, to avoid any false positives.
As you can see there are many of new features, so let’s look at them separately:
Renaming Warp API
After Alpha1 we got several requests for clarifying the Warp high-level API:
Warp.execute(ClientAction).verify(ServerAssertion)
The announced survey helped us choose the new API. As a result, 88% of participants reported they found this new API more natural:
Warp.initiate(Activity).inspect(Inspection)
Big thanks to everyone who participated in the survey! This type of collaboration makes me really proud to be part of the team.
Warp Extensions: REST and Spring MVC
Warp was from the beginning built as a project that focused on any framework/technology that is based on top of the Servlet API.
Thus it’s not surprising that there are already two extensions shaping out thanks to Jakub Narloch:
Introduction of Dependency Chain
Putting Warp to work in your Maven project is now as easy as defining a single dependency:
<dependency>
<groupId>org.jboss.arquillian.extension</groupId>
<artifactId>arquillian-warp</artifactId>
<version>1.0.0.Alpha2</version>
<type>pom</type>
</dependency>
This declaration will bring Warp core, which supports Servlet API lifecycle callbacks.
Renaming Phaser to Warp JSF
Initially we had created Phaser as the next generation of the successful JSFUnit. It occured to use that Phaser is an unfortunate name and it just makes it harded to understand the Arquillian eco-system.
That’s why we have come up with a simpler variant – so let me introduce the Warp JSF extension.
You can bring Warp JSF to your project just by adding the following declaration:
<dependency>
<groupId>org.jboss.arquillian.extension</groupId>
<artifactId>arquillian-warp-jsf</artifactId>
<version>1.0.0.Alpha2</version>
</dependency>
Dependency Injection for Servlets and JSF
After the announcement of the Alpha1 release, we focused on improving Warp to come closer to the Arquillian goal: bring all necessary dependencies to the test (in our case to inspection).
Now, you can not only inject all CDI managed beans (@Inject
), EJB beans (@EJB
) or container managed resources @Resource
, but you can also inject the following resources:
- Servlet resources
ServletRequest
orHttpServletRequest
ServletResponse
orHttpServletResponse
- JSF resources
FacesContext
Application
ELContext
,ELResolver
,ExpressionFactory
ExceptionHandler
Flash
NavigationHandler
PartialViewContext
RenderKit
ResourceHandler
StateManager
UIViewRoot
ViewHandler
Migration from Alpha1
We’ve create a little bash script to convert the java source from Alpha1 API to Alpha2 that might help you with the upgrade.
How to Learn Warp?
The best way now is to look at functional tests for Warp or Warp JSF.
Roadmap
The roadmap to Beta1 is pretty clear:
- documentation and guides
- adding features known from SeamTest and JSFUnit
- new injections and event hooks (e.g. improved CDI integration)
- hardering and usability enhancements (here we rely on your issue reports!)
Along the way we will welcome every idea for integrating Warp with your favorite web framework – so don’t be a stranger and come to us!