Overview:
Automated validation of Charts & Graphs is one of the biggest challenges in test automation. In our application, We have tons of charts. I would show you how I have automated that to give you some idea.
Ocular:
I would be using Ocular – the image validation library! In fact, I created this Ocular lib just for this purpose!
Udemy – Java 8 and Beyond for Testers:
TestAutomationGuru has released a brand new course in Udemy on Java 8 and Beyond for Testers. 12 hours course with java latest features, lambda, stream, functional style programming etc. Please access the above link which gives you the special discount. You can also get your money back if you do not like the course within 30 days.
Sample Application:
In order to explain things better, I am going to create 2 simple HTML files as shown below (I took the HTML from this site) & each HTML file contains 3 charts.
Basically here we are going to assume that we would expect the right side charts to be exactly like the ones on the left side. Right side charts are almost same – except the January data of the Income chart.
Our expectation here is – as part of our automated testing, this difference should be reported and the test should fail!
The HTML source looks like this.
Now It is time for us to design the Page Object for the above HTML file.
Page Object:
public class SampleChartPage {
private WebDriver driver;
private Map<String, String> map;
@FindBy(id = "buyers")
private WebElement buyersChart;
@FindBy(id = "countries")
private WebElement countriesChart;
@FindBy(id = "income")
private WebElement incomeChart;
public SampleChartPage(WebDriver driver) {
this.driver = driver;
PageFactory.initElements(driver, this);
// Page object should contain the location of the baseline images
// these images no need to be present
// Ocular will create these images if they are not found
map = new HashMap<String, String>();
map.put("buyers", "buyers.png");
map.put("countries", "countries.png");
map.put("income", "income.png");
}
public boolean verifyBuyersChart() {
return this.verifyChart(map.get("buyers"), buyersChart);
}
public boolean verifyCountriesChart() {
return this.verifyChart(map.get("countries"), countriesChart);
}
public boolean verifyIncomeChart() {
return this.verifyChart(map.get("income"), incomeChart);
}
// common method to compare the baseline image against actual whole page / specific element
private boolean verifyChart(String fileName, WebElement element) {
Path path = Paths.get(fileName);
OcularResult result = Ocular.snapshot()
.from(path)
.sample()
.using(driver)
.element(element)
.compare();
return result.isEqualsImages();
}
}
I assume above page object is self-explanatory. I create folders like this in the project.
- snap folder should contain all the baseline images
- result will contain the comparison result
Initially these folders can be empty. Because we would not have the images of those 3 charts web elements. [Ocular will create these images under the snap folder during the first run].
Now it is time for us to create the Test.
TestNG Test:
In my testNG test for this sample application, I have 3 tests.
- baseline_test – aim of this test to produce the baseline images first – when you run the test for the first time, Ocular creates the baseline images. So that, you can use it for any future validation. This test will always PASS.
- visual_test_without_any_change – here, basically I am going to call the same HTML file. So Ocular will compare the charts against the baselines created as part of the previous test (baseline_test). This test will PASS because since the same HTML is launched with same data, charts would be as expected.
- visual_test_after_change – in this test, I would launch another HTML where the income chart data is slightly changed. So Ocular will validate and report the differences.
Once I run the baseline_test, snap folder will contain all the images we need!
public class OcularDemo {
private WebDriver driver;
private SampleChartPage page;
@BeforeSuite
public void ocularConfig() {
// update ocular config
// set the base location of the baseline images - this folder should be present
// set the base location of the result after comparison - this folder should be present
Ocular.config()
.snapshotPath(Paths.get(".", "src/test/resources/snap"))
.resultPath(Paths.get(".", "src/test/resources/result"));
}
@BeforeMethod
public void beforeMethod() {
driver = new ChromeDriver();
}
@AfterMethod
public void afterMethod() {
driver.quit();
}
// during this test, snap folder is empty. ocular does not find any baseline images.
// so, ocular creates the baseline images and comparison result will be always TRUE.
@Test
public void baselineTest() throws InterruptedException {
driver.get("file:///" + Paths.get("chart-js.html").toAbsolutePath());
page = new SampleChartPage(driver);
Assert.assertTrue(page.verifyBuyersChart());
Assert.assertTrue(page.verifyCountriesChart());
Assert.assertTrue(page.verifyIncomeChart());
}
// during this test, snap folder contains the baseline images.
// so, ocular compares the actual webelement against the given image & returns the result
@Test(dependsOnMethods = "baselineTest")
public void visaul_test_without_any_change() throws InterruptedException {
driver.get("file:///" + Paths.get("chart-js.html").toAbsolutePath());
page = new SampleChartPage(driver);
Assert.assertTrue(page.verifyBuyersChart());
Assert.assertTrue(page.verifyCountriesChart());
Assert.assertTrue(page.verifyIncomeChart());
}
// snap folder already contains the baseline images.
// so, ocular compares the actual webelement against the given image & returns the result
// income chart data is changed - so it will fail
@Test(dependsOnMethods = "visaul_test_without_any_change")
public void visaul_test_after_change() throws InterruptedException {
driver.get("file:///" + Paths.get("chart-js-changed.html").toAbsolutePath());
page = new SampleChartPage(driver);
Assert.assertTrue(page.verifyBuyersChart());
Assert.assertTrue(page.verifyCountriesChart());
Assert.assertTrue(page.verifyIncomeChart()); // this will fail - because data is changed
}
}
Executing the above test produced below result.
For the failed test, difference was highlighted as shown here!!
Summary:
Most of the automation suites compares the charts by reading the chart data and compare if the data is as expected assuming actual validation of the chart is difficult. But if we see the above example, Verifying the charts is no longer a big challenge with Ocular! If we pass the baseline image location and element, Ocular compares and highlights the differences easily!
Hope the above example was easy for you to understand this better. Ocular can do a lot more than this!! So, Please check that out and leave a comment / suggestion.
Happy Testing & Subscribe 🙂
Hi ,
Thanks for sharing your knowledge, i have been following your blog for very long and always find it very useful .
I just wanted to seek some information , can you share on this topic – how we can validate the UI /WebElement with respect with truncation , overlap etc kind of bug detection logic in it in our script .
PS: I am sorry i am using this post for commenting.
Hi
Thank you for this tutorial. I just wanted to know whether the ocular software is an open source one .
Yes, it is Open Source.
Thank you !!
Thanks for the solution. It is working fine.
Really good one and it is working for me !!!!!
Hi vlns,
I tested Ocular and it runs smoothly on MacOS. But when it comes to Windows, I got a failure on assertion. When checking folder snap and result, here is what I got:
For snap folder:
http://i64.tinypic.com/2mnoux4.jpg
For result folder:
http://i63.tinypic.com/2hxn5zn.jpg
My Windows is Windows 10 64-bits. May I conclude that Ocular does not support Windows 10, since I can run the test normally on MacOS?
Ocular was developed in Java and should be able to work anywhere where JRE is running. Here the point is the application image is rendered by windows seems to be slightly off by few 1 or pixels which causes this failure which human beings can not notice. In those cases, I would suggest you to follow OS specific images for baseline. Check the responsive web design testing for example. http://www.testautomationguru.com/selenium-webdriver-how-to-automate-responsive-design-testing/
Hi vIns, could you give an example for katalon and Ocular? That will be so helpful.
Firstly i’m very thankful to you for the topics that you have mentioned in the blog.Mainly the Ocular.One doubt i’m working with the dashboard that are devloped in Tabelau so is there any other lib that will locate elements that developed in non HTML .Thanks in advance
I am not sure of other lib. Ocular is for selenium projects.
Does this work for svg charts??
Yes. It should.
Is Ocular be used if am coding in selenium with C# language?
No. It is a java lib.
Can you please tell which library can be used for automating ” comparison of graphs” in selenium with c#?
Hi,
I am not really familiar with C#. You could ask in Stackoverlfow to get help.
Thank you .!
I have experienced that screenshot comparison testing is flaky. Do you have some solution to make it more stable.
Can you elaborate more on that? You can exclude elements which are dynamic in nature. Will it fix your problem?
Actually I follow sample step to test chart on my page.
After the first run, snap image is created which is not that chart that I specified in element by xpath
for example: I have chart with id = “abc”
private boolean verifyChart(String fileName, WebElement element)
the element is that chart (chartjs and/or canvas)
The result is the image in snap folder is not the chart (the screen shot of chart is not correct)
and the result compare is always true although I made a change so that chart is differs with the baseline!
Please advise!
Can you share code so that I could check?
Is it possible to provide the x and y coordinates to take the baseline and actual screen shots?
I have a canvas graph in which x axis varies based on time, so i can not use webelement to locate the graph. I want to avoid the x-axis portion of graph.
Please advice.
You can create your own images either manually or programmatically and use ocular for comparison.
Great tutorial thanks. Have you ever tried to do this for a forex chart and do you think it would be able to identify chart patterns I. E head and shoulders or channels?.
It is an image comparison and validation library. I do not know about forex chart. You can try.
I wanna validate data points of graph that are tooltips,
can we do that using this in selenium java.
Such tool tips are easily accessible via Selenium itself. So, we should be able to do that.
Hi @vlns
I wanna compare image in my web application, but how can i get the excat image from DOM element, that I can use for assertion using Ocular
Hi @vlns
Getting the below issue on comparing the element from the bottom of the screen after page scroll down
Please Advise.
issue:java.awt.image.RasterFormatException: (y + height) is outside of Raster
at sun.awt.image.ByteInterleavedRaster.createWritableChild(ByteInterleavedRaster.java:1248)
at java.awt.image.BufferedImage.getSubimage(BufferedImage.java:1202)
at ocularComparator.ImageUtil.getElementSnapshot(ImageUtil.java:43)
at ocularSample.SampleBuilderImpl.element(SampleBuilderImpl.java:46)
Hi Nithya,
This is more of a bug in the utility which has been there for a while. Unfortunately I never had a chance to fix it.
Thanks.