Headless Testing Documentation

Headless testing significantly minimizes the time it takes to run a test. Because the browser runs in headless mode, it is not necessary to render the graphical user interface.

This means the browser starts faster and uses less resources, resulting in quicker test execution.

You can still take screenshots during headless mode. Video recording of the test however is not available in headless mode.

Chrome Headless Testing

To run headless tests on Chrome, simply set headless: true in tb:options. This tells TestingBot to launch the browser in headless mode and automatically disables video recording.

We recommend using the LINUX platform for the fastest headless testing experience.

import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.remote.RemoteWebDriver;
import java.net.URL;
import java.util.HashMap;
import java.util.Map;

public class HeadlessChromeTest {
    public static void main(String[] args) throws Exception {
        ChromeOptions chromeOptions = new ChromeOptions();
        chromeOptions.setPlatformName("LINUX");
        chromeOptions.setBrowserVersion("latest");

        Map<String, Object> tbOptions = new HashMap<>();
        tbOptions.put("key", "api_key");
        tbOptions.put("secret", "api_secret");
        tbOptions.put("name", "Chrome Headless Test");
        tbOptions.put("headless", true);

        chromeOptions.setCapability("tb:options", tbOptions);

        WebDriver driver = new RemoteWebDriver(
            new URL("https://hub.testingbot.com/wd/hub"),
            chromeOptions
        );

        driver.get("https://www.google.com");
        System.out.println("Title: " + driver.getTitle());
        driver.quit();
    }
}
from selenium import webdriver
from selenium.webdriver.chrome.options import Options

chrome_options = Options()
chrome_options.set_capability("platformName", "LINUX")
chrome_options.set_capability("browserVersion", "latest")
chrome_options.set_capability("tb:options", {
    "key": "api_key",
    "secret": "api_secret",
    "name": "Chrome Headless Test",
    "headless": True
})

driver = webdriver.Remote(
    command_executor="https://hub.testingbot.com/wd/hub",
    options=chrome_options
)

driver.get("https://www.google.com")
print("Title:", driver.title)
driver.quit()
const { Builder } = require('selenium-webdriver');

async function runHeadlessTest() {
    const driver = await new Builder()
        .forBrowser('chrome')
        .withCapabilities({
            'browserName': 'chrome',
            'browserVersion': 'latest',
            'platformName': 'LINUX',
            'tb:options': {
                'key': 'api_key',
                'secret': 'api_secret',
                'name': 'Chrome Headless Test',
                'headless': true
            }
        })
        .usingServer('https://hub.testingbot.com/wd/hub')
        .build();

    try {
        await driver.get('https://www.google.com');
        const title = await driver.getTitle();
        console.log('Title:', title);
    } finally {
        await driver.quit();
    }
}

runHeadlessTest();
// wdio.conf.js
exports.config = {
    user: 'api_key',
    key: 'api_secret',

    capabilities: [{
        browserName: 'chrome',
        browserVersion: 'latest',
        platformName: 'LINUX',
        'tb:options': {
            name: 'Chrome Headless Test',
            headless: true
        }
    }],

    services: [['testingbot']],

    // Your test configuration
    specs: ['./test/specs/**/*.js'],
    framework: 'mocha',
    reporters: ['spec']
};

// test/specs/example.js
describe('Headless Chrome Test', () => {
    it('should load Google', async () => {
        await browser.url('https://www.google.com');
        const title = await browser.getTitle();
        console.log('Title:', title);
    });
});
require 'selenium-webdriver'

options = Selenium::WebDriver::Chrome::Options.new
options.platform_name = 'LINUX'
options.browser_version = 'latest'

caps = Selenium::WebDriver::Remote::Capabilities.new(
  'tb:options': {
    key: 'api_key',
    secret: 'api_secret',
    name: 'Chrome Headless Test',
    headless: true
  }
)

driver = Selenium::WebDriver.for(
  :remote,
  url: 'https://hub.testingbot.com/wd/hub',
  capabilities: [options, caps]
)

driver.get('https://www.google.com')
puts "Title: #{driver.title}"
driver.quit
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;
using OpenQA.Selenium.Remote;

