Skip to content

Selenium quickstart

A MaxoPerf fleet speaks the W3C WebDriver protocol, so any Selenium client connects after a one-URL swap. Replace your grid’s command_executor / server URL with the fleet’s WebDriver endpoint. Choose the browser with the standard browserName capability (ChromeOptions, FirefoxOptions, EdgeOptions).

Get started with browser fleets.
  • A running fleet with at least one chrome, firefox, or edge browser. Create one from the console, an AI agent, or the REST API below.
  • The fleet’s connection token (mpft_…) or an account API key (mpak_…).

Connect a client covers the same ground for every protocol: endpoint shapes, where credentials go, and how a fleet’s protocols relate.

Selenium clients pass credentials as basic auth in the URL. The fleet id is the username and the token is the password:

https://<fleetId>:<token>@app.maxoperf.com/browser-fleets/<fleetId>/wd/hub

Any mpak_… account key with access to the fleet works in the password position too.

Both halves of that URL come from the fleet's Connect tab: the fleet id for the username, and the connection token (masked until you reveal it) for the password.
# pip install selenium
from selenium import webdriver
from selenium.webdriver.chrome.options import Options as ChromeOptions
driver = webdriver.Remote(
command_executor="https://flt-a1b2c3d4e5:mpft_example_token@app.maxoperf.com/browser-fleets/flt-a1b2c3d4e5/wd/hub",
options=ChromeOptions(), # or FirefoxOptions() / EdgeOptions()
)
driver.get("https://example.com")
print(driver.title)
driver.quit()

Replace flt-a1b2c3d4e5 with your fleet id and mpft_example_token with your token.

The browserName capability decides which fleet browser you get. Swap the options object per language:

  • chrome: ChromeOptions (Python/Java) or .forBrowser('chrome') (JS)
  • firefox: FirefoxOptions or .forBrowser('firefox')
  • edge: EdgeOptions or .forBrowser('MicrosoftEdge')

Ask for a WebDriver BiDi session with webSocketUrl: true on chrome, edge or firefox — the session only gets a BiDi endpoint back when it asks. Chrome/Edge sessions also get Selenium’s automatic browser-level se:cdp capability, no extra request needed:

// npm i selenium-webdriver
const { Builder } = require('selenium-webdriver');
const driver = await new Builder()
.usingServer('https://app.maxoperf.com/browser-fleets/flt-a1b2c3d4e5/wd/hub')
.withCapabilities({
browserName: 'firefox',
webSocketUrl: true,
'maxoperf:options': { token: 'mpft_example_token', name: 'checkout' },
})
.build();
const bidi = await driver.getBidi(); // live WebSocket to this session's BiDi endpoint

maxoperf:options.name (or se:name) names the session so it shows up labeled on the fleet’s Sessions tab. See Connect a client for the full se:cdp snippet.

To script fleet creation instead of using the console, call POST /v1/fleets with a JWT or an mpak_… API key. Request browsers by count and location, and optionally set how many browsers pack onto each runner, a lifetime, and an idle timeout:

Terminal window
curl -X POST https://app.maxoperf.com/v1/fleets \
-H "Authorization: Bearer mpak_example_key" \
-H "X-Account-Id: acn-1234567890" \
-H "Content-Type: application/json" \
-d '{
"name": "nightly-eu-grid",
"browsers": [
{ "browser": "chrome", "count": 5, "location": "aws:us-east-1" },
{ "browser": "firefox", "count": 3, "location": "gcp:europe-west1" },
{ "browser": "edge", "count": 2, "location": "aws:us-east-1" }
],
"browsersPerRunner": 5,
"ttlMinutes": 120,
"idleTimeoutMinutes": 15,
"stepCapture": true
}'

stepCapture (default true) turns interaction-step capture on or off for every session on the fleet; set it false for anti-bot pages or a strict content-security policy. Changing it later (PATCH /v1/fleets/<fleetId>, or the Configuration tab in the console) applies from the fleet’s next Start — it never touches sessions already running.

The 201 response carries the fleet id, the run it created, every endpoint, the connection token, and the supported Playwright minors. This is the only response that returns the token inline. Retrieve it later with GET /v1/fleets/<fleetId>/token. The create response looks like this:

{
"fleetId": "flt-a1b2c3d4e5",
"runId": "run-9f8e7d6c5b",
"status": "allocating",
"endpoints": {
"webdriver": "https://app.maxoperf.com/browser-fleets/flt-a1b2c3d4e5/wd/hub",
"playwright": {
"chromium": "wss://app.maxoperf.com/browser-fleets/flt-a1b2c3d4e5/playwright/chromium",
"firefox": "wss://app.maxoperf.com/browser-fleets/flt-a1b2c3d4e5/playwright/firefox",
"msedge": "wss://app.maxoperf.com/browser-fleets/flt-a1b2c3d4e5/playwright/msedge"
},
"cdp": "wss://app.maxoperf.com/browser-fleets/flt-a1b2c3d4e5/cdp"
},
"token": "mpft_example_token",
"expiresAt": "2026-07-19T14:00:00Z",
"supportedPlaywrightVersions": ["1.59", "1.58", "1.57", "1.56", "1.63"]
}

browsersPerRunner is the fleet version of “virtual users per runner” on test create. 1 gives each session its own full-screen video. Higher values pack more browsers onto each runner, with tiled video. The default comes from your plan’s browser policy, and MaxoPerf clamps the value to your tier’s min/max. Details are in Billing & limits.

  • 401 Unauthorized: bad or missing credentials, or the fleet isn’t yours. In Java, read the preemptive basic-auth note above.
  • invalid session id: the session already ended (idle timeout) or never existed. Start a new session.
  • session not created after a pause: every browser was busy. The gateway queues new-session requests for a short time and returns this W3C error if no slot frees up. Add browsers or lower concurrency.
  • 410 Gone: the fleet has ended. Create a new one.