Using Headless Mode in Firefox

If you know the ropes, good news! Firefox now has support for headless mode, making it easier to use as a backend to automated tools. You can jump ahead to learn how to use it.

Browser automation is not a new idea, but is an increasingly important part of how modern websites are built, tested, and deployed. Automation setups range from scripts run on local machines to vast deployments of specialized servers running in the cloud. To this end, browsers have long supported some level of automated control, usually via third-party driver software.

Browsers are at their core a user interface to the web, and a graphical user interface in particular. This poses a few problems for automation. In some environments, there may be no graphical display available, or it may be desirable to not have the browser appear at all when being controlled. This has required tools like virtual display software in order to run properly, adding complexity. More recently, tools like Lighthouse have packaged complex automated tests into a simple attractive package. They use the browser as a testing runtime, but there’s no need to display the browser window while the tests run.

For years, the best way to load webpages without displaying UI was PhantomJS, which is based on WebKit. While it remains a fantastic tool, it’s valuable to be able to run automated browser tests in official browsers, and so it’s valuable to have a headless mode available.

In June, Google shipped Chrome 59 featuring a headless mode, and Firefox has followed close behind with headless mode available on all platforms starting with version 56.

Using Firefox in Headless Mode

Launching Firefox in headless mode is simple enough. From the command line, simply add the -headless argument:

/path/to/firefox -headless

Great! Firefox is running in headless mode. How do you control it?

Right.

There are multiple options out there, many of which actually pre-date headless mode itself. Let’s review them!

Selenium/WebDriver

There’s a wealth of of information about selenium-webdriver testing on the MDN page for headless mode. Here’s a high-level overview.

Selenium is a venerable tool for browser automation, and it’s all the better with a headless browser. Writing a headless test is just as it was before, and there are some great libraries out there to make it easier. For instance, here is a basic node script to capture a screenshot of a webpage:

const { Builder } = require('selenium-webdriver');
const firefox = require('selenium-webdriver/firefox');
const fs = require('fs');

require('geckodriver');

async function capture(url) {
  const binary = new firefox.Binary(firefox.Channel.RELEASE);
  binary.addArguments('-headless'); // until newer webdriver ships

  const options = new firefox.Options();
  options.setBinary(binary);
  // options.headless(); once newer webdriver ships

  const driver = new Builder().forBrowser('firefox')
    .setFirefoxOptions(options).build();

  await driver.get(url);
  const data = await driver.takeScreenshot();
  fs.writeFileSync('./screenshot.png', data, 'base64');

  driver.quit();
}

capture('https://hacks.mozilla.org/');

Really the only difference when using headless mode is to make sure the right argument is passed.

That said, if you just need a screenshot of a webpage, that’s built in:

# -screenshot assumes -headless
firefox -screenshot https://hacks.mozilla.org/

# want to pick the resolution?
firefox -screenshot https://hacks.mozilla.org/ --window-size=480,1000

DevTools Debugging Protocol

Firefox has a debugging protocol that allows scripts to drive its DevTools from remotely. There are libraries such as node-firefox and foxdriver that use this protocol to remotely debug websites, fetch their logs, etc. For security reasons, the remote debugging protocol is not enabled by default, but can be enabled in preferences or from the command line:

/path/to/firefox --start-debugger-server 6000 -headless

In addition, the remote debugging protocol also speaks WebSockets! You can connect a webpage to a remote Firefox and drive it from there:

/path/to/firefox --start-debugger-server ws:6000 -headless

Learn (Lots) More!

This is an overview of what’s possible with headless Firefox and it’s the early days of support, but there’s already great information out there. In particular:

Happy scripting!

About Potch

Potch is a Web Platform Advocate at Mozilla.

More articles by Potch…


5 comments

  1. GP

    Are there plans to support Chrome’s remote debugging protocol? Firefox doesn’t figure in RemoteDebug’s compatibility table either.

    December 5th, 2017 at 18:52

    Reply

  2. Rick

    I’m wondering if you’d know the answer to a problem I suspect we may have using headless mode.

    If you want to do something like a WebRTC screen recording in FireFox, you have to give permission every time. In headless mode is there a way to essentially disable that security check entirely without having to see it once and click the ‘remember’ button? Presumably this works the same way as webcam / microphone access permissions.

    December 6th, 2017 at 01:01

    Reply

    1. Philipp Hancke

      Rick: setting media.navigator.permission.disabled to true allows screensharing without a prompt. Works great in combination with selenium.

      December 7th, 2017 at 01:04

      Reply

  3. Patrick

    Hi,

    headless Firefox looks awesome.

    Is there a way to make the background transparent?

    I’m trying to convert a SVG to a PNG and there are areas which are transparent, but the current screenshot feature is based on a white background.

    December 6th, 2017 at 02:51

    Reply

  4. Muhammad

    It would be nice to include a delay option/argument with screenshot.
    something like –delay Xms

    December 7th, 2017 at 09:12

    Reply

Post Your Comment