the Chromium logo

The Chromium Projects

Web Apps Testing on CrOS

This guide is the central starting point for running automated web tests on a CrOS Device or VM from a separate host machine. It covers the initial device setup, connection verification, and framework-specific configuration.

Typography Conventions

Commands are shown with different labels to indicate where they apply to:

  1. Your host machine (the machine on which you're doing development, e.g., Linux, macOS, or Windows).
  2. Your CrOS device or VM (the device on which you are testing your web apps).
Label Commands
(host) on your host machine
(device) on your CrOS device or VM

Beneath the label, the command(s) you should type are prefixed with a generic shell prompt, $. This distinguishes input from the output of commands.

Step 1: CrOS Device or VM Setup

This one-time setup configures your CrOS device to allow remote control of the browser. It is required to use a device or VM with at least CrOS version M141-16376.0.0.

Recommendation: Use a ChromiumOS VM Starting your testing with a ChromiumOS VM is highly recommended. This allows for faster iteration, easier debugging, and a more controlled environment. Follow the Running a Prebuilt ChromiumOS VM guide.

a. Enable Developer Mode

The device must be in Developer Mode. This will wipe all local data. Please refer to the official documentation for your specific device.

b. Remove Root File System (rootfs) Verification

To modify Chrome's startup flags, you must disable rootfs verification.

SECURITY WARNING: This reduces your device's security. Do not perform these actions on a device with sensitive information.

(device)

$ sudo /usr/share/vboot/bin/make_dev_ssd.sh \
  --remove_rootfs_verification --force && sudo reboot

After rebooting, remount the filesystem as read-write when you need to make changes:

(device)

$ sudo mount -o remount,rw /

c. Enable Chrome DevTools Remote Debugging

Start Chrome with the remote debugging port enabled by editing /etc/chrome_dev.conf.

(device)

$ export PORT=9222
$ echo "--remote-debugging-port=${PORT}" >> /etc/chrome_dev.conf

Reboot the device or restart the UI to apply the changes.

d. Establish and Verify SSH Tunnel

Create an SSH tunnel from your host to the device to forward the debugging port. This terminal window must remain open during testing.

(host)

$ export DEVICE_IP=<your_device_ip>
$ export PORT=9222
$ ssh -L ${PORT}:localhost:${PORT} root@${DEVICE_IP}

Verify the tunnel is working by running this command in a new terminal on your host:

(host)

$ curl http://localhost:${PORT}/json/version

A successful connection will return a JSON object with browser details.

Step 2: Verify Your Connection

Before configuring a specific framework, run a simple connection test to ensure your setup is working. This guide provides example scripts for both Puppeteer and Selenium.

Step 3: Host Machine Setup & Framework Configuration

This guide assumes you are already familiar with your chosen testing framework. The primary difference when testing on CrOS is how you connect to the browser. Instead of launching a new local instance, you connect to the remote browser via its debugging port.

a. Puppeteer

Instead of launching a new, local browser instance with puppeteer.launch(), you will connect to the existing browser on the remote device using puppeteer.connect(), targeting the remote debugging port that is forwarded through your SSH tunnel.

const browser = await puppeteer.connect({
  browserURL: `http://localhost:${PORT}`,
});

For complete installation and API details, refer to the official Puppeteer documentation.

b. Selenium WebDriver

Instead of having Selenium start a new, local browser instance, you will configure your WebDriver Options to connect to the existing browser on the remote device by setting the debuggerAddress. This targets the remote debugging port that is forwarded through your SSH tunnel.

options = Options()
options.add_experimental_option("debuggerAddress", f"127.0.0.1:{PORT}")
driver = webdriver.Chrome(service=service, options=options)

How WebDriver, ChromeDriver, and CDP Work Together

All communication with the browser happens via CDP. The key is understanding that chromedriver acts as a translator.

This flow is illustrated below:

+-----------------------------------------------------------+
| Host Machine                                              |
|                                                           |
| +-------------+  WebDriver  +-------------+  CDP Commands |
| | Test Script |-----------> | chromedriver|---+           |
| | (e.g. Py)   |  Commands   | (on Host)   |   |           |
| +-------------+             +-------------+   |           |
|  (High-Level)                (Translates)     |           |
+-----------------------------------------------v-----------+
                                                |
                                                | SSH Tunnel
                                                v
+-----------------------------------------------+-----------+
| CrOS Device                                   |           |
|                                    +----------v-------+   |
|                                    | Chrome Browser   |   |
|                                    | (receives CDP)   |   |
|                                    +------------------+   |
+-----------------------------------------------------------+

Download & Configure ChromeDriver

Because chromedriver must translate commands for a specific version of Chrome, it is crucial that its version matches the version of Chrome running on the CrOS device or VM.

  1. Get Chrome Version: Get the version from the device by either opening the chrome://version page in the browser or by running the following command on the device:

    (device)

    $ /opt/google/chrome/chrome --version
    

    You will get a version string like Google Chrome 144.0.7524.0.

  2. Download and Install ChromeDriver: Visit the Chrome for Testing Dashboard to find the matching driver for your Host OS (linux64, mac-x64, or win64). If an exact build match isn't available, download the latest available build for that Major version. You can either download it manually from the dashboard or use a command-line utility like curl.

    For example, to download version 144.0.7559.3 on Linux, you can use the following commands:

    (host)

    $ curl -o chromedriver.zip https://storage.googleapis.com/chrome-for-testing-public/144.0.7559.3/linux64/chromedriver-linux64.zip
    $ unzip chromedriver.zip
    $ mv chromedriver-linux64/chromedriver .
    $ chmod +x chromedriver
    

For more details, see the official Selenium documentation.

c. Playwright

Instead of launching a new, local browser instance with chromium.launch(), you will connect to the existing browser on the remote device using chromium.connectOverCDP(), targeting the remote debugging port that is forwarded through your SSH tunnel.

import { chromium } from 'playwright';

const browser = await chromium.connectOverCDP(`http://localhost:${PORT}`);

For complete installation and API details, refer to the official Playwright documentation.

Step 4: Explore Testing Scenarios

Now that you have configured your framework, you can explore task-specific testing guides that provide concrete examples for different scenarios.