Tuesday, 14 April 2015

Extending Arquillian Graphene


With Arquillian Graphene, you can write tests which inspect the GUI of your web application (HTML based ones) right from within your familiar Unit Test code structure.

And there are already many nice features available, but sometimes, you want to extend the concepts of Arquillian Graphene. So that you can write cleaner code in some use cases.

The good thing is that you can achieve this quite easily due to the internal structure of the framework which uses 'Enricher's and Service extensions.

Extended Page Fragments

The concept of Page Fragments is described here and allows you to encapsulate the HTML structure of your widget.

As an example, we have a look at the inputText widget from PrimeFaces.  When the validation of the field fails, the element gets an ui-state-error CSS class set. So instead of checking if the class attribute contains the text as in this statement:


You can create a Page Fragment for the component where you encapsulate this check.
Your test looks now much cleaner and more descriptive


But for more complex components, like for example the PrimeFaces dataTable, it is nearly impossible to reference all parts of the component using the FindBy annotation within your Page Fragment.

It would be much easier if we could have a method which is executed the first time our proxy of the Page Fragment is accessed.
In Java EE terminology, we would like to have a @PostConstruct annotated method executed.

To achieve this, we have to define our extension (through the org.jboss.arquillian.core.spi.LoadableExtension file) and add a TestEnricher.

The TestEnricher can be used to add additional functionality to a Page Object or Page Fragment.  In our case we define an interceptor which gets executed every time we invoke a method on our Proxy page fragment.

In this interceptor we can verify if this is the first time we invoke something on the proxy (a bit tricky to know as there is no real identifier in our proxy) and if so, with the help of a bi reflection, find the method annotated with @PostConstruct and execute it.

See GrafacesInterceptor for the code.

In this initialisation method, we can search for other components in our widget on the screen using the findElements method available in the WebElement class.

List<WebElement> headers = root.findElements(By.tagName("th"));

The above example finds all the column headers of our table.

Validating the Page fragment

Now we can have a powerful Page Fragment, by using the default Graphene capabilities and adding our @PostConstruct initialisation method.

But what happens if we assign the PrimeFaces DataTable Page Fragment to a completely different type of widget, like a button?  In fact, the assignment is just done by specifying an id.  And mistakes are easily made.

If you have written your code in a proper way, defensive where you perform plenty checks on null pointers and non existing components, you can end up with a test which just fails without telling you that you actually made a mistake in the @FindBy to identify the widget.

The second extension which we discuss here, is that you can implement a detector method, to verify if you assigned the Page Fragment to the correct widget on the screen.
You can use all kind information available on the root (tag name, CSS classes, etc) to decide if the assignment is correct.
And if not, you can fail the test with a descriptive message what happened.

Injecting non visual helpers

Selenium WebDriver has support for checking web browser alerts.
One of the drawbacks is the not trivial code you have to write to verify for example if the alert is shown.

WebDriverWait wait = new WebDriverWait(driver, 5);if (wait.until(ExpectedConditions.alertIsPresent()) == null) {

    fail("Alert not showing as feedback for user");}

When you want to encapsulate this in a helper class, you need to pass the WebDriver instance into it. 

But we can't use the regular Arquillian Graphene way of working (using injection).  Because we don't have an ID on the screen which we can link to. So we need a custom annotation for injection, without an ID.

Besides the TestEnricher I have discussed earlier, there also exist a SearchContextTestEnricher.  The name is a bit confusing but it allows you to 'enrich' the test class as a whole.  And thus here we can search for fields which are annotated with our custom annotation, like @Grafaces.
Our enricher instantiates the object and also injects the regular Arquillian Grafaces artefacts like WebDriver instances annotated with @Drone.

This allows us then to write nicely readable test code like 

assertEquals("You choose JSF", alertHandling.checkForAlert().switchToAlert().getAlertText());


Arquillian Graphene is a great framework for testing your HTML based GUI directly within the browser.  Due to the open structure, you can write easily extensions for it.
In this text, 3 examples are presented to have 
  • Java based initialisation of the Page Object/Page Fragment
  • Validation of the assignment of the Page Fragment to the HTML widget
  • Wrapping the Selenium WebDriver alert handling functionality in a helper class which can be injected into your test class.

The code is available a GitHub and was presented at the ConFESS 2015 conference. Slides are at SlideShare.

No comments:

Post a Comment