Using Selenium with a Cloud Browser
Run Selenium tests on remote browsers with RemoteWebDriver, Grid or a hosted service. Learn setup, capabilities, files, security, debugging and costs.
Short answer: run your test code locally (the client computer) and create a RemoteWebDriver session at a Selenium Grid or hosted browser endpoint (the remote computer). Pass the endpoint URL and browser options or capabilities, run the test, collect artifacts, and always call quit(). Selenium’s documentation describes the pattern directly: “To direct Selenium tests to the remote computer, you need to use a Remote WebDriver class and pass the URL including the port of the grid on that machine.” Read the Remote WebDriver documentation.
1. How do I use Selenium with a cloud browser?
The workflow is:
- Make the test pass against a local browser first.
- Choose a self-managed Selenium Grid or a hosted browser service.
- Store the remote endpoint and credentials as secrets.
- Create browser-specific options and supported capabilities.
- Construct
RemoteWebDriverwith the endpoint and options. - Run assertions, capture logs or video, and close the session in a
finallyblock.
A cloud browser is still controlled with normal WebDriver commands. The important difference is the machine boundary: paths, downloads, network access, latency and browser support now depend on the remote host.
2. Choose Grid or a hosted browser service
Self-managed Selenium Grid
Grid lets you own the browser nodes, network boundary and deployment. Standalone mode is a simple single-machine setup, normally listening at http://localhost:4444. Hub/node and distributed modes place nodes on multiple machines for parallel sessions and broader browser or platform coverage. Follow the Grid getting-started guide and the Grid overview.
Hosted browser service
A provider operates the browsers and exposes a remote WebDriver URL. You use the same client pattern, but authentication, capability names, concurrency, artifacts and private-network access vary. Selenide documents integrations including BrowserStack, TestMu AI (formerly LambdaTest) and Sauce Labs; AWS Device Farm documents signed endpoint URLs, desktop browser sessions, recordings and Selenium logs.
| Decision | Questions to answer |
|---|---|
| Coverage | Which browser versions, operating systems and screen sizes are required? |
| Scale | How many sessions can run concurrently, and how are queues handled? |
| Network | Can the browser reach staging sites, VPNs or private VPC resources? |
| Artifacts | Are video, screenshots, console logs and WebDriver logs available? |
| Capabilities | Are proxy, clipboard, downloads, uploads and permissions supported? |
| Billing | Is usage billed per minute, session, seat or another unit? |
AWS’s desktop browser testing guide describes Chrome, Firefox and Chromium Edge on Windows, parallel sessions, recordings and Selenium logs, with per-minute billing. Confirm the current support matrix, regions, limits and pricing before committing.
3. Start a local Grid
For a basic self-managed experiment, install Selenium Server and start standalone mode according to the current Grid guide. The client endpoint is typically:
http://localhost:4444
In production, protect the endpoint with firewall rules and private networking. Selenium warns that an exposed Grid can allow access to infrastructure, internal applications and files, or permit arbitrary binaries to run.
4. Java: complete RemoteWebDriver example
Add Selenium Java to your build, then replace GRID_URL with your Grid or provider endpoint.
import java.net.URL;
import java.time.Duration;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.remote.RemoteWebDriver;
public class CloudBrowserTest {
public static void main(String[] args) throws Exception {
String endpoint = System.getenv().getOrDefault("SELENIUM_ENDPOINT", "http://localhost:4444");
ChromeOptions options = new ChromeOptions();
options.setBrowserVersion("stable");
options.setPlatformName("linux");
options.setCapability("se:name", "cloud-browser-smoke");
WebDriver driver = new RemoteWebDriver(new URL(endpoint), options);
try {
driver.manage().timeouts().pageLoadTimeout(Duration.ofSeconds(60));
driver.get("https://example.com");
String heading = driver.findElement(By.tagName("h1")).getText();
if (!"Example Domain".equals(heading)) {
throw new AssertionError("Unexpected heading: " + heading);
}
} finally {
driver.quit();
}
}
}
Use provider-specific capability namespaces only when that provider documents them. A capability accepted by one service may be ignored or rejected by another.
5. Python: complete remote browser example
import os
from selenium import webdriver
from selenium.webdriver.chrome.options import Options
from selenium.webdriver.common.by import By
endpoint = os.getenv("SELENIUM_ENDPOINT", "http://localhost:4444")
options = Options()
options.browser_version = "stable"
options.platform_name = "linux"
options.set_capability("se:name", "python-cloud-smoke")
driver = webdriver.Remote(command_executor=endpoint, options=options)
try:
driver.set_page_load_timeout(60)
driver.get("https://example.com")
assert driver.find_element(By.TAG_NAME, "h1").text == "Example Domain"
finally:
driver.quit()
6. JavaScript and Node.js example
Install the Selenium package with npm install selenium-webdriver. The endpoint can be a Grid URL or a provider URL that includes the required authentication.
const { Builder, By } = require('selenium-webdriver');
const chrome = require('selenium-webdriver/chrome');
(async () => {
const endpoint = process.env.SELENIUM_ENDPOINT || 'http://localhost:4444';
const options = new chrome.Options();
options.setBrowserVersion('stable');
options.setPlatform('linux');
options.set('se:name', 'node-cloud-smoke');
const driver = await new Builder()
.forBrowser('chrome')
.setChromeOptions(options)
.usingServer(endpoint)
.build();
try {
await driver.manage().setTimeouts({ pageLoad: 60000 });
await driver.get('https://example.com');
const heading = await driver.findElement(By.css('h1')).getText();
if (heading !== 'Example Domain') throw new Error(`Unexpected heading: ${heading}`);
} finally {
await driver.quit();
}
})();
7. Browser options and capabilities
Options create the browser-specific configuration. Capabilities describe the requested browser and platform to Grid’s matching process. Common W3C fields include:
browserName, selected by the language binding or options class.browserVersion, such asstableor a provider-supported version.platformName, such aslinuxorwindows.se:name, useful for identifying a session in Grid or a provider dashboard.
Do not assume every W3C capability is implemented by every service. AWS documents service-specific aws: capabilities and notes that not all W3C capabilities are implemented. Keep provider settings isolated in one configuration function so your tests remain portable.
8. Uploads, downloads and other remote-machine differences
Uploads
An upload path normally exists on the client machine, while the browser resolves paths on the remote host. Selenium treats uploads as a special case because those files must cross the boundary. Use the language binding’s file-upload mechanism and verify how your Grid or provider transfers the file.
Downloads
Downloads are written on the remote machine. Selenium Grid can manage them when started with --enable-managed-downloads true; the client also enables the se:downloadsEnabled capability and retrieves files through Selenium’s downloadable-files interface. The returned list is an immediate snapshot: it does not wait for a download to finish. Poll for the expected file or application state before retrieving it.
Private applications
A hosted browser must be able to resolve and reach the target. Check DNS, firewall rules, allowlists, VPN or VPC connectivity, and whether the provider offers a private-network integration. Never expose internal applications by opening broad inbound access to a self-managed Grid.
9. Reliability and performance
- Stabilize locally first. AWS recommends observing and confirming local behavior before migration, so remote failures are not confused with existing test defects.
- Expect network latency. Keep assertions explicit, wait for application conditions rather than arbitrary sleeps, and set page-load and script timeouts appropriate to the application.
- Use isolated sessions. Create a fresh driver per test or controlled test group and always call
quit(), including on assertion failure. - Control concurrency. Match parallel workers to the Grid node pool or provider quota. More workers can increase queue time, resource contention and cost.
- Capture evidence. Record the session identifier, requested capabilities, URL, exception, browser console output and provider artifacts. AWS documents video and Selenium logs; Grid provides status through its UI and APIs.
- Retry selectively. Retry infrastructure-level session creation failures with a bounded policy. Do not blindly retry assertion failures, because that can hide product defects.
Cloud execution is not automatically faster or cheaper. Measure your own suite, including session startup, queue time, command latency and artifact transfer.
10. Security checklist
- Keep Grid endpoints on private networks or behind an authenticated gateway.
- Allow only trusted clients and required ports through firewalls.
- Store provider tokens in a secret manager, never in test source or logs.
- Use least-privilege AWS credentials when requesting Device Farm endpoints.
- Review where screenshots, videos, downloads and page data are stored.
- Remove credentials and personal data from URLs, headers and captured artifacts.
- Confirm whether the provider can access staging systems and which regions process data.
11. Troubleshooting common failures
| Error or symptom | Likely cause | Fix |
|---|---|---|
| Connection refused | Grid is stopped, the port is wrong, or a firewall blocks it. | Open the endpoint from the client network, verify the listening port and inspect Grid logs. |
| Session not created | No node matches browser or platform capabilities. | Request an installed version, remove unsupported capabilities and check the provider matrix. |
| Invalid argument or capability | A provider-specific field is in the wrong namespace or unsupported. | Use the provider’s documented namespace and send only supported fields. |
| Page timeout | The remote browser cannot resolve the host, the page is slow, or resources are blocked. | Test DNS and network access from the browser environment, then tune page-load and script timeouts. |
| Works locally, fails remotely | Different browser version, OS, permissions, timezone, network or file path. | Log capabilities and environment details; reproduce with the same remote configuration. |
| Upload cannot find file | The path is local to the client, not the browser host. | Use Selenium’s upload transfer support and verify the provider’s file-handling behavior. |
| Downloaded file is missing | Download is still running or managed downloads are not enabled. | Enable the Grid/client download settings, wait for completion, then retrieve the file. |
| Tests hang after failure | The driver was not closed. | Put quit() in finally or an equivalent teardown hook. |
| Intermittent stale or missing elements | Tests race the application’s rendering. | Wait for a specific element state or network-driven application condition instead of sleeping. |
12. Cost planning
Self-managed Grid costs the machines, storage, networking and maintenance you provide. Hosted services commonly meter sessions, minutes, concurrency or seats. AWS Device Farm desktop browser testing is billed per minute. Include browser startup, queue time, retries, video retention and parallel workers in your estimate, and verify current provider pricing before purchase.
13. Or skip the browser setup
If your goal is a clean image or PDF rather than interactive browser assertions, ScreenshotNeo provides a single HTTP request to capture a URL. Its cookie and consent step accepts the banner like a visitor, then removes more than 60 known consent platforms, newsletter popups and chat widgets before capture; each step can be disabled. Bot checks or CAPTCHAs, blank pages, timeouts, failed loads and cache hits are not billed, and response headers report the page verdict and billing status. ScreenshotNeo also offers an MCP server for Claude, Cursor and other MCP clients, with take_screenshot, get_page_info and capture_pdf.
See the ScreenshotNeo API documentation for all options.
curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://stripe.com -o shot.webp
import requests
r = requests.get("https://api.screenshotneo.com/v1/shot", params={"access_key": "YOUR_API_KEY", "url": "https://stripe.com"}, timeout=90)
open("shot.webp", "wb").write(r.content)
const q = new URLSearchParams({ access_key: 'YOUR_API_KEY', url: 'https://stripe.com' });
const res = await fetch(`https://api.screenshotneo.com/v1/shot?${q}`);
There is a free tier of 1,000 screenshots per month with no card. Paid plans start at $5 for 3,000 screenshots. Create a free ScreenshotNeo account.
14. FAQ
How do I run Selenium tests on a remote browser?
Use RemoteWebDriver with the remote Grid or provider URL and browser options, then run the same WebDriver commands as locally.
Does Selenium Grid require a cloud provider?
No. You can run standalone, hub/node or distributed Grid yourself, or use a hosted service that exposes a compatible endpoint.
Can a remote browser access localhost?
Usually localhost refers to the remote browser machine, not your laptop. Provide a network route, deploy the test site where the browser can reach it, or use a provider-supported tunnel.
Are cloud browser sessions deterministic?
No. Browser versions, network paths, shared capacity and provider limits can differ. Pin supported versions, record capabilities and keep waits tied to application state.
What should I do with downloads?
Configure managed downloads when using Grid, wait for completion, and retrieve files through the binding’s downloadable-files interface. The file list is a snapshot and does not wait automatically.