var chromeOptions = new ChromeOptions();
chromeOptions.PlatformName = "LINUX";
chromeOptions.BrowserVersion = "latest";

var tbOptions = new Dictionary<string, object>
{
    ["key"] = "api_key",
    ["secret"] = "api_secret",
    ["name"] = "Chrome Headless Test",
    ["headless"] = true
};

chromeOptions.AddAdditionalOption("tb:options", tbOptions);

IWebDriver driver = new RemoteWebDriver(
    new Uri("https://hub.testingbot.com/wd/hub"),
    chromeOptions.ToCapabilities(),
    TimeSpan.FromSeconds(600)
);

driver.Navigate().GoToUrl("https://www.google.com");
Console.WriteLine("Title: " + driver.Title);
driver.Quit();
<?php
require_once('vendor/autoload.php');

use Facebook\WebDriver\Remote\RemoteWebDriver;
use Facebook\WebDriver\Remote\DesiredCapabilities;

$capabilities = DesiredCapabilities::chrome();
$capabilities->setCapability('browserVersion', 'latest');
$capabilities->setCapability('platformName', 'LINUX');
$capabilities->setCapability('tb:options', [
    'key' => 'api_key',
    'secret' => 'api_secret',
    'name' => 'Chrome Headless Test',
    'headless' => true
]);

$driver = RemoteWebDriver::create(
    'https://hub.testingbot.com/wd/hub',
    $capabilities,
    60000,
    60000
);

$driver->get('https://www.google.com');
echo "Title: " . $driver->getTitle() . "\n";
$driver->quit();
?>

Save the example below in a headless_chrome.robot file:

*** Settings ***
Library    SeleniumLibrary
Library    TestingBot
Library    Collections

Test Setup    Open Headless Chrome Browser
Test Teardown    Close Test Browser

*** Variables ***
${TB_KEY}       api_key
${TB_SECRET}    api_secret

*** Test Cases ***
Chrome Headless Test
    Go To    https://www.google.com
    Title Should Be    Google

*** Keywords ***
Open Headless Chrome Browser
    ${chrome_options}=    Evaluate    selenium.webdriver.ChromeOptions()    modules=selenium.webdriver

    # Set W3C capabilities
    Call Method    ${chrome_options}    set_capability    platformName    LINUX
    Call Method    ${chrome_options}    set_capability    browserVersion    latest

    # Set TestingBot options with headless enabled
    ${tb_options}=    Create Dictionary    name=Chrome Headless Test    headless=${True}
    Call Method    ${chrome_options}    set_capability    tb:options    ${tb_options}

    Open Browser    about:blank
    ...    remote_url=https://${TB_KEY}:${TB_SECRET}@hub.testingbot.com/wd/hub
    ...    options=${chrome_options}

Close Test Browser
    Report TestingBot Status
    ...    ${SUITE_NAME} | ${TEST_NAME}
    ...    ${TEST_STATUS}
    ...    ${TB_KEY}:${TB_SECRET}
    Close All Browsers

Save the code below in a TestingBot.py file:

import requests
from robot.libraries.BuiltIn import BuiltIn

def report_testingbot_status(name, status, credentials):
    selenium = BuiltIn().get_library_instance('SeleniumLibrary')
    session_id = selenium.driver.session_id

    payload = {'test[name]': name, 'test[success]': int(status == 'PASS')}
    key, secret = credentials.split(':')

    url = 'https://api.testingbot.com/v1/tests/{0}'.format(session_id)
    response = requests.put(url, data=payload, auth=(key, secret))
    assert response.status_code == 200, response.text

To run the test:

pip install robotframework-seleniumlibrary requests
PYTHONPATH=$PYTHONPATH:. robot headless_chrome.robot

Firefox Headless Testing

To run headless tests on Firefox, simply set headless: true in tb:options. This tells TestingBot to launch the browser in headless mode and automatically disables video recording.

import org.openqa.selenium.WebDriver;
import org.openqa.selenium.firefox.FirefoxOptions;
import org.openqa.selenium.remote.RemoteWebDriver;
import java.net.URL;
import java.util.HashMap;
import java.util.Map;

