Testing Internal Sites with BrowserStack Local in Selenium CI Pipelines
Learn how to set up BrowserStack Local, run a Selenium test against a locally hosted staging page, and evaluate latency, bandwidth, and firewall trade‑offs.
27 Sept 2026, 17:58 UTC

The problem: accessing non‑public URLs from remote browsers
When your Selenium suite needs to verify a feature on a staging or internal web app, the test runners running on BrowserStack cannot reach URLs that are not exposed to the public internet. Opening those services to the world defeats the purpose of a staging environment and may violate security policies.
How BrowserStack Local solves it
BrowserStack Local creates a persistent, encrypted WebSocket tunnel from your machine (or CI agent) to BrowserStack’s remote VMs. Traffic destined for the tunnel‑enabled hostname is forwarded through this tunnel, so the remote browser sees the same localhost or internal host as your machine does. The tunnel works for HTTP, HTTPS and WebSocket protocols and can be limited to specific folders or ports.
Setting up the tunnel
- Download the binary for your OS from the BrowserStack dashboard and make it executable.
- Authenticate with your access key (found under Account Settings).
- Start the tunnel in the background, allowing outbound TCP 443 (or a custom port you configure).
# Example: Linux/macOS CI agent
chmod +x BrowserStackLocal
./BrowserStackLocal --key YOUR_ACCESS_KEY &
# The ampersand runs it in the background; note the PID for later shutdown
Verify the tunnel is active by checking the process list or looking for the line "BrowserStack Local is running" in the output.
Worked example: Selenium test against a local staging page
Assume you have a simple HTML file served locally on port 8000:
# Serve a test page (run on the same machine as the tunnel)
python3 -m http.server 8000 --bind 127.0.0.1
# File: /path/to/test.html contains <h1>Hello BrowserStack</h1>
Now configure your Selenium capabilities to enable the tunnel:
from selenium import webdriver
options = webdriver.ChromeOptions()
options.set_capability('browser', 'Chrome')
options.set_capability('browser_version', 'latest')
options.set_capability('os', 'Windows')
options.set_capability('os_version', '10')
options.set_capability('browserstack.local', 'true') # <‑‑ key part
options.set_capability('browserstack.user', 'YOUR_BROWSERSTACK_USERNAME')
options.set_capability('browserstack.key', 'YOUR_BROWSERSTACK_ACCESS_KEY')
driver = webdriver.Remote(
command_executor='https://hub.browserstack.com/wd/hub',
options=options
)
driver.get('http://localhost:8000/test.html')
assert 'Hello BrowserStack' in driver.title
print('Test passed')
driver.quit()
When the test runs, BrowserStack routes the request to localhost:8000 through the Local tunnel, and the assertion succeeds.
Trade‑offs and limitations
- Latency: Each request incurs the extra hop through the tunnel. For UI‑heavy suites, measure round‑trip time (e.g., ping the tunnel endpoint) and consider limiting Local use to tests that truly need internal access.
- Bandwidth sharing: All concurrent sessions share the same tunnel throughput. Large file downloads or video streaming can saturate the link and cause throttling.
- Firewall requirements: The tunnel needs outbound TCP 443 (or a custom port) open. Strict corporate proxies may block it unless the domain
bs-local.comis allowed.
Practical verification: after starting the tunnel, run curl -v http://localhost:8000/test.html from the same machine. If you see a successful HTTP 200 response, the tunnel is forwarding correctly. Stop the tunnel with kill <PID> (or Ctrl+C if running in foreground) and re‑run the curl; a connection refused or timeout confirms the tunnel is required.
Actionable closing
To make BrowserStack Local a reliable part of your CI pipeline:
- Start the tunnel as a service step before your test job and stop it afterward.
- Collect latency metrics (e.g.,
time curl -o /dev/null -s -w "%{time_total}" http://localhost:8000/test.html) and set a threshold that triggers a warning if exceeded. - Whitelist only the specific folders or ports your staging site needs, reducing the attack surface.
- Monitor the tunnel’s process health; restart it automatically if it exits unexpectedly.
With these checks in place, you can safely run Selenium suites against internal URLs without exposing them to the public internet.
0 replies
A thoughtful contribution can make all the difference. Be the first to share one.