DEV Community

Weather Clock Dash
Weather Clock Dash

Posted on

Firefox Browser Automation: Playwright, Selenium, and Headless Mode

Firefox supports browser automation via multiple tools — useful for testing, scraping, accessibility checks, and CI workflows. Here's a practical guide to each option.

Playwright (Recommended)

Playwright is the most actively developed cross-browser automation framework. It supports Chromium, Firefox (via Playwright's bundled Gecko), and WebKit.

npm install playwright
npx playwright install firefox
Enter fullscreen mode Exit fullscreen mode

Basic example:

const { firefox } = require('playwright');

(async () => {
  const browser = await firefox.launch({ headless: true });
  const page = await browser.newPage();

  await page.goto('https://example.com');
  const title = await page.title();
  console.log(title);

  await page.screenshot({ path: 'screenshot.png' });
  await browser.close();
})();
Enter fullscreen mode Exit fullscreen mode

Playwright advantages over older tools:

  • Built-in auto-wait (waits for elements to be ready before interacting)
  • Network interception API (intercept/mock HTTP requests)
  • Multiple contexts (test isolated browser sessions)
  • Trace viewer for debugging recorded runs
  • Good Firefox support

WebDriver / Selenium

Older standard. Firefox uses GeckoDriver as the WebDriver implementation.

npm install selenium-webdriver geckodriver
Enter fullscreen mode Exit fullscreen mode
const { Builder, By } = require('selenium-webdriver');
const firefox = require('selenium-webdriver/firefox');

const driver = new Builder()
  .forBrowser('firefox')
  .setFirefoxOptions(new firefox.Options().headless())
  .build();
Enter fullscreen mode Exit fullscreen mode

When to use Selenium: If you have existing Selenium tests you're maintaining, or if you need the WebDriver standard for compliance/cross-tool compatibility.

Firefox CDP (Chrome DevTools Protocol)

Firefox supports a subset of CDP (needed for compatibility with Chrome-targeted tools). This enables Playwright's Firefox support under the hood.

If you have existing Chrome automation using CDP, Firefox's CDP support may let you run it on Firefox with minimal changes.

Puppeteer with Firefox

Puppeteer recently added Firefox support (Puppeteer 22+, 2024):

npm install puppeteer
npx puppeteer browsers install firefox
Enter fullscreen mode Exit fullscreen mode
const puppeteer = require('puppeteer');

const browser = await puppeteer.launch({
  browser: 'firefox',
  headless: true
});
Enter fullscreen mode Exit fullscreen mode

Note: Puppeteer's Firefox support is newer and less battle-tested than Playwright's. Playwright is generally more reliable for Firefox automation.

Firefox Headless Mode (Direct CLI)

Firefox ships with native headless mode (no display required):

firefox --headless --screenshot output.png https://example.com
firefox --headless --window-size=1280,720 --screenshot output.png https://example.com
Enter fullscreen mode Exit fullscreen mode

For simple one-off screenshots, the CLI works without any npm dependencies.

Print to PDF:

firefox --headless --print-to-pdf output.pdf https://example.com
Enter fullscreen mode Exit fullscreen mode

Testing Extensions

To test a Firefox extension automatically with Playwright:

const { firefox } = require('playwright');
const path = require('path');

const extensionPath = path.resolve('./extension');

const context = await firefox.launchPersistentContext('', {
  headless: false, // Headless + extensions has limitations in some versions
  args: ['-wait-for-browser', '--load-extension=' + extensionPath]
});
Enter fullscreen mode Exit fullscreen mode

Note: Loading unpacked extensions in headless Firefox has limitations — behavior can differ from headed mode. Some extension testing requires headed mode.

CI/CD Integration

For running Firefox automation in CI (GitHub Actions, GitLab CI, etc.):

GitHub Actions:

- name: Install Firefox
  uses: browser-actions/setup-firefox@latest
  with:
    firefox-version: latest

- name: Run tests
  run: npx playwright test
  env:
    DISPLAY: ':99'  # Required if running headed tests on Linux
Enter fullscreen mode Exit fullscreen mode

Playwright's --headed mode in CI requires either a virtual display (Xvfb) or use of their built-in --headed Docker images.

Headless is simpler: For CI, use headless: true — no display server needed.

Firefox with Testing Profiles

Playwright and Selenium support using a custom Firefox profile, useful for pre-configured state (logged-in sessions, specific preferences):

// Playwright: use persistent context to maintain profile state
const context = await firefox.launchPersistentContext('./my-firefox-profile', {
  headless: true
});
Enter fullscreen mode Exit fullscreen mode

Useful Automation Patterns

Capturing CSRF tokens:

let csrfToken;
page.on('response', async res => {
  const text = await res.text().catch(() => '');
  const match = text.match(/name="csrf-token" content="([^"]+)"/);
  if (match) csrfToken = match[1];
});
Enter fullscreen mode Exit fullscreen mode

Network throttling:

// Playwright doesn't have built-in Firefox throttling,
// but you can use CDP:
const client = await page.context().newCDPSession(page);
await client.send('Network.emulateNetworkConditions', {
  downloadThroughput: 1.6e6 / 8, // 1.6 Mbps
  uploadThroughput: 750 * 1024 / 8,
  latency: 150
});
Enter fullscreen mode Exit fullscreen mode

For new projects: Playwright is the best starting point for Firefox automation. It's actively maintained, has excellent Firefox support, and the auto-wait feature alone prevents most flaky test issues.

Top comments (0)