Principle:Webdriverio Webdriverio Local Tunnel Connectivity
Metadata
| Field | Value |
|---|---|
| Page ID | Local_Tunnel_Connectivity |
| Wiki | Webdriverio_Webdriverio |
| Type | Principle |
| Domains | Testing, Cloud, Networking |
| Knowledge Sources | Repo (https://github.com/webdriverio/webdriverio), Doc (https://www.browserstack.com/docs/local-testing) |
| Related Implementations | Implementation: BrowserStack_Launcher_Tunnel |
Overview
A technique for establishing secure tunnels between local development machines and cloud browser testing infrastructure. Local Tunnel Connectivity creates a secure connection that enables cloud-hosted browsers to access localhost URLs, staging servers, and internal network resources that are not publicly accessible on the internet.
Description
Local Tunnel Connectivity creates a secure connection between the machine running tests and a cloud testing provider, enabling cloud-hosted browsers to access localhost, staging servers, and internal network resources. This is essential for testing applications before they are deployed to public URLs. The tunnel encrypts traffic and routes it through the cloud provider's infrastructure.
Without a local tunnel, cloud browsers can only access publicly reachable URLs. This makes it impossible to test:
- Applications running on
localhostduring development. - Applications on internal staging servers behind corporate firewalls.
- Applications on private networks or VPNs.
- Microservices running on local Docker containers.
Each cloud provider supported by WebdriverIO offers its own tunnel implementation:
- BrowserStack Local -- A binary (
browserstack-local) that creates a tunnel from the local machine to BrowserStack's infrastructure. Managed by@wdio/browserstack-service. - Sauce Connect -- A proxy that creates a TLS tunnel from the local machine to Sauce Labs. Managed by
@wdio/sauce-service. - TestingBot Tunnel -- A tunnel binary (
testingbot-tunnel-launcher) that connects to TestingBot's infrastructure. Managed by@wdio/testingbot-service.
All three follow the same lifecycle pattern within WebdriverIO:
- Start -- The tunnel is started in the
onPreparehook, before any test workers are spawned. - Run -- Tests execute in cloud browsers, with traffic routed through the tunnel to reach local/internal resources.
- Stop -- The tunnel is stopped in the
onCompletehook, after all test workers have finished.
Usage
Use Local Tunnel Connectivity when running tests on cloud browsers that need to access local or internal applications.
When to apply:
- Testing an application running on
localhostduring development or CI. - Testing applications on internal staging servers not exposed to the internet.
- Testing applications behind a corporate firewall or VPN.
- When the application under test is not yet deployed to a public URL.
When to avoid:
- When the application under test is already accessible via a public URL.
- When running tests against a local browser (no cloud provider involved).
- When the cloud provider offers alternative access methods (e.g., public URLs).
Configuration pattern:
// wdio.conf.ts -- BrowserStack Local
export const config: WebdriverIO.Config = {
user: process.env.BROWSERSTACK_USERNAME,
key: process.env.BROWSERSTACK_ACCESS_KEY,
services: [['browserstack', {
browserstackLocal: true,
opts: {
localIdentifier: 'my-tunnel'
}
}]],
capabilities: [{
browserName: 'chrome',
'bstack:options': {
local: true,
localIdentifier: 'my-tunnel'
}
}]
}
// wdio.conf.ts -- Sauce Connect
export const config: WebdriverIO.Config = {
user: process.env.SAUCE_USERNAME,
key: process.env.SAUCE_ACCESS_KEY,
services: [['sauce', {
sauceConnect: true,
sauceConnectOpts: {
tunnelName: 'my-sc-tunnel'
}
}]],
capabilities: [{
browserName: 'chrome',
'sauce:options': {
tunnelName: 'my-sc-tunnel'
}
}]
}
Theoretical Basis
Tunnel architecture:
Tunneling uses a client-side binary that establishes an encrypted connection (typically WebSocket or TCP over TLS) to the cloud provider. The connection flow works as follows:
- The tunnel binary starts on the local machine and authenticates with the cloud provider using API credentials.
- The binary establishes an encrypted connection to the provider's tunnel server.
- When a cloud browser needs to access a local resource (e.g.,
http://localhost:3000), the request is routed through the tunnel. - The tunnel binary on the local machine receives the request and forwards it to the target address on the local network.
- The response travels back through the tunnel to the cloud browser.
This creates a virtual network bridge between the cloud browser and the local network, making localhost and internal URLs accessible as if the cloud browser were on the same network.
Lifecycle integration:
WebdriverIO integrates tunnels into the service lifecycle:
| Hook | Action | Timing |
|---|---|---|
onPrepare |
Start the tunnel binary and wait for it to be ready | Before all tests |
| (test execution) | Route cloud browser traffic through the active tunnel | During tests |
onComplete |
Stop the tunnel binary and clean up | After all tests |
The onPrepare hook runs in the main WDIO process before any worker processes are spawned. This ensures the tunnel is fully operational before the first test attempts to access a local resource. The onComplete hook runs after all workers have exited, ensuring the tunnel remains available for the entire test run duration.
Tunnel identifiers:
When multiple tunnel instances run concurrently (e.g., in parallel CI jobs), a tunnel identifier disambiguates which tunnel each test session should use. The identifier is set both in the service configuration and in the session capabilities:
- BrowserStack:
opts.localIdentifier(service) andbstack:options.localIdentifier(capability) - Sauce Labs:
sauceConnectOpts.tunnelName(service) andsauce:options.tunnelName(capability) - TestingBot:
tbTunnelOpts.tunnelIdentifier(service) andtb:options['tunnel-identifier'](capability)
If no tunnel identifier is provided, the services generate a random one (e.g., SC-tunnel-${Math.random()}) and automatically inject it into the capabilities.
Related Pages
Implementation:Webdriverio_Webdriverio_BrowserStack_Launcher_Tunnel
- implemented_by Implementation: BrowserStack_Launcher_Tunnel