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).
Before you start
Section titled “Before you start”- 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.
The connection URL
Section titled “The connection URL”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/hubAny mpak_… account key with access to the fleet works in the password position too.
Connect
Section titled “Connect”# pip install seleniumfrom selenium import webdriverfrom 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()// selenium-java on the classpathimport org.openqa.selenium.chrome.ChromeOptions;import org.openqa.selenium.remote.RemoteWebDriver;import java.net.URL;
URL grid = new URL("https://flt-a1b2c3d4e5:mpft_example_token@app.maxoperf.com/browser-fleets/flt-a1b2c3d4e5/wd/hub");RemoteWebDriver driver = new RemoteWebDriver(grid, new ChromeOptions());driver.get("https://example.com");System.out.println(driver.getTitle());driver.quit();// npm i selenium-webdriverconst { Builder } = require('selenium-webdriver');
const driver = await new Builder() .usingServer('https://flt-a1b2c3d4e5:mpft_example_token@app.maxoperf.com/browser-fleets/flt-a1b2c3d4e5/wd/hub') .forBrowser('chrome') // or 'firefox' / 'MicrosoftEdge' .build();
await driver.get('https://example.com');console.log(await driver.getTitle());await driver.quit();Replace flt-a1b2c3d4e5 with your fleet id and mpft_example_token with your token.
Pick a browser and options
Section titled “Pick a browser and options”The browserName capability decides which fleet browser you get. Swap the options object per language:
- chrome:
ChromeOptions(Python/Java) or.forBrowser('chrome')(JS) - firefox:
FirefoxOptionsor.forBrowser('firefox') - edge:
EdgeOptionsor.forBrowser('MicrosoftEdge')
BiDi and se:cdp
Section titled “BiDi and se:cdp”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-webdriverconst { 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 endpointmaxoperf: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.
Create a fleet from the REST API
Section titled “Create a fleet from the REST API”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:
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.
Troubleshooting
Section titled “Troubleshooting”- 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 createdafter 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.