October 26, 2017

Up and Running With Headless Chrome

Headless is a common term that’s thrown around in the Software Engineering world. It generally means the ability of a piece of software that usually has a graphical user interface (GUI) component to run without it.

But, Why...

Automated testing for web applications has come a long way. You can write tests that drive a web browser in almost any language and have them run continuously whenever an application's code has changed.

What has been tricky in the past is running those tests on remote servers in the cloud. Typically a linux server on Amazon Web Services or Google Cloud Platform (or Azure, IBM, etc) will not be configured with desktop GUI software, because it is unnecessary for day to day software development. Being able to run Chrome in that environment in headless mode makes automated testing in the cloud not only possible, but pretty simple.


As of Chrome 60, headless mode is available on all of the major operating systems, Windows, Mac and Linux.


If you’re using Windows or Mac, it’s extremely likely you already have and use Google Chrome, but for arguments sake, we’ll provide the details of how to install on all major operating systems, Windows, Mac and Linux.

Windows & Mac

Go here to download Chrome. Once downloaded, run the executable and follow the setup instructions.


Open up your terminal and follow these steps:

Add the key:

$ wget -q -O - https://dl-ssl.google.com/linux/linux_signing_key.pub | sudo apt-key add -

Set repository:

$ sudo sh -c 'echo "deb [arch=amd64] http://dl.google.com/linux/chrome/deb/ stable main" >> /etc/apt/sources.list.d/google-chrome.list'

Update: $ sudo apt-get update

Install: $ sudo apt-get install google-chrome-stable

Confirm Installation

Open up your terminal of choice, type in google-chrome and press enter. If at this point you see “command not found”, or something along those lines, then you’ll need to add the Chrome executable path to the path system environment variable, or add an alias which is what we’re going to do for consistency in this article.

We’re going to explain how to do this with the ~/.bash_aliases file, because it’s OS agnostic, aside from the different Google Chrome executable paths we’ll be using.

Let’s begin by opening the ~/.bash_aliases file. You can navigate to your home directory yourself, and open the file in your editor of choice, or like me, open the file from the terminal using vim by entering: vim ~/.bash_aliases

At the top of this file, dependent on OS, we’re going to add this line:

NOTE: This is where we expect Google Chrome to be installed on your system, you may have it installed it somewhere else. If you’re having any trouble, ensure the Chrome binaries are in the locations specified.


alias chrome=“C:/Program Files (x86)/Google/Chrome/Application/chrome.exe”


alias chrome="/Applications/Google\ Chrome.app/Contents/MacOS/Google\ Chrome"


alias chrome=":/opt/google/chrome"

Save the file, and that’s it! You can now launch Google Chrome, globally, from a new terminal instance, with the “chrome” alias we just added.

Getting Started

This is where the fun starts. We’re going to discuss the various ways of running and interacting with Google Chrome, and how we enable Headless Mode via the Google Chrome Switch.


If you’re using a desktop with a monitor, you can test launching Google Chrome from the CLI, using the alias we made, and firstly without Headless Mode enabled. To do this, simply open your terminal of choice and run this command:

$ chrome https://bugreplay.com

You should see a Google Chrome window appear which has opened our website BugReplay. This is the most simplest usage of Google Chrome from the CLI, to continue on from this, we’ll start adding arguments, or as Google has named them, Google Chrome Switches.

Headless Chrome Switches

There are many Google Chrome Switches, but for the purposes of this articles, we’ll focus purely on a few common Headless specific Google Chrome Switches, as documented here.


Changes the background color, in the case of recording the screen.


Enables crash reporting.


The path to save the crash reports to.


This forces network requests to complete in the order they were created.


Dumps dom to standard output.


Hides scrollbars, in the case of recording the screen.


Print the screen to a pdf.


Define a proxy server to use for requests.


This argument is ignored if the --proxy-server argument isn’t used as well. Here you can set a list of host, which we bypass proxy settings for. 


Runs a read-eval-print loop, that you can interact with to run Javascript on the page you’ve loaded. Try this!


Take a screenshot. It’ll be saved to the current working directory.


Define a timeout, e.g. --timeout=60


Define a custom user agent, e.g. --user-agent=”Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/60.0.3112.113 Safari/537.36” 


Override the default user data directory. If you wanted to store custom Google Chrome Profiles in an area different from the default user data directory, then this will be helpful to you.


Define a window size, e.g. --window-size=1024,768

Now we have a little bit of knowledge on some of the common Google Chrome Switches, we can start to do a few interesting things from the CLI with Google Chrome, and with Headless Mode enabled.

Dump DOM

This will print the page DOM to standard output, so you’ll see it appear in the terminal when you run it.

This output could easily be piped to a file using the tee command like so.

$ chrome --headless --disable-gpu --dump-dom https://bugreplay.com | tee dom.html

Save Screenshot

This will save a screenshot to the current working directory.

$ chrome --headless --disable-gpu --screenshot https://bugreplay.com

Save PDF

This will save a PDF to the current working directory.

$ chrome --headless --disable-gpu --print-to-pdf https://bugreplay.com

Wrapping Up

Starting from just CLI usage, you can already see how you can do some pretty powerful things with Google Chrome, outside of using it as a traditional browser. But when you get into the real meat of it, and use implementations of the DevTools Protocol, and the same for the WebDriver Protocol, the possibilities are quite literally, endless. Coupled with the added performance increase when running headlessly, then you can see how this is clearly the winner when it comes to browser automation in 2017.


I’ve already had a lot of fun working with Headless Chrome this year, and can be sure I’ll enjoy working on many more projects in the future. I hope that you’ve learned a thing or two, and of course, enjoyed the article overall.

Feel free to leave a comment in the section below, we’d love to hear from you.