public class HeadlessFirefoxTest {
    public static void main(String[] args) throws Exception {
        FirefoxOptions firefoxOptions = new FirefoxOptions();
        firefoxOptions.setPlatformName("LINUX");
        firefoxOptions.setBrowserVersion("latest");

        Map<String, Object> tbOptions = new HashMap<>();
        tbOptions.put("key", "api_key");
        tbOptions.put("secret", "api_secret");
        tbOptions.put("name", "Firefox Headless Test");
        tbOptions.put("headless", true);

        firefoxOptions.setCapability("tb:options", tbOptions);

        WebDriver driver = new RemoteWebDriver(
            new URL("https://hub.testingbot.com/wd/hub"),
            firefoxOptions
        );

        driver.get("https://www.google.com");
        System.out.println("Title: " + driver.getTitle());
        driver.quit();
    }
}
from selenium import webdriver
from selenium.webdriver.firefox.options import Options

firefox_options = Options()
firefox_options.set_capability("platformName", "LINUX")
firefox_options.set_capability("browserVersion", "latest")
firefox_options.set_capability("tb:options", {
    "key": "api_key",
    "secret": "api_secret",
    "name": "Firefox Headless Test",
    "headless": True
})

driver = webdriver.Remote(
    command_executor="https://hub.testingbot.com/wd/hub",
    options=firefox_options
)

driver.get("https://www.google.com")
print("Title:", driver.title)
driver.quit()
const { Builder } = require('selenium-webdriver');

async function runHeadlessTest() {
    const driver = await new Builder()
        .forBrowser('firefox')
        .withCapabilities({
            'browserName': 'firefox',
            'browserVersion': 'latest',
            'platformName': 'LINUX',
            'tb:options': {
                'key': 'api_key',
                'secret': 'api_secret',
                'name': 'Firefox Headless Test',
                'headless': true
            }
        })
        .usingServer('https://hub.testingbot.com/wd/hub')
        .build();

    try {
        await driver.get('https://www.google.com');
        const title = await driver.getTitle();
        console.log('Title:', title);
    } finally {
        await driver.quit();
    }
}

runHeadlessTest();
// wdio.conf.js
exports.config = {
    user: 'api_key',
    key: 'api_secret',

    capabilities: [{
        browserName: 'firefox',
        browserVersion: 'latest',
        platformName: 'LINUX',
        'tb:options': {
            name: 'Firefox Headless Test',
            headless: true
        }
    }],

    services: [['testingbot']],

    // Your test configuration
    specs: ['./test/specs/**/*.js'],
    framework: 'mocha',
    reporters: ['spec']
};

// test/specs/example.js
describe('Headless Firefox Test', () => {
    it('should load Google', async () => {
        await browser.url('https://www.google.com');
        const title = await browser.getTitle();
        console.log('Title:', title);
    });
});
require 'selenium-webdriver'

options = Selenium::WebDriver::Firefox::Options.new
options.platform_name = 'LINUX'
options.browser_version = 'latest'

caps = Selenium::WebDriver::Remote::Capabilities.new(
  'tb:options': {
    key: 'api_key',
    secret: 'api_secret',
    name: 'Firefox Headless Test',
    headless: true
  }
)

driver = Selenium::WebDriver.for(
  :remote,
  url: 'https://hub.testingbot.com/wd/hub',
  capabilities: [options, caps]
)

driver.get('https://www.google.com')
puts "Title: #{driver.title}"
driver.quit
using OpenQA.Selenium;
using OpenQA.Selenium.Firefox;
using OpenQA.Selenium.Remote;

var firefoxOptions = new FirefoxOptions();
firefoxOptions.PlatformName = "LINUX";
firefoxOptions.BrowserVersion = "latest";

var tbOptions = new Dictionary<string, object>
{
    ["key"] = "api_key",
    ["secret"] = "api_secret",
    ["name"] = "Firefox Headless Test",
    ["headless"] = true
};

firefoxOptions.AddAdditionalOption("tb:options", tbOptions);

