Highcharts is an interactive javascript charts. Highcharts is using SVG (Scalable Vector Graphics). SVG defines the charts in XML format. SVG has some predefined shape elements such as rectangle (for bar chart), and path (for line chart). The chart is rendered with these shapes.
To automate the testing of the charts, we don't really need to go in detail on SVG. All we need to know is the DOM structure for the High Chart, navigate to the data points(shape elements) in the chart, mouse over on the data points so that tooltip with the data will be displayed and then read the chart data displayed in the tooltip. Then compare the chart data against the database.
Sample Code:
( I am using jQuery to read the data elements from the chart as well as tooltip information. If you don't know jQuery earlier, you can learn it easily. It's a javascript library which does too many things. What we use here is the core functionality of jQuery that is to find the elements from the HTML DOM structure. jQuery primarily uses CSS Selector syntax to find the elements from the HTML page. The sample code is for the chart that is displayed on the separate frame. You can customize the code if the chart is displayed on the main page itself)
//jQuery to return all the elements
String c = "return $('#frame id').contents().find(\"div[id='highcharts-index']\").contents().find(\"g[class='highcharts-series-group'] > g[class='highcharts-markers highcharts-series-0 highcharts-tracker'] > path[fill='#ft5es5']\").get()";
//jQuery to return tool-tip data
String tool1 = "return $('#' frame id).contents().find(\"div[id='highcharts-index']\").contents().find(\"g[class='highcharts-tooltip']>text>\").get();";
//Execute the jQuery to find the Path elements for all the data elements in the line chart
ArrayList webE = (ArrayList)((JavascriptExecutor) driver).executeScript(c);
driver.switchTo().frame("frame id");
//Mouse over on each path element and read the tooltip data
for (int i = 0; i < webE.size(); i++) {
//perform Mouseover on the element
Actions builder=new Actions(driver);
builder.moveToElement(webE.get(i)).click().build().perform();
driver.switchTo().defaultContent();
//Execute the jQuery to find the tooltip data
ArrayList webE2 = (ArrayList)((JavascriptExecutor) driver).executeScript(tool1);
driver.switchTo().frame("frame id");
System.out.println(webE2.get(0).getTagName() + webE2.get(0).getText());
System.out.println(webE2.get(1).getTagName() + webE2.get(1).getText());
System.out.println(webE2.get(2).getTagName() + webE2.get(2).getText());
}
Tips:
If you are using Chrome Driver, navigating between main window (default) and iFrame is little tricky. So it's a good idea to switch to the iFrame and then find the path elements using jQuery within the iFrame like ( return $(\"div[id='highcharts-index']\").contents().find(\"g[class='highcharts-series-group'] > g[class='highcharts-markers highcharts-series-0 highcharts-tracker'] > path[fill='#ft5es5']\").get()).
If mouseover doesn't work, try clicking twice : builder.moveToElement(webE.get(i)).click().build().perform();
builder.moveToElement(webE.get(i)).click().build().perform();
Use explicit wait for each element:
wait.until(ExpectedConditions.visibilityOfElementLocated(By.xpath("//*[@id='userInput']")));
Use driver.getPageSource() to debug the code:
It helps to print the page source(complete DOM structure) in the console. usually Eclipse console shows only 80000 characters. Go to preferences and uncheck the 'Limit the console output'. Now you can get the complete DOM structure in the console.
Use Debug options:
Use all the debug options for java in Eclipse:
1. Step into(F5)/Step Over(F6)/Step Return(F7)/Move to next breakpoint(F8)
2. watch/inspect/execute/return to line/expressions/variables
To automate the testing of the charts, we don't really need to go in detail on SVG. All we need to know is the DOM structure for the High Chart, navigate to the data points(shape elements) in the chart, mouse over on the data points so that tooltip with the data will be displayed and then read the chart data displayed in the tooltip. Then compare the chart data against the database.
Sample Code:
( I am using jQuery to read the data elements from the chart as well as tooltip information. If you don't know jQuery earlier, you can learn it easily. It's a javascript library which does too many things. What we use here is the core functionality of jQuery that is to find the elements from the HTML DOM structure. jQuery primarily uses CSS Selector syntax to find the elements from the HTML page. The sample code is for the chart that is displayed on the separate frame. You can customize the code if the chart is displayed on the main page itself)
//jQuery to return all the
String c = "return $('#frame id').contents().find(\"div[id='highcharts-index']\").contents().find(\"g[class='highcharts-series-group'] > g[class='highcharts-markers highcharts-series-0 highcharts-tracker'] > path[fill='#ft5es5']\").get()";
//jQuery to return tool-tip data
String tool1 = "return $('#' frame id).contents().find(\"div[id='highcharts-index']\").contents().find(\"g[class='highcharts-tooltip']>text>\").get();";
//Execute the jQuery to find the Path elements for all the data elements in the line chart
ArrayList
driver.switchTo().frame("frame id
//Mouse over on each path element and read the tooltip data
for (int i = 0; i < webE.size(); i++) {
//perform Mouseover on the
Actions builder=new Actions(driver);
builder.moveToElement(webE.get(i)).click().build().perform();
driver.switchTo().defaultContent();
//Execute the jQuery to find the tooltip data
ArrayList
driver.switchTo().frame("frame id
System.out.println(webE2.get(0).getTagName() + webE2.get(0).getText());
System.out.println(webE2.get(1).getTagName() + webE2.get(1).getText());
System.out.println(webE2.get(2).getTagName() + webE2.get(2).getText());
}
Tips:
If you are using Chrome Driver, navigating between main window (default) and iFrame is little tricky. So it's a good idea to switch to the iFrame and then find the path elements using jQuery within the iFrame like ( return $(\"div[id='highcharts-index']\").contents().find(\"g[class='highcharts-series-group'] > g[class='highcharts-markers highcharts-series-0 highcharts-tracker'] > path[fill='#ft5es5']\").get()).
If mouseover doesn't work, try clicking twice : builder.moveToElement(webE.get(i)).click().build().perform();
builder.moveToElement(webE.get(i)).click().build().perform();
Use explicit wait for each element:
wait.until(ExpectedConditions.visibilityOfElementLocated(By.xpath("//*[@id='userInput']")));
Use driver.getPageSource() to debug the code:
It helps to print the page source(complete DOM structure) in the console. usually Eclipse console shows only 80000 characters. Go to preferences and uncheck the 'Limit the console output'. Now you can get the complete DOM structure in the console.
Use Debug options:
Use all the debug options for java in Eclipse:
1. Step into(F5)/Step Over(F6)/Step Return(F7)/Move to next breakpoint(F8)
2. watch/inspect/execute/return to line/expressions/variables