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.
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.
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
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.
Windows
alias chrome=“C:/Program Files (x86)/Google/Chrome/Application/chrome.exe”
Mac
alias chrome="/Applications/Google\ Chrome.app/Contents/MacOS/Google\ Chrome"
Linux
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.
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.
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.
–default-background-color
Changes the background color, in the case of recording the screen.
–enable-crash-reporter
Enables crash reporting.
–crash-dumps-dir
The path to save the crash reports to.
–deterministic-fetch
This forces network requests to complete in the order they were created.
–dump-dom
Dumps dom to standard output.
–hide-scrollbars
Hides scrollbars, in the case of recording the screen.
–print-to-pdf
Print the screen to a pdf.
–proxy-server
Define a proxy server to use for requests.
–proxy-bypass-list
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.
–repl
Runs a read-eval-print loop, that you can interact with to run Javascript on the page you’ve loaded. Try this!
–screenshot
Take a screenshot. It’ll be saved to the current working directory.
–timeout
Define a timeout, e.g. --timeout=60
–user-agent
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”
–user-data-dir
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.
–window-size
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.
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
This will save a screenshot to the current working directory.
$ chrome --headless --disable-gpu --screenshot https://bugreplay.com
This will save a PDF to the current working directory.
$ chrome --headless --disable-gpu --print-to-pdf https://bugreplay.com
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.