← All guides
DEVELOPER GUIDES · 6 MIN READ

SeleniumBase Proxy Setup for Chromium Tests

Configure authenticated proxies, PAC files or multiple proxy inputs in SeleniumBase, then validate the browser result.

SeleniumBase gives a browser test a proxy at startup. The useful job is repeatable Chromium traffic in CI: choose an HTTP, SOCKS or PAC route, keep the browser session consistent for the assertions that depend on it, and count a run only when the required page content is present.

There are several connections in a SeleniumBase run. The test process starts WebDriver, the browser connects through the configured route, and the target returns a page to that browser. A proxy argument does not validate the target’s content, and a driver download or Selenium Manager connection is a separate setup path.

Install SeleniumBase

Install the package in the environment that runs your tests:

python -m pip install -U seleniumbase

For a first probe, use a Chromium browser and put the proxy value in a secret environment binding. SeleniumBase documents SERVER:PORT for an unauthenticated proxy and USER:PASS@SERVER:PORT for an authenticated proxy. Do not paste a real credential into a shell history, source file or CI log.

Run the browser and validate its result

This script accepts either PROXY or PROXY_PAC_URL. It fails before browser startup when the route, target or required marker is missing. The exit-IP request and target navigation use the same WebDriver instance.

import json
import os
import time
from seleniumbase import Driver


target_url = os.environ.get("TARGET_URL")
expected_marker = os.environ.get("EXPECTED_MARKER", "").strip()
proxy = os.environ.get("PROXY")
proxy_pac_url = os.environ.get("PROXY_PAC_URL")
if not target_url or not expected_marker:
    raise SystemExit("TARGET_URL and EXPECTED_MARKER are required")
if bool(proxy) == bool(proxy_pac_url):
    raise SystemExit("Set exactly one of PROXY or PROXY_PAC_URL")

driver = None
try:
    options = {"browser": "chrome", "headless2": True, "log_cdp_events": True}
    if proxy:
        options["proxy"] = proxy
    else:
        options["proxy_pac_url"] = proxy_pac_url
    driver = Driver(**options)
    driver.set_page_load_timeout(25)

    driver.get("https://api.ipify.org?format=json")
    exit_ip = driver.find_element("tag name", "body").text.strip()
    if not exit_ip:
        raise RuntimeError("The configured browser returned no exit-IP body")

    driver.get_log("performance")  # Discard events from the exit check
    driver.get(target_url)
    frame = driver.execute_cdp_cmd("Page.getFrameTree", {})["frameTree"]["frame"]
    status = None
    deadline = time.monotonic() + 5
    while status is None and time.monotonic() < deadline:
        for entry in driver.get_log("performance"):
            event = json.loads(entry["message"])["message"]
            data = event.get("params", {})
            if (event["method"] == "Network.responseReceived"
                    and data.get("type") == "Document"
                    and data.get("frameId") == frame["id"]
                    and data.get("loaderId") == frame["loaderId"]):
                status = data["response"]["status"]
        if status is None:
            time.sleep(0.1)
    body = driver.find_element("tag name", "body").text
    if status != 200 or expected_marker not in body:
        raise RuntimeError("Target content validation failed")
    print({"exit_ip_present": True, "status": status, "content_valid": True})
finally:
    if driver is not None:
        driver.quit()

WebDriver’s get() does not return an HTTP response. Here log_cdp_events=True enables ChromeDriver performance events. The filter selects the final top-level document by frame and loader ID, excluding iframe and earlier navigation responses. Missing status evidence fails the run. Keep raw events private because URLs and headers can contain secrets.

The final assertion requires HTTP 200 and a nonempty marker. Replace EXPECTED_MARKER with a field, heading or other value that proves the permitted page is the one your parser expects. HTTP 200, a non-empty body or an IP response is transport evidence; it is not a useful record by itself.

Choose proxy type and session policy

Workload Proxy type Session choice Acceptance signal
One public CI check HTTP host:port Fresh driver per test job Required marker passes
Authenticated Chromium route user:pass@host:port One driver for related assertions Exit and target fields agree
Browser route rules PAC URL Keep one driver while evaluating the rule set Expected hosts use the intended path
Parallel test suite Proxy list plus --multi-proxy One route per worker where your run design requires it Results remain attributable by worker

The CLI equivalent of proxy_pac_url is --proxy-pac-url=URL; --proxy-bypass-list specifies hosts that skip the proxy. PAC rules can also select a direct connection, so verify the rule for the target host separately from the IP-check host.

SeleniumBase also documents SOCKS4 and SOCKS5 values, proxy bypass lists, and named entries in proxy_list.py. --multi-proxy allows multiple authenticated proxies when tests run multi-threaded. These are input and run controls. They do not establish that a supplier rotates cleanly, that every browser backend accepts credentials, or that a target will allow the request.

The important authentication boundary is explicit: SeleniumBase’s authenticated proxy examples are for Chromium only. Do not copy USER:PASS@HOST:PORT into a Firefox assumption. Check the selected browser backend and provider authentication contract before changing the test matrix.

Diagnose the failing layer

Symptom Layer Next check
Required environment variable fails Test configuration Inspect the CI secret binding names without printing values
Driver cannot start Browser or driver setup Check the installed browser, driver path and SeleniumBase startup output
Browser starts but exit-IP navigation times out Proxy connection Check host, port, protocol, firewall and runner reachability
407 or authentication prompt Proxy authentication Recheck Chromium auth syntax and provider credentials; use the proxy 407 guide
Exit check works but marker is absent Target or parser Inspect the returned page, selector, target permissions and redirects
Related steps see different identities Session policy Keep one driver for the flow and review proxy rotation and sticky sessions

For cost comparisons, record attempts, retries, transferred bytes and valid records separately. The cost-per-successful-request guide gives the accounting frame. Close the driver after every bounded run, including failures, so a stale session cannot contaminate the next result.

SeleniumBase gives you a clear place to configure browser proxy behavior. Your test still owns permissions, target interpretation, field validation and the decision that a record is useful.

Sources and further reading

Sign in ↗

Keep reading

Amazon Scraper API vs Proxy: Choose a Product Data Source

Distinguish authorized Amazon APIs, licensed product data and proxy-based page checks by record quality and access rights.

Read guide →

Apify Custom Proxy Setup: Use Your Own Residential Route

Connect a buyer-owned proxy to an Apify Actor, keep the session boundary clear, and validate records instead of counting requests.

Read guide →

Australia Residential Proxies: Verify the AU Exit and State-Level Result

Separate Australian egress from en-AU content, AUD pricing, GST display, postcode validation and the state delivery context.

Read guide →