Selenium WebDriver – How To Automate Charts And Graphs Validation

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.

chart-base-2-html

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.

chart-source

 

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

ocular-base-location

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!

ocular-snap-location

 

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.

chart-result-2

For the failed test, difference was highlighted as shown here!!
chart-result-1

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 🙂

 

Share This:

31 thoughts on “Selenium WebDriver – How To Automate Charts And Graphs Validation

  1. 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.

  2. Hi
    Thank you for this tutorial. I just wanted to know whether the ocular software is an open source one .

    1. 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/

  3. 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

  4. 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!

  5. 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.

  6. 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?.

  7. 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

  8. 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)

    1. 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.

Leave a Reply to Shakti Cancel reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.