Tuesday, November 15, 2011

How to automate JQPlot Charts using Sahi


JQPlots is a charting engine. More details regarding the same can be found at this site. http://www.jqplot.com/

Application under test for which we are developing sahi automation, has two specific implementations of JQplots.

In both the implementations we found that JQPlot Chart gets painted with number of html elements which are recognized as _canvas by sahi. It is with the help of these elements we can verify chart content. Let us take a closer look at both the implementations.


Implementation One

AUT Functional Definition : CFD Charts: In the Swift-Kanban Application which the AUT we are testing, The Cumulative Flow Diagram (CFD) helps to track the performance of the project and how close you are to completing the project on a whole. It plots the count of cards in particular state/lane for each day between a specified duration. On the diagram, hover and rest your pointer on the line determining the total count of cards for different queues as on that date, which is displayed at the left corner of the chart. As you move to the next date, you can analyze how work has progressed.

TestCase Objective : We need to validate information represented in a CFD Chart.
Test Input - An excel with example data as shown below –

It basically indicates, when we hover on date 21-Sep-10, All the Lanes mentioned (Aechieve, Complete, Done, In-Progress, Ready, Backlog) should show respective values in the top-left corner table.

Test Output – Boolean. True indicates, real time values painted in the chart match the excel input. False indicate values in excel do not match the input data.

Test Automatoin Objective : We need to read the chart and output the data in excel format that matches the testcase input. So a simple CSV compare will meet the testcase objective.

AUT UI Recognition
So there were two challenges automating this JQPlot implementation:-
1. need to hover mouse at a particular position so as to get the data point
2. Read data

Since everything is an image, or more rightly _canvas element, how do we capture the element of our interest?

Firebug came to our rescue. It has helped me right from beginning in solving UI recognition challenges related to test automation. When we open the CFD page with firebug we have following findings –
Sahi Implementation

JQ Chart gets painted with –

1. _div(“jqplot-axis jqplot-xaxis”) with x-axis co-ordinates as its childnodes
2. _div(“jqplot-axis jqplot-yaxis”) with y-axis co-ordinates as its childnodes
3. _canvas(“jqplot-event-canvas”)
4. There are a number of other canvas elements like _canvas(“jqplot-grid-canvas”), _canvas(“jqplot-series-shadowCanvas”), etc which are not of our interest

So what we needed to do was (The Algo) –

1. get the position of x-axis co-ordinates (HTML Element).
2. hover mouse on the event canvas at the position found in point1
3. read the legend table getting painted in the left hand side corner
4. keep writing information in the table to an an array which can be written to a CSV at the end. Repeat step 1,2,3 till all the x-axis elements are over.

This is how we do it –

1. get the position of x-axis co-ordinates (HTML Element).
This could be easily done using the following –

_set($xAxisLength,parseInt(_div("jqplot-axis jqplot-xaxis").childNodes.length));
Element =>_div("jqplot-axis jqplot-xaxis").childNodes[0]
_set($value1, _position($xAxisElement)[0]); //get the $x, $y positions of the x-axis element.


2. hover mouse on the event canvas at the position found in point1

_call(_sahi.simulateMouseEventXY(document.getElementsByTagName("canvas")[document.getElementsByTagName("canvas").length-1], "mouseover", $x, $y,false,false));

3. read the legend table getting painted in the left hand side corner
This is a straight forward _table() recognition. Can be easily read using _cell, _getText methods.

4. keep writing information in the table to an an array which can be written to a CSV at the end. Repeat step 1,2,3 till all the x-axis elements are over.


Implementation Two

AUT Functional Definition : Control charts display limits and which is the voice of the process. Points outside of these control limits are signals indicating that the process is not operating as consistently as possible; that some assignable cause has resulted in a change in the process. Similarly, runs of points on one side of the average line should also be interpreted as a signal of some change in the process. When such signals exist, action should be taken to identify and eliminate them. When no such signals are present, no changes to the process control variables (i.e. “tampering”) is necessary or desirable.

TestCase Objective : We need to validate information represented in a Control Chart.
Test Input - An excel with example data as shown below –
All the bubbles are mentioned as points with their respective information captured from the tooltip.

Test Output – Boolean. True indicates, real time values painted in the chart match the excel input. False indicate values in excel do not match the input data.

Test Automatoin Objective : We need to read the chart and output the data in excel format that matches the testcase input. So a simple CSV compare will meet the testcase objective.

AUT UI Recognition
Control Charts are bubble charts. When we hover on any bubble, a tooltip displays information of interest. A static table is present in top-left hand side corner of the table.
Let us look at what firebug has to say about it.
Same as implementation one, it has x-axis and y-axis DIV Elements. Bubbles are painted on x-axis co-ordinate across the length of y-axis. There is no handle on where on x-axis a bubble will be painted.
Secondly when we hover mouse on any bubble a tooltip provides info which is a high-lighter DIV. It needs to be read and info in the table need to be captured.

The Sahi Implementation

So our algorithm to read control charts looks like this –

1. get all the x-axis co-ordinates
2. get position of a x-axis co-ordinate
3. mouse hover on a x-axis co-ordinate along the length of y-axis on the event canvas
4. if we hit upon a bubble, read the table painted in the tooltip
5. put the information in the table in an array, which finally will be written to CSV
6. iterate through step 2-5 to cover all the x-axis co-ordinates
7. A static table in the top left corner which remains un-altered through out the life time of chart settings can be read anytime and written to CSV.


This is how it is done -
1. get all the x-axis co-ordinates. This remains the same as in CFD Charts –

total number of x-axis points>_div("/jqplot-axis jqplot-xaxis).childNodes.length

2. get position of a x-axis co-ordinate

$xAxisElement = _canvas("jqplot-xaxis-tick["+$i+"]"
_position($xAxisElement) will give $x and $y values.

3. mouse hover on a x-axis co-ordinate along the length of y-axis on the event canvas
4. if we hit upon a bubble, read the table painted in the tooltip
5. put the information in the table in an array, which finally will be written to CSV

_set($click_x,(parseInt($xAxisElement_x_pos) - parseInt($canvas_x_pos) + parseInt($xAxisElement_width)));

for ($click_y = 0;$click_y<$canvas_height;$click_y=$click_y+3)
{
_click(_xy($eventCanvasObject, $click_x, $click_y));
_wait(1);
if (_isVisible($tooltipTableObject))
{
Read the table and write the tootltip data
}
}


6. iterate through step 2-5 to cover all the x-axis co-ordinates
7. A static table in the top left corner which remains un-altered through out the life time of chart settings can be read anytime and written to CSV.




1 comment: