Automated Testing Charts in Selenium WebDriver

Charting, such as HighCharts, is commonly seen on modern web apps. These charts packages usually generate charts in an SVG (Scalable Vector Graphics) format.

We probably want to test charts to see if they are being displayed correctly — but how can we do that with automation?

Test Design

  1. Verify the chart is present by checking the svg tag
  2. Save the chart to a file
  3. Verify the image file
  4. Visually inspect the image file on the Continuous Testing (CT) server

1. Verify the chart exists

To verify that the chart exists, we need to check whether the div (or figure) that you used to trigger the chart contains the chart. In HighCharts, you must create a div, and give it an id and then HighCharts will render the chart there for you. Here are the first few lines of the JavaScript I used to generate a chart in chart-container-9.

Highcharts.chart('chart-container-9', {
chart: {
type: 'column',
},
// other chart settings...
});

If we view the page source, you will notice that the chart is not there. There is nothing under chart-container-9.

JavaScript renders the chart afterwards, so it doesn’t show up in the Page Source. Once rendered properly, it will show on Inspect Element.

However, using Inspect Element, we can see that the chart container (in my case, chart-container-9 , which is the top-most chart) has an SVG.

To accommodate this in our test, we will:

  1. Wait for the JS to render
  2. Then verify that the svg tag exists
visit("/servers/1")
sleep 2 # wait JS rendering

elem = driver.find_element(:id, "chart-container-9")
elem_html = driver.execute_script("return arguments[0].outerHTML;", elem)
expect(elem_html).to include("<svg")

If you run this test, it will pass! Great, but it only checks that some svg was rendered — did your chart display correctly?

So how can we verify your chart was displayed with an end to end test?

2. Saving your chart as an image

The solution: save the svg as a PNG image.

Before doing this, decide the file destination (where you will save the image). Prior to checking the image file, make sure the image does not already exist.

Also, I recommend using a relative path to save the image so that the test will run on any machine.

tmp_dir = File.expand_path File.join(File.dirname(__FILE__), "..", "tmp")
dest_image_file_path = File.join(tmp_dir, "chart.png")
FileUtils.rm dest_image_file_path if File.exists?(dest_image_file_path)

# save the chart image, selenium 4 new feature
elem.save_screenshot(dest_image_file_path)
expect(File.exists?(dest_image_file_path)).to be true

By the way, saving a specific web element to an image is a Selenium 4 feature.

3. Verify the image file

Furthermore, we can verify whether what we saved is a valid image or not.

If we can open the image, it is valid, and then you can perform checks on the image (PNG), such as the dimensions, using the FastImage gem.

require('fastimage')
puts FastImage.type(dest_image_file_path) # => "png"
puts FastImage.size(dest_image_file_path) # => [300, 60]

Alternatively, we can extract the dimensions directly from a PNG file.

img_dim = IO.read(dest_image_file_path)[0x10..0x18].unpack('NN')
expect(img_dim).to eq([300, 60])

4. Visually inspect the image file on the Continuous Testing (CT) server

Apart from the automated test’s purposes, we may want to make the saved image file available to all team members. This can be beneficial if you manually want to verify the chart contents or other team members also want to look at the chart.

Automated Tests have little value unless you run them frequently in a continuous server. We can set this up with a BuildWise CT Server.

In BuildWise, you may specify specific files or directories to archive under the project settings.

Adding chart.png to BuildWise file archive setting.

After triggering a build, you can click the dropdown for “Build artifacts”, then you can see the chart image listed there.

chart.png listed under “Build artifacts” on BuildWise

Once you click on it, you can view the chart — straight from the CT server!

chart.png opened in BuildWise

Complete Code below

load File.dirname(__FILE__) + '/../test_helper.rb'describe "Sequential Test - Project Chart" do
include TestHelper
before(:all) do
# browser_type, browser_options, site_url are defined in test_helper.rb
@driver = $driver = Selenium::WebDriver.for(browser_type, browser_options)
driver.manage().window().resize_to(1280, 720)
driver.get(site_url)
relogin("pro")
end
after(:all) do
driver.quit unless debugging?
end
it "Chart exists on server project page" do
visit("/servers/1")
sleep 2 # wait JS rendering

elem = driver.find_element(:id, "chart-container-9")
elem_html = driver.execute_script("return arguments[0].outerHTML;", elem)
expect(elem_html).to include("<svg")

# save chart image, make sure no existing files first, relative path
tmp_dir = File.expand_path File.join(File.dirname(__FILE__), "..", "tmp")
dest_image_file_path = File.join(tmp_dir, "chart.png")
FileUtils.rm dest_image_file_path if File.exists?(dest_image_file_path)

# save the chart image, selenium 4 new feature
elem.save_screenshot(dest_image_file_path)
expect(File.exists?(dest_image_file_path)).to be true

img_dimension = IO.read(dest_image_file_path)[0x10..0x18].unpack('NN')
puts img_dimension.inspect
expect(img_dimension).to eq([300, 60])
end
end

--

--

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store