IWebDriver driver = new RemoteWebDriver(
    new Uri("https://hub.testingbot.com/wd/hub"),
    firefoxOptions.ToCapabilities(),
    TimeSpan.FromSeconds(600)
);

driver.Navigate().GoToUrl("https://www.google.com");
Console.WriteLine("Title: " + driver.Title);
driver.Quit();
<?php
require_once('vendor/autoload.php');

use Facebook\WebDriver\Remote\RemoteWebDriver;
use Facebook\WebDriver\Remote\DesiredCapabilities;

$capabilities = DesiredCapabilities::firefox();
$capabilities->setCapability('browserVersion', 'latest');
$capabilities->setCapability('platformName', 'LINUX');
$capabilities->setCapability('tb:options', [
    'key' => 'api_key',
    'secret' => 'api_secret',
    'name' => 'Firefox Headless Test',
    'headless' => true
]);

$driver = RemoteWebDriver::create(
    'https://hub.testingbot.com/wd/hub',
    $capabilities,
    60000,
    60000
);

$driver->get('https://www.google.com');
echo "Title: " . $driver->getTitle() . "\n";
$driver->quit();
?>

Save the example below in a headless_firefox.robot file:

*** Settings ***
Library    SeleniumLibrary
Library    TestingBot
Library    Collections

Test Setup    Open Headless Firefox Browser
Test Teardown    Close Test Browser

*** Variables ***
${TB_KEY}       api_key
${TB_SECRET}    api_secret

*** Test Cases ***
Firefox Headless Test
    Go To    https://www.google.com
    Title Should Be    Google

*** Keywords ***
Open Headless Firefox Browser
    ${firefox_options}=    Evaluate    selenium.webdriver.FirefoxOptions()    modules=selenium.webdriver

    # Set W3C capabilities
    Call Method    ${firefox_options}    set_capability    platformName    LINUX
    Call Method    ${firefox_options}    set_capability    browserVersion    latest

    # Set TestingBot options with headless enabled
    ${tb_options}=    Create Dictionary    name=Firefox Headless Test    headless=${True}
    Call Method    ${firefox_options}    set_capability    tb:options    ${tb_options}

    Open Browser    about:blank
    ...    remote_url=https://${TB_KEY}:${TB_SECRET}@hub.testingbot.com/wd/hub
    ...    options=${firefox_options}

Close Test Browser
    Report TestingBot Status
    ...    ${SUITE_NAME} | ${TEST_NAME}
    ...    ${TEST_STATUS}
    ...    ${TB_KEY}:${TB_SECRET}
    Close All Browsers

Save the code below in a TestingBot.py file:

import requests
from robot.libraries.BuiltIn import BuiltIn

def report_testingbot_status(name, status, credentials):
    selenium = BuiltIn().get_library_instance('SeleniumLibrary')
    session_id = selenium.driver.session_id

    payload = {'test[name]': name, 'test[success]': int(status == 'PASS')}
    key, secret = credentials.split(':')

    url = 'https://api.testingbot.com/v1/tests/{0}'.format(session_id)
    response = requests.put(url, data=payload, auth=(key, secret))
    assert response.status_code == 200, response.text

To run the test:

pip install robotframework-seleniumlibrary requests
PYTHONPATH=$PYTHONPATH:. robot headless_firefox.robot

Microsoft Edge Headless Testing

To run headless tests on Microsoft Edge, simply set headless: true in tb:options. This tells TestingBot to launch the browser in headless mode and automatically disables video recording.

We recommend using the WIN11 or WIN10 platform for Edge headless testing.

import org.openqa.selenium.WebDriver;
import org.openqa.selenium.edge.EdgeOptions;
import org.openqa.selenium.remote.RemoteWebDriver;
import java.net.URL;
import java.util.HashMap;
import java.util.Map;

