!geek

Code, learn & share

Using app objects in multi app functional tests

It is better to create small modular apps instead of single monolithic application. In Bahmni EMR we have small apps for Patient Registration, Consultation, etc. An end to end functional test covering patient registration and consultation goes through multiple apps. We needed to abstract the concept of an app in test code to increase the readability and maintainability.

The app objects are natural extension of page objects recommended for writing functional tests. An app encapsulates all pages and coarse level actions in the app.

Make sure functional tests are user centric

In modern day web applications, most of the data is fetched and saved using ajax calls and the mark up is generated on client side by compiling static HTML templates. The functional tests need to make sure assertions wait till completion of ajax call.

Couple of bad ways to achieve this is by using sleep(xSeconds) or wait_for_ajax like this

Keep your models independent of angular

If you are using MVC framework you need to make sure controllers are very thin and domain logic lies in small, framework independent, composable models - Wise People

In AngularJS, you need to make sure lot of data is not defined directly on $scope and domain logic is not dependent on angular’s digest cycle. If follow this mantra, unit testing the models would be a lot simpler which in turn is a indicates that your code in is good shape.

Javascript functions in JSON configuration

There is no native support for defining functions in JSON. Commonly used approach is to define function as string and use eval() or new Function() to contruct the function. The basic difference between these two are

  • eval() works within the current execution scope. It can access or modify local variables.
  • new Function() runs in a separate scope. It cannot access or modify local variables.

These samples show how the json would differ in these two cases

Spinners in single page apps

One of the good practices in single page apps, is to show spinners (overlay + loading icon) while retrieving data or saving asynchronously. Often people tend to add a generic interceptor to show spinner for all ajax calls. In any mid size app, you will realize that the assumption “Show an overlay for all ajax call” is incorrect. Few examples

  • An autocomplete input box fetching reote data
  • An infininte scroll fetching more data as the use scrolls down the list.

Printing external html templates using AngularJS

Use case

In Bahmni EMR we needed to support customizable html templates for printing patient regisatrtion card and other printable documents. We needed a print API which looks like

1
2
3
4
5
//Contract
printer.print(templateUrl, data)

//This would called on clicking the print button
printer.print('/config/registrationCardTempate.html', {patient: {name: 'Ram Kumar', dateOfBirth: '1978-08-23', gender: 'M'}})

Waiting for AngularJS digest cycle

The million dollar question most of the AngularJS users(devs) end up asking is

  • How to wait for angular digest cycle to be completed? or in simple terms
  • How to wait for browser to complete rendering the view with angular bindings?

Printing html with image and css

There are plenty of examples for printing html of an element. Most of them look like this

1
2
3
4
5
6
7
8
9
10
11
12
//The simple soultion but has few problems listed below.
function printHtml(html)
{
    var mywindow = window.open();
    mywindow.document.write('<html><head><title>My App</title>');
    mywindow.document.write('</head><body>');
    mywindow.document.write(html);
    mywindow.document.write('</body></html>');
    mywindow.print();
    mywindow.close();
    return true;
}

The issues with above solution: