December 20, 2018

Basic Capybara-Gauge: Set Up Headless Chrome

This is the fourth part of a series of blog posts. Care to go back to the beginning

We've come up with test specs for Dave Haeffner's The-Internet. We've set up a Ruby environment to run the tests, and configured Chrome to open the Login page.

With this entry, we will be activating Chrome in Headless Mode, i.e. running Chrome but without a visual interface, allowing the tests to run faster.

About Headless Chrome

According to Eric Bidelman's article, Getting Started with Headless Chrome, the new option of running Chrome in Headless mode started with Google Chrome version 59, released in May 2017.

Before, you had to use something such as PhantomJS to emulate the Chrome browser if you wanted to run Chrome in a place where the processing power to bring up a visual window would be a waste, such as running it with an automated test script running in a continuous integration environment. Now, it is built right in.

"Headless Chrome is shipping in Chrome 59. It's a way to run the Chrome browser in a headless environment. Essentially, running Chrome without chrome! It brings all modern web platform features provided by Chromium and the Blink rendering engine to the command line.

"Why is that useful? A headless browser is a great tool for automated testing and server environments where you don't need a visible UI shell. For example, you may want to run some tests against a real web page, create a PDF of it, or just inspect how the browser renders an URL".

The power of Headless Chrome and browser automation (Google I/O '18)

There are a few command line interface commands from this article that we can incorporate when registering the Chrome driver:
  • Command to run Chrome in Headless Mode: --headless
  • Needed when running on Windows: --disable-gpu
  • Aren't setting up a specific Chrome user? --no-sandbox
There is one more command we should activate, in case we want to eventually use Chrome inside a Docker container: --disable-dev-shm-usage

If you launch a Docker container, by default, the /dev/shm partition will be 64 MB in size, too small to load. Let's add this to the spec_helper file.

Let's create a constant in Ruby to indicate if we want Headless mode on or off.

How do we know we are in headless mode or not when running the test? Let's output it to the screen:
  • HEADLESS_MODE = true
  • puts "CHROME_DRIVER: Headless mode == #{HEADLESS_MODE}"
Ruby is dynamically typed. Put a Boolean in it, it becomes a Boolean! Put a String in it, it becomes a String!

Ruby allows you to take a String and embed the value of a variable in it by using the hashtag and surrounding the variable with curly braces.

Move Headless Value to Gauge Properties

Gauge allows you to switch up environment properties for your Gauge project.

Let's say you want to have the tests run on your default environment (env/default) in your file:
  • Need visual aids for debugging? Set HEADLESS = false
  • Don't need visual aids for debugging? Set HEADLESS = true
By adding the HEADLESS = false in our env/default/ file we don't have to go mucking about in the code itself to change these environment variables.

In our spec_helper file, we declare a constant, HEADLESS_MODE, and setting it to the environment variable we created:


 require 'bundler'  
 require 'capybara/dsl'  
 require 'capybara/rspec'  
 module DRIVER  
  include RSpec::Matchers  
  include Capybara::DSL  
 TIMEOUT = 20  
 Capybara.default_driver = :chrome  
 Capybara.current_driver = :chrome  
 Capybara.javascript_driver = :chrome  
 before_suite do  
  Capybara.register_driver(:chrome) do |app|  
   options =  
   puts "CHROME_DRIVER: Headless mode == #{HEADLESS_MODE}"  
   if HEADLESS_MODE == true  
           browser: :chrome,  
           options: options)  
  Capybara.configure do |config|  
   config.default_max_wait_time = timeout  
   config.ignore_hidden_elements = true  
 Gauge.configure do |config|  
  config.include DRIVER  
  config.screengrabber = -> {'/tmp/screenshot.png')  
    return File.binread('/tmp/screenshot.png')  

Copying and pasting the to a new local directory in the env folder, and adding on HEADLESS = false, we get:

 gauge_reports_dir = reports  
 overwrite_reports = true  
 screenshot_on_failure = true  
 logs_directory = logs  
 enable_multithreading = false  
 gauge_clear_state_level = scenario  
 gauge_specs_dir = specs  
 csv_delimiter = ,  
 allow_multiline_step = false   

 # sample_key = sample_value  
 HEADLESS = false  

Running the Headless Tests

Want to run the tests pulling the environment variables of the local environment, where tests are being run in Chrome regularly, where HEADLESS = false?
  • bundle exec gauge run specs/Navigation.spec -v
Want to switch it up and see if tests can be run headlessly?

Change that HEADLESS = true in the file.

Next, we will revisit the Authorization test scenarios we came up with when analyzing The-Internet.
Happy Testing!

-T.J. Maher

Sr. QA Engineer, Software Engineer in Test
Meetup Organizer, Ministry of Testing - Boston

Twitter | YouTubeLinkedIn | Articles

No comments: