Selenium browser tests on MaxoPerf
Browser-level load testing drives real browser instances rather than simulating HTTP traffic. This lets you measure the full end-user experience — including JavaScript execution, rendering, and client-side timing — but at a significantly higher resource cost per virtual user. MaxoPerf runs browser load tests via the Taurus executor: selenium integration.
Before you start
Section titled “Before you start”- Read Taurus fundamentals — Selenium on MaxoPerf is driven through Taurus YAML.
- Read Frontend browser performance test for context on when browser-level testing is appropriate.
When browser testing adds value
Section titled “When browser testing adds value”HTTP-level simulation (JMeter, k6, Taurus native) is faster and cheaper per virtual user. Use browser-level testing when:
- You need to measure client-side metrics (First Contentful Paint, Time to Interactive, JavaScript error rate).
- Your application uses heavy client-side rendering that cannot be tested at the HTTP level.
- You are load-testing a WebSocket-heavy or SSE-driven UI that requires a real browser event loop.
- You are measuring Largest Contentful Paint or Core Web Vitals under simulated concurrent users.
For pure API or backend load testing, use HTTP-level simulation — it is 10–100x more efficient per VU.
Selenium executor YAML example
Section titled “Selenium executor YAML example”execution: - executor: selenium concurrency: 5 # keep low — each VU is a full browser process hold-for: 3m scenario: checkout-browser
scenarios: checkout-browser: script: test_checkout.py # Python WebDriver script — uploaded as Test asset browser: chrome # chrome (default) or firefoxPython WebDriver script example
Section titled “Python WebDriver script example”from selenium import webdriverfrom selenium.webdriver.common.by import Byfrom selenium.webdriver.support.ui import WebDriverWaitfrom selenium.webdriver.support import expected_conditions as EC
def test_checkout(driver): driver.get("https://app.example.com/")
# Wait for the login form WebDriverWait(driver, 10).until( EC.presence_of_element_located((By.ID, "username")) )
driver.find_element(By.ID, "username").send_keys("testuser@example.com") driver.find_element(By.ID, "password").send_keys("test-password") driver.find_element(By.CSS_SELECTOR, "button[type='submit']").click()
# Assert the dashboard loaded WebDriverWait(driver, 15).until( EC.url_contains("/dashboard") )
# Navigate to checkout driver.find_element(By.LINK_TEXT, "Add to cart").click() driver.find_element(By.LINK_TEXT, "Checkout").click()
WebDriverWait(driver, 10).until( EC.presence_of_element_located((By.CSS_SELECTOR, ".order-summary")) )The script file is uploaded as a Test asset and referenced from the Taurus YAML scenarios.*.script key.
Selenium IDE .side files
Section titled “Selenium IDE .side files”MaxoPerf also recognizes Selenium IDE project files (.side extension). Upload the .side file as the entrypoint directly — MaxoPerf infers the selenium executor from the file extension:
my-recording.side → Entrypoint → engine: seleniumNo Taurus YAML wrapper is needed for .side files, though you can still wrap them if you want YAML-controlled concurrency:
execution: - executor: selenium concurrency: 3 hold-for: 5m scenario: recorded-flow
scenarios: recorded-flow: script: my-recording.sideUploading and running
Section titled “Uploading and running”import { Steps } from ‘@astrojs/starlight/components’;
- Open the test in MaxoPerf console → Files tab.
- Upload your Taurus YAML as the Entrypoint.
- Upload the Python script (or
.sidefile) as a Test asset. - Save. MaxoPerf validates the YAML references the script correctly.
- Click Run. The runner starts Chrome (or Firefox) instances equal to the
concurrencyvalue.
Reading browser test results
Section titled “Reading browser test results”Selenium executor results appear in the same MaxoPerf run-detail view as HTTP-based tests:
- Latency — measured as the time for
driver.get()and WebDriverfind_elementwaits, not raw HTTP response time. - Error rate — WebDriver assertion failures and uncaught exceptions are counted as errors.
- Throughput — iteration rate (completed browser flows per second) rather than HTTP RPS.
wdio — WebdriverIO alternative
Section titled “wdio — WebdriverIO alternative”If your team uses JavaScript-based browser automation, the wdio (WebdriverIO) executor is an alternative to the Selenium Python executor:
execution: - executor: wdio concurrency: 3 hold-for: 3m scenario: wdio-checkout
scenarios: wdio-checkout: script: test/checkout.js # WebdriverIO spec fileSee the Taurus executor catalog for the wdio executor entry.
Do / don’t
Section titled “Do / don’t”Do:
- Keep browser test concurrency low (2–10 VUs). The goal is to measure browser-level experience, not to generate massive load.
- Use explicit waits (
WebDriverWait) rather thantime.sleep()— explicit waits are more reliable and produce more accurate timing measurements. - Test your script locally first with
python test_checkout.pybefore uploading to MaxoPerf.
Don’t:
- Use browser tests as a substitute for HTTP-level load testing at high VU counts — the cost per VU is prohibitive.
- Put real user credentials in the script file — use Manage test secrets and inject via environment variables.
- Rely on hard-coded
time.sleep()delays — the runner’s Chrome instance may be slower or faster than your local machine.
Where to go next
Section titled “Where to go next”- Frontend browser performance test — test type context for browser-level load.
- Taurus executor catalog — the
seleniumandwdioexecutor entries. - Taurus fundamentals — YAML structure and upload workflow.
- Test engines concept page — high-level engine comparison.