Selenium browser tests on MaxoPerf
Browser-level load testing drives real browser instances instead of simulating HTTP traffic. You measure the full end-user experience, including JavaScript execution, rendering, and client-side timing. Each virtual user costs far more resources. MaxoPerf runs browser load tests through the Taurus executor: selenium integration.
Before you start
Section titled “Before you start”- Read Taurus fundamentals. MaxoPerf drives Selenium through Taurus YAML.
- Read Frontend browser performance test to learn when browser-level testing fits.
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 relies on client-side rendering that you cannot test 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")) )Upload the script file as a Test asset and reference it 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 directly as the entrypoint. MaxoPerf infers the selenium executor from the file extension:
my-recording.side → Entrypoint → engine: selenium.side files need no Taurus YAML wrapper. You can still wrap them to set concurrency in YAML:
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 checks that 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: the time for
driver.get()and WebDriverfind_elementwaits, not raw HTTP response time. - Error rate: MaxoPerf counts WebDriver assertion failures and uncaught exceptions as errors.
- Throughput: iteration rate (completed browser flows per second) instead of HTTP RPS.
wdio: WebdriverIO alternative
Section titled “wdio: WebdriverIO alternative”If your team writes browser automation in JavaScript, use the wdio (WebdriverIO) executor instead of 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). You are measuring the browser-level experience, not generating heavy load.
- Use explicit waits (
WebDriverWait) instead oftime.sleep(). Explicit waits fail less often and give more accurate timings. - Run your script locally with
python test_checkout.pybefore you upload it to MaxoPerf.
Don’t:
- Use browser tests in place of HTTP-level load testing at high VU counts. The cost per VU is too high.
- Put real user credentials in the script file. Use Manage test secrets and inject them as 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: the test type 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.