Automated Testing QR Codes in Selenium WebDriver
How to test QR Codes on a web page in automated test scripts
This is also included in the “How to in Selenium WebDriver” series.
QR Codes are a barcode that can be scanned with a camera app or dedicated scanner. QR Codes are becoming a more and more common method of link sharing, but how can we test that the QR Code you generated goes where it needs to go?
This tutorial will show you how to verify that a valid QR Code was created and it successfully goes to a particular URL.
Tutorial Website
The WhenWise app (created by me) has a QR Code for directly booking an appointment with a resource. The below QR Code is an example on a server running locally for testing purposes (if you try to scan it, it won’t work).
Test Design
Save the QR Code image
Selenium 4 supports saving an individual page element to an image. Typically, generated QR codes are in SVG format, not conventional bitmap image formats such as PNG.Read the QR code
We need to decode the QR code to text. This can be achieved from a library.
(The availability of many libraries is one great benefit of writing automated tests in a powerful scripting language such as Ruby.)Verify the URL
Determine the expected URL first, then compare it with the decoded text from the QR code.
I used raw Selenium WebDriver with RSpec syntax for automated test scripts (AgileWay Test Automation Formula).
Prerequisite
I use qrio, a QR code decoder library in pure Ruby. Install it on your command line with:
gem install qrio
We can use QRio to extract the text from a QR Code image. Example usage from the documentation is:
require 'qrio'
qr_decoded = Qrio::Qr.load("qr-code.png").qr.text
Complete Test Script
it "Verify QRCode" do
require "qrio"
visit("/human_resources/6")
human_resource_page = HumanResourcePage.new(driver)
expected_qrcode_url = driver.find_element(:id, "booking-qrcode")["href"]
puts "Expected => #{expected_qrcode_url}"
# save the qr code image
tmp_dir = File.expand_path File.join(File.dirname(__FILE__), "..", "..", "tmp")
dest_image_file_path = File.join(tmp_dir, "qr_code.png")
elem_qrcode = driver.find_element(:tag_name, "svg")
elem_qrcode.save_screenshot(dest_image_file_path)
# read the qr code
qr_code_text = Qrio::Qr.load(dest_image_file_path).qr.text
puts "Scanned => #{qr_code_text}" # assert QR code url is correct
expect(qr_code_text).to eq(expected_qrcode_url)
end
Notes:
Find the QR Code element
Here I used thetag_name
locator, as there is only one SVG image on the WhenWise site.
If there are more, usefind_elements(:tag_name, ...).last
or an XPath locator.Save the QR code image
Using Selenium’selem.save_screenshot
(v4).
Note: I suggest using a relative path, it’s good practice.Decode the QR code from the saved image
Using theqrio
library. There are other libraries in Ruby (and other languages as well), but I have not encountered any problems with QRio.
Test Execution (in TestWise)
Below is a screenshot after execution in TestWise.
For demonstration purposes, I added two steps to print out the expected and scanned QR Code’s URLs, displayed in the console at the bottom right.
Expected => http://localhost:8080/biz/wise-driving/for/ben-cooper
Scanned => http://localhost:8080/biz/wise-driving/for/ben-cooper
Both are the same — so the test passes successfully!
The full execution can be seen in the animated gif below.
Alternatives
I tried using a Chrome Extension “QR Code Reader” first, a more visual way. It worked in normal mode but NOT in automation mode.
Anyway, I think the approach I showed earlier is better. The Chrome extension approach may work if you find a good one. Check out this article on how to load Chrome extensions in your Selenium script.