Reusing browser instance in Geb UI tests

Tags: , , ,

Geb is next-generation UI testing library that frees developer from dealing with Selenium API which is in many cases not so friendly. The most important feature of Geb is its support, or I would even say, strong encouragement to use Page Objects in your UI tests. Page Objects are also present in Selenium, but they are not as intuitive and east to use as in Geb.
But enough about Geb itself. Today I will share with you simple trick how to share one browser instance when running many Geb UI tests. This will significantly reduce time needed to execute UI tests and also reduce memory usage on test machines.

The Problem

Assume we have many test classes (spefications) similar to this one below.

class ExampleUITest extends GebSpec {

    def "Should test feature 1"() {
        given:
        to LoginPage

        when:
        loginWith("login", "password")

        then:
        at HomePage
        assert loggedUserLabel == "loggedUser"
    }

    def "Should test feature 2"() {
        given:
        to LoginPage

        when:
        loginWith("login", "password")

        then:
        at HomePage
        assert loggedUserLabel == "loggedUser"
    }
   
    // and so on...

What we have to do is prepare browser instance (in our case Firefox one) to click through our tests. We could to it in setup() method:

class ExampleUITest extends GebSpec {

    def setup() {
        driver = new FirefoxDriver()
    }

    def "Should test feature 1"() {
        // ...
    }  

    def cleanup() {
        driver.quit()
    }

This approach works but it has one, big drawback. We all know that UI tests tend to last quite long and creating new browser instance for each, yes, each test method will only make this situation worse as it also takes some time to start browser on your testing server.

Second approach

We also could reuse same browser in each specification (each Geb class) by using setupSpec() and cleanupSpec() methods instead. This will reduce number of new instances created but still we will have many of them, especially in large codebase with many test classes.

Solution

My solution to this issue takes from both approaches presented above. But instead of creating browser for each specification, I am reusing one created in the first executed class.

To make it work we need to introduce common abstract class for all our UI tests:

class IntelliGebSpec extends GebSpec {

    static def cachedDriver // static variable will store our single driver instance

    def setupSpec() {
        if ( cachedDriver == null) { // in first Specification this will be true
            cachedDriver = new FirefoxDriver()  // so let's create driver and put it in cachedDriver variable
        }
    }

    def setup() {
        driver = cachedDriver   // each test should use our cached browser instance
    }

    // as we are reusing browser, we should logout from our application after
    // each test to have clean browser state on each test run
    def cleanup() {  
        if ($(id: "logout").isDisplayed()) {
            $(id: "logout").click()
            waitFor { $(id: "inputName").isDisplayed() }
        }
        driver.manage().deleteAllCookies()
    }
}    

Summary

In this post I have shown my home made solution to reusing browser in multiple tests. I strongly suggest all of you to check and try Geb, as after over a year of using Selenium I am really impressed by this library. Easy to use with really cool Page Objects.

Easy Html/Javascript JSON escaping in Scalatra

Tags: , ,

logo-scalatra
Scalatra is a small web-framework that allows to easily build Rest API for web applications. We are using it in two projects to serve JSON data consumed by AngularJS based front-ends. And in one of this project we had a problem with text messages that could contain Html/Javascript elements. User could save message and then this message could be used on two pages. On first we need to display escaped data (read-only view) and on second (edit page) we wanted to display message in the exactly same way as user typed it.
So basically we needed easy and declarative way to define which Scalatra Rest end-points should return escaped and not-escaped JSON data.

Basic Scalatra project

To show how it could be accomplished, we need a simple sample project using Scalatra. I didn’t want to create it from scratch by myself so I removed some Swagger related stuff from project by my colleague Krzysztof Ciesielski (his post about Scalatra and Swagger) and I was ready to go :) Full commit with this basic project is available here, but the most interesting class is shown below:
Continue reading this post …

XStream – XStreamely easy way to work with XML data in Java

Tags: , , ,

From time to time there is a moment when we have to deal with XML data. And most of the time it is not the happiest day in our life. There is even a term “XML hell” describing situation when programmer has to deal with many XML configuration files that are hard to comprehend. But, like it or not, sometimes we have no choice, mostly because specification from client says something like “use configuration written in XML file” or something similar. And in such cases, XStream comes with its very cool features that make dealing with XML really less painful.

xstream

Overview

XStream is a small library to serialize data between Java objects and XML. It’s lightweight, small, has nice API and what is most important, it works with and without custom annotations that we might be not allowed to add when we are not the owner of Java classes.
Continue reading this post …

Jasmine tests reporter in TeamCity with Scala and SBT

Tags: , , ,

This post is basically re-post of article I have written on my company blog here. But before you go there to read the full story, please check this short introduction below to decide if you are interested :)

In our company sandbox project called Bootzoooka we are using pretty cool technology stack: Scala, Scalatra, SBT and AngularJS. Of course we have some JavaScript tests that are executed using sbt jasmine plugin from Guardian. Current 0.8 version of this plugin allows to execute these tests in TeamCity and even fails build when any JS test is not passing, but it didn’t provide full test report for these tests. This plugin worked quite well for us, but we wanted something more and that’s why added story saying “As a Developer I want to see jasmine tests in TeamCity report” to our Bootzooka backlog.

To sum up, we have added support to TeamCity Reporting Tests feature allowing CI to react on specific log messages produced during different test execution phases and after that we released our forked version 0.8.1 of sbt jasmine plugin and also made a pull request to Guardian project.

The whole process of plugin modification is described in this blog post mentioned above.

Instant AngularJS Starter – book review

Tags: , ,

Some time ago I have received an offer from Packt Publishing to write a review of their new small book about AngularJS framework “Instant AngularJS Starter“. And because I still consider myself as a AngularJS beginner, I decided to give it a go.
angular_cover

Content

Book is indeed very short and concise, but still worth reading. It contains four main chapters, two short: one about AngularJS in general and second one with places about this library that are worth visiting and people on the Web that often publish something interesting and valuable on this topic. Luckily two remaning chapters are longer and contain the most interesting part of material covered in this book.

First large chapter guides us through a simple web application using Angular, starting from the scratch and then describing all its features and how they are implemented. It is a well formed and thought out step by step tutorial introducing newbies to the most important and most often used features of the library. And even if you have some experience with it, you will find something new and useful there.

Second large section is about top five features of AngularJS that make it special and so easy to use. There are some stuff about the most frequently used directives and annotations, detailed description of dependency injection and its internals, modules and how application could be modularised. And the last part is about writing custom, reusable directives. For me that was the most informative part of this book.

Impressions

So to sum up, I can suggest “Instant AngularJS Starter” to everyone starting their adventure with AngularJS and also for developers that have some experience with this library. In my opinion it is well structured and allows much easier start that online documentation available on the official site. From the other side, definitely it is not a best choice for those using Angular extensively for a year or so, as I think they won’t find anything new inside.

With my experience lasting only a few months, I have found many useful stuff, I have learnt about less known directives: ng-pluralize, ng-cloak or ng-init to name only a few. There were also a very interesting explanation what are differences between service, factory and provider methods and in which cases they should be used.

On the other hand I was really missing one subject: testing. Definitely this is the area that strongly distinguishes AngularJS from other libraries and frameworks and in my opinion it should be covered in every, even short, book about this library.

But in spite of that, I was really happy to read this book and my knowledge about Angular increased significantly after finishing it. Some thing were new and some were shifted to a correct locations in my head.

Twitter Bootstrap Navbar as AngularJS component

Tags: ,

You all know Twitter Bootstrap, don’t you? It’s the awesome library to make your web application looks pretty good without spending many hours on CSS. We are using Bootstrap based design in our current project that also uses AngularJS and as we are planning to have many new pages, we decided that’s the earlier we introduce some components to our UI the better. And, what shouldn’t be a surprise, navigation bar natually became the first candidate.

Overview

So in this post I am going to show how externalize Twitter Bootstrap Navbar into a separate, flexible AngularJS component. All source code is available in my GitHub repository , so everything should be easy to follow and repeat.

Basic setup

To start from the basics, I’ve prepared three pages that use the same navigation bar. These pages will soon become our super simple web application using AngularJS:

navbar_angularjs1

Next step will be adding AngularJS and converting three pages into one small application. This is done in this commit. And after that we are ready to start working on our Navbar component. Continue reading this post …