public class HeadlessEdgeTest {
    public static void main(String[] args) throws Exception {
        EdgeOptions edgeOptions = new EdgeOptions();
        edgeOptions.setPlatformName("WIN11");
        edgeOptions.setBrowserVersion("latest");

        Map<String, Object> tbOptions = new HashMap<>();
        tbOptions.put("key", "api_key");
        tbOptions.put("secret", "api_secret");
        tbOptions.put("name", "Edge Headless Test");
        tbOptions.put("headless", true);

        edgeOptions.setCapability("tb:options", tbOptions);

        WebDriver driver = new RemoteWebDriver(
            new URL("https://hub.testingbot.com/wd/hub"),
            edgeOptions
        );

        driver.get("https://www.google.com");
        System.out.println("Title: " + driver.getTitle());
        driver.quit();
    }
}
from selenium import webdriver
from selenium.webdriver.edge.options import Options

edge_options = Options()
edge_options.set_capability("platformName", "WIN11")
edge_options.set_capability("browserVersion", "latest")
edge_options.set_capability("tb:options", {
    "key": "api_key",
    "secret": "api_secret",
    "name": "Edge Headless Test",
    "headless": True
})

driver = webdriver.Remote(
    command_executor="https://hub.testingbot.com/wd/hub",
    options=edge_options
)

driver.get("https://www.google.com")
print("Title:", driver.title)
driver.quit()
const { Builder } = require('selenium-webdriver');

async function runHeadlessTest() {
    const driver = await new Builder()
        .forBrowser('MicrosoftEdge')
        .withCapabilities({
            'browserName': 'MicrosoftEdge',
            'browserVersion': 'latest',
            'platformName': 'WIN11',
            'tb:options': {
                'key': 'api_key',
                'secret': 'api_secret',
                'name': 'Edge Headless Test',
                'headless': true
            }
        })
        .usingServer('https://hub.testingbot.com/wd/hub')
        .build();

    try {
        await driver.get('https://www.google.com');
        const title = await driver.getTitle();
        console.log('Title:', title);
    } finally {
        await driver.quit();
    }
}

runHeadlessTest();
// wdio.conf.js
exports.config = {
    user: 'api_key',
    key: 'api_secret',

    capabilities: [{
        browserName: 'MicrosoftEdge',
        browserVersion: 'latest',
        platformName: 'WIN11',
        'tb:options': {
            name: 'Edge Headless Test',
            headless: true
        }
    }],

    services: [['testingbot']],

    // Your test configuration
    specs: ['./test/specs/**/*.js'],
    framework: 'mocha',
    reporters: ['spec']
};

// test/specs/example.js
describe('Headless Edge Test', () => {
    it('should load Google', async () => {
        await browser.url('https://www.google.com');
        const title = await browser.getTitle();
        console.log('Title:', title);
    });
});
require 'selenium-webdriver'

options = Selenium::WebDriver::Edge::Options.new
options.platform_name = 'WIN11'
options.browser_version = 'latest'

caps = Selenium::WebDriver::Remote::Capabilities.new(
  'tb:options': {
    key: 'api_key',
    secret: 'api_secret',
    name: 'Edge Headless Test',
    headless: true
  }
)

driver = Selenium::WebDriver.for(
  :remote,
  url: 'https://hub.testingbot.com/wd/hub',
  capabilities: [options, caps]
)

driver.get('https://www.google.com')
puts "Title: #{driver.title}"
driver.quit
using OpenQA.Selenium;
using OpenQA.Selenium.Edge;
using OpenQA.Selenium.Remote;

var edgeOptions = new EdgeOptions();
edgeOptions.PlatformName = "WIN11";
edgeOptions.BrowserVersion = "latest";

var tbOptions = new Dictionary<string, object>
{
    ["key"] = "api_key",
    ["secret"] = "api_secret",
    ["name"] = "Edge Headless Test",
    ["headless"] = true
};

edgeOptions.AddAdditionalOption("tb:options", tbOptions);

IWebDriver driver = new RemoteWebDriver(
    new Uri("https://hub.testingbot.com/wd/hub"),
    edgeOptions.ToCapabilities(),
    TimeSpan.FromSeconds(600)
);

driver.Navigate().GoToUrl("https://www.google.com");
Console.WriteLine("Title: " + driver.Title);
driver.Quit();
<?php
require_once('vendor/autoload.php');

use Facebook\WebDriver\Remote\RemoteWebDriver;
use Facebook\WebDriver\Remote\DesiredCapabilities;

$capabilities = DesiredCapabilities::microsoftEdge();
$capabilities->setCapability('browserVersion', 'latest');
$capabilities->setCapability('platformName', 'WIN11');
$capabilities->setCapability('tb:options', [
    'key' => 'api_key',
    'secret' => 'api_secret',
    'name' => 'Edge Headless Test',
    'headless' => true
]);

$driver = RemoteWebDriver::create(
    'https://hub.testingbot.com/wd/hub',
    $capabilities,
    60000,
    60000
);

$driver->get('https://www.google.com');
echo "Title: " . $driver->getTitle() . "\n";
$driver->quit();
?>

Save the example below in a headless_edge.robot file:

*** Settings ***
Library    SeleniumLibrary
Library    TestingBot
Library    Collections

Test Setup    Open Headless Edge Browser
Test Teardown    Close Test Browser

*** Variables ***
${TB_KEY}       api_key
${TB_SECRET}    api_secret

*** Test Cases ***
Edge Headless Test
    Go To    https://www.google.com
    Title Should Be    Google

*** Keywords ***
Open Headless Edge Browser
    ${edge_options}=    Evaluate    selenium.webdriver.EdgeOptions()    modules=selenium.webdriver

    # Set W3C capabilities
    Call Method    ${edge_options}    set_capability    platformName    WIN11
    Call Method    ${edge_options}    set_capability    browserVersion    latest

    # Set TestingBot options with headless enabled
    ${tb_options}=    Create Dictionary    name=Edge Headless Test    headless=${True}
    Call Method    ${edge_options}    set_capability    tb:options    ${tb_options}

    Open Browser    about:blank
    ...    remote_url=https://${TB_KEY}:${TB_SECRET}@hub.testingbot.com/wd/hub
    ...    options=${edge_options}

Close Test Browser
    Report TestingBot Status
    ...    ${SUITE_NAME} | ${TEST_NAME}
    ...    ${TEST_STATUS}
    ...    ${TB_KEY}:${TB_SECRET}
    Close All Browsers

Save the code below in a TestingBot.py file:

import requests
from robot.libraries.BuiltIn import BuiltIn

def report_testingbot_status(name, status, credentials):
    selenium = BuiltIn().get_library_instance('SeleniumLibrary')
    session_id = selenium.driver.session_id

    payload = {'test[name]': name, 'test[success]': int(status == 'PASS')}
    key, secret = credentials.split(':')

    url = 'https://api.testingbot.com/v1/tests/{0}'.format(session_id)
    response = requests.put(url, data=payload, auth=(key, secret))
    assert response.status_code == 200, response.text

To run the test:

pip install robotframework-seleniumlibrary requests
PYTHONPATH=$PYTHONPATH:. robot headless_edge.robot

Safari Headless Testing

Safari does not support headless mode. Apple has not implemented headless functionality in Safari or the SafariDriver.

If you need to run Safari tests, they will always run in headed (visible) mode. For headless testing requirements, consider using Chrome, Firefox or Edge as alternatives.

At TestingBot we run all Safari 17 and higher versions on Apple Silicon for maximum performance.

Mobile Headless Testing

TestingBot uses Appium to run mobile tests. Appium supports running your iOS and Android tests in headless mode (no screen rendering).

To enable headless mode for mobile testing, specify the isHeadless capability in your test configuration.

iOS Headless Testing

import io.appium.java_client.ios.IOSDriver;
import io.appium.java_client.ios.options.XCUITestOptions;
import java.net.URL;
import java.util.HashMap;
import java.util.Map;

public class HeadlessIOSTest {
    public static void main(String[] args) throws Exception {
        XCUITestOptions options = new XCUITestOptions();
        options.setPlatformName("iOS");
        options.setPlatformVersion("18.0");
        options.setDeviceName("iPhone 16");
        options.setBrowserName("safari");
        options.setCapability("appium:isHeadless", true);

        Map<String, Object> tbOptions = new HashMap<>();
        tbOptions.put("key", "api_key");
        tbOptions.put("secret", "api_secret");
        tbOptions.put("name", "iOS Headless Test");

        options.setCapability("tb:options", tbOptions);

        IOSDriver driver = new IOSDriver(
            new URL("https://hub.testingbot.com/wd/hub"),
            options
        );

        driver.get("https://www.google.com");
        System.out.println("Title: " + driver.getTitle());
        driver.quit();
    }
}
from appium import webdriver
from appium.options.ios import XCUITestOptions

options = XCUITestOptions()
options.platform_name = "iOS"
options.platform_version = "18.0"
options.device_name = "iPhone 16"
options.browser_name = "safari"
options.set_capability("appium:isHeadless", True)
options.set_capability("tb:options", {
    "key": "api_key",
    "secret": "api_secret",
    "name": "iOS Headless Test"
})

driver = webdriver.Remote(
    command_executor="https://hub.testingbot.com/wd/hub",
    options=options
)

driver.get("https://www.google.com")
print("Title:", driver.title)
driver.quit()
const { remote } = require('webdriverio');

async function runHeadlessIOSTest() {
    const driver = await remote({
        hostname: 'hub.testingbot.com',
        port: 443,
        path: '/wd/hub',
        protocol: 'https',
        capabilities: {
            'platformName': 'iOS',
            'appium:platformVersion': '18.0',
            'appium:deviceName': 'iPhone 16',
            'browserName': 'safari',
            'appium:isHeadless': true,
            'tb:options': {
                'key': 'api_key',
                'secret': 'api_secret',
                'name': 'iOS Headless Test'
            }
        }
    });

    await driver.url('https://www.google.com');
    const title = await driver.getTitle();
    console.log('Title:', title);
    await driver.deleteSession();
}

runHeadlessIOSTest();
require 'appium_lib'

caps = {
  platformName: 'iOS',
  'appium:platformVersion': '18.0',
  'appium:deviceName': 'iPhone 16',
  browserName: 'safari',
  'appium:isHeadless': true,
  'tb:options': {
    key: 'api_key',
    secret: 'api_secret',
    name: 'iOS Headless Test'
  }
}

opts = {
  caps: caps,
  appium_lib: {
    server_url: 'https://hub.testingbot.com/wd/hub'
  }
}

driver = Appium::Driver.new(opts, true)
driver.start_driver

driver.get('https://www.google.com')
puts "Title: #{driver.title}"
driver.quit
using OpenQA.Selenium.Appium;
using OpenQA.Selenium.Appium.iOS;

var options = new AppiumOptions();
options.PlatformName = "iOS";
options.AddAdditionalAppiumOption("appium:platformVersion", "18.0");
options.AddAdditionalAppiumOption("appium:deviceName", "iPhone 16");
options.AddAdditionalAppiumOption("browserName", "safari");
options.AddAdditionalAppiumOption("appium:isHeadless", true);

var tbOptions = new Dictionary<string, object>
{
    ["key"] = "api_key",
    ["secret"] = "api_secret",
    ["name"] = "iOS Headless Test"
};

options.AddAdditionalAppiumOption("tb:options", tbOptions);

var driver = new IOSDriver(
    new Uri("https://hub.testingbot.com/wd/hub"),
    options,
    TimeSpan.FromSeconds(600)
);

driver.Navigate().GoToUrl("https://www.google.com");
Console.WriteLine("Title: " + driver.Title);
driver.Quit();

Android Headless Testing

import io.appium.java_client.android.AndroidDriver;
import io.appium.java_client.android.options.UiAutomator2Options;
import java.net.URL;
import java.util.HashMap;
import java.util.Map;

public class HeadlessAndroidTest {
    public static void main(String[] args) throws Exception {
        UiAutomator2Options options = new UiAutomator2Options();
        options.setPlatformName("Android");
        options.setPlatformVersion("14.0");
        options.setDeviceName("Pixel 8");
        options.setBrowserName("chrome");
        options.setCapability("appium:isHeadless", true);

        Map<String, Object> tbOptions = new HashMap<>();
        tbOptions.put("key", "api_key");
        tbOptions.put("secret", "api_secret");
        tbOptions.put("name", "Android Headless Test");

        options.setCapability("tb:options", tbOptions);

        AndroidDriver driver = new AndroidDriver(
            new URL("https://hub.testingbot.com/wd/hub"),
            options
        );

        driver.get("https://www.google.com");
        System.out.println("Title: " + driver.getTitle());
        driver.quit();
    }
}
from appium import webdriver
from appium.options.android import UiAutomator2Options

options = UiAutomator2Options()
options.platform_name = "Android"
options.platform_version = "14.0"
options.device_name = "Pixel 8"
options.browser_name = "chrome"
options.set_capability("appium:isHeadless", True)
options.set_capability("tb:options", {
    "key": "api_key",
    "secret": "api_secret",
    "name": "Android Headless Test"
})

driver = webdriver.Remote(
    command_executor="https://hub.testingbot.com/wd/hub",
    options=options
)

driver.get("https://www.google.com")
print("Title:", driver.title)
driver.quit()
const { remote } = require('webdriverio');

async function runHeadlessAndroidTest() {
    const driver = await remote({
        hostname: 'hub.testingbot.com',
        port: 443,
        path: '/wd/hub',
        protocol: 'https',
        capabilities: {
            'platformName': 'Android',
            'appium:platformVersion': '14.0',
            'appium:deviceName': 'Pixel 8',
            'browserName': 'chrome',
            'appium:isHeadless': true,
            'tb:options': {
                'key': 'api_key',
                'secret': 'api_secret',
                'name': 'Android Headless Test'
            }
        }
    });

    await driver.url('https://www.google.com');
    const title = await driver.getTitle();
    console.log('Title:', title);
    await driver.deleteSession();
}

runHeadlessAndroidTest();
require 'appium_lib'

caps = {
  platformName: 'Android',
  'appium:platformVersion': '14.0',
  'appium:deviceName': 'Pixel 8',
  browserName: 'chrome',
  'appium:isHeadless': true,
  'tb:options': {
    key: 'api_key',
    secret: 'api_secret',
    name: 'Android Headless Test'
  }
}

opts = {
  caps: caps,
  appium_lib: {
    server_url: 'https://hub.testingbot.com/wd/hub'
  }
}

driver = Appium::Driver.new(opts, true)
driver.start_driver

driver.get('https://www.google.com')
puts "Title: #{driver.title}"
driver.quit
using OpenQA.Selenium.Appium;
using OpenQA.Selenium.Appium.Android;

var options = new AppiumOptions();
options.PlatformName = "Android";
options.AddAdditionalAppiumOption("appium:platformVersion", "14.0");
options.AddAdditionalAppiumOption("appium:deviceName", "Pixel 8");
options.AddAdditionalAppiumOption("browserName", "chrome");
options.AddAdditionalAppiumOption("appium:isHeadless", true);

var tbOptions = new Dictionary<string, object>
{
    ["key"] = "api_key",
    ["secret"] = "api_secret",
    ["name"] = "Android Headless Test"
};

options.AddAdditionalAppiumOption("tb:options", tbOptions);

var driver = new AndroidDriver(
    new Uri("https://hub.testingbot.com/wd/hub"),
    options,
    TimeSpan.FromSeconds(600)
);

driver.Navigate().GoToUrl("https://www.google.com");
Console.WriteLine("Title: " + driver.Title);
driver.Quit();

Benefits of Headless Testing

  • Faster Test Execution: Without rendering the UI, tests start and complete more quickly.
  • Lower Resource Usage: Headless browsers consume less memory and CPU.
  • Ideal for CI/CD: Perfect for automated pipelines where visual output is not needed.
  • Screenshots Supported: You can still capture screenshots during headless tests.

Limitations

  • No Video Recording: Video recording is not available during headless tests.
  • Debugging: Debugging can be more challenging without seeing the browser UI.

For debugging purposes, we recommend switching to headed mode temporarily to visually inspect the browser during test execution.

Was this page helpful?

Looking for More Help?

Have questions or need more information?
You can reach us via the following channels: