Skip to main content
Back to Blog
Guide
2026-05-14

Selenide Grid Parallel Testing — Complete Guide 2026

Master Selenide with Selenium Grid for parallel browser testing. Remote URL, hub-node, cross-browser, Docker, and CI/CD scaling patterns.

Selenide Grid Parallel Testing Complete Guide

Running browser tests serially on a single machine is fine for 10 tests, painful for 100, and impossible for 1000+. Selenium Grid solves this by distributing tests across a pool of browser nodes — local, cloud, or Docker — and Selenide integrates with Grid via a single configuration property. Combined with JUnit 5 parallel execution and Docker-based browser nodes, you can run hundreds of tests in minutes instead of hours.

This guide is a comprehensive walkthrough of running Selenide tests against Selenium Grid in 2026. We cover the Configuration.remote property, Docker-based Selenium Grid setup (Hub + Chrome + Firefox nodes), parallel test execution patterns, cross-browser matrix testing, cloud Grid services (Sauce Labs, BrowserStack, LambdaTest), and CI/CD configuration. Every code sample is working Java with Selenide 7+ and JUnit 5.


Key Takeaways

  • Configuration.remote points Selenide at a Selenium Grid hub URL
  • Grid 4.x is the modern Selenium architecture (replaces Grid 3 hub/nodes)
  • JUnit 5 parallel execution scales tests across grid nodes
  • Docker Selenium is the easiest way to run a local Grid
  • Cloud Grids (Sauce Labs, BrowserStack) work with the same Configuration.remote
  • Per-thread driver isolation is built into Selenide

Local Selenium Grid with Docker

Start a Grid hub plus Chrome and Firefox nodes:

# docker-compose.yml
version: '3.8'
services:
  selenium-hub:
    image: selenium/hub:4.27.0
    ports:
      - "4442:4442"
      - "4443:4443"
      - "4444:4444"

  chrome:
    image: selenium/node-chrome:4.27.0
    shm_size: 2gb
    depends_on:
      - selenium-hub
    environment:
      - SE_EVENT_BUS_HOST=selenium-hub
      - SE_EVENT_BUS_PUBLISH_PORT=4442
      - SE_EVENT_BUS_SUBSCRIBE_PORT=4443
      - SE_NODE_MAX_SESSIONS=4

  firefox:
    image: selenium/node-firefox:4.27.0
    shm_size: 2gb
    depends_on:
      - selenium-hub
    environment:
      - SE_EVENT_BUS_HOST=selenium-hub
      - SE_EVENT_BUS_PUBLISH_PORT=4442
      - SE_EVENT_BUS_SUBSCRIBE_PORT=4443
      - SE_NODE_MAX_SESSIONS=4

Start:

docker compose up -d

Hub is now available at http://localhost:4444.


Configuring Selenide

import com.codeborne.selenide.Configuration;

@BeforeAll
static void setup() {
    Configuration.remote = "http://localhost:4444/wd/hub";
    Configuration.browser = "chrome";
    Configuration.browserSize = "1920x1080";
}

That's it. Every Selenide command now routes through the Grid.


Cross-Browser Matrix

Run the same test in Chrome and Firefox:

import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.ValueSource;

class CrossBrowserTest {

    @ParameterizedTest
    @ValueSource(strings = { "chrome", "firefox" })
    void worksInBrowser(String browser) {
        Configuration.browser = browser;
        open("/login");
        $("#email").setValue("a@b.com");
        $("#submit").click();
        $(".dashboard").shouldBe(visible);
    }
}

JUnit 5 runs the test once per browser.


JUnit 5 Parallel Execution

To run multiple tests in parallel:

# junit-platform.properties
junit.jupiter.execution.parallel.enabled=true
junit.jupiter.execution.parallel.mode.default=concurrent
junit.jupiter.execution.parallel.mode.classes.default=concurrent
junit.jupiter.execution.parallel.config.strategy=fixed
junit.jupiter.execution.parallel.config.fixed.parallelism=4

Selenide handles per-thread driver isolation via thread-local WebDriver instances. Each test thread gets its own browser session from the Grid.


Maven Surefire Parallel

<plugin>
  <groupId>org.apache.maven.plugins</groupId>
  <artifactId>maven-surefire-plugin</artifactId>
  <version>3.5.1</version>
  <configuration>
    <parallel>methods</parallel>
    <threadCount>4</threadCount>
    <useUnlimitedThreads>false</useUnlimitedThreads>
    <forkCount>1</forkCount>
    <reuseForks>true</reuseForks>
  </configuration>
</plugin>

Cloud Grid: Sauce Labs

String username = System.getenv("SAUCE_USERNAME");
String accessKey = System.getenv("SAUCE_ACCESS_KEY");

Configuration.remote = String.format(
    "https://%s:%s@ondemand.saucelabs.com/wd/hub",
    username, accessKey
);
Configuration.browser = "chrome";

For Sauce-specific options like build name:

import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.MutableCapabilities;

ChromeOptions chromeOptions = new ChromeOptions();
MutableCapabilities sauceOptions = new MutableCapabilities();
sauceOptions.setCapability("name", "Login Test");
sauceOptions.setCapability("build", "PR-" + System.getenv("BUILD_NUMBER"));
sauceOptions.setCapability("tags", new String[]{ "smoke", "checkout" });
chromeOptions.setCapability("sauce:options", sauceOptions);

Configuration.browserCapabilities = chromeOptions;

Cloud Grid: BrowserStack

String username = System.getenv("BROWSERSTACK_USERNAME");
String accessKey = System.getenv("BROWSERSTACK_ACCESS_KEY");

Configuration.remote = String.format(
    "https://%s:%s@hub-cloud.browserstack.com/wd/hub",
    username, accessKey
);

MutableCapabilities caps = new MutableCapabilities();
caps.setCapability("browserName", "Chrome");
caps.setCapability("browserVersion", "latest");
caps.setCapability("bstack:options", Map.of(
    "os", "Windows",
    "osVersion", "11",
    "buildName", "Build-1",
    "sessionName", "Login Test"
));
Configuration.browserCapabilities = caps;

Cloud Grid: LambdaTest

String username = System.getenv("LT_USERNAME");
String accessKey = System.getenv("LT_ACCESS_KEY");

Configuration.remote = String.format(
    "https://%s:%s@hub.lambdatest.com/wd/hub",
    username, accessKey
);

CI/CD with Grid: GitHub Actions

name: cross-browser-tests
on: [push]
jobs:
  test:
    runs-on: ubuntu-latest
    services:
      selenium-hub:
        image: selenium/hub:4.27.0
        ports:
          - 4444:4444
      chrome:
        image: selenium/node-chrome:4.27.0
        env:
          SE_EVENT_BUS_HOST: selenium-hub
          SE_EVENT_BUS_PUBLISH_PORT: 4442
          SE_EVENT_BUS_SUBSCRIBE_PORT: 4443
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-java@v4
        with:
          distribution: temurin
          java-version: 21
      - run: ./mvnw test -Dselenide.remote=http://localhost:4444/wd/hub

Scaling: How Many Parallel Tests?

ResourceEffect
HubCoordinates ~50-100 sessions, low CPU
Chrome node1 session uses ~1 GB RAM, 1 CPU
Firefox nodeSimilar to Chrome

For local Docker on a 16 GB machine, 8-12 parallel sessions is comfortable.

In cloud Grids, you typically pay per session-minute, so parallelism is limited by your plan.


Session Timeouts

Configuration.pageLoadTimeout = 60_000; // page load
Configuration.browserCapabilities.setCapability("idleTimeout", 90); // sec

Sauce Labs and BrowserStack have additional session timeouts configured per-capability.


Video Recording on Cloud Grids

Most cloud Grids record video automatically. Selenide doesn't need any special setup — the video URL appears in the cloud dashboard.

For local Docker Selenium, use the video-enabled image:

chrome:
  image: selenium/node-chrome:4.27.0
chrome-video:
  image: selenium/video:ffmpeg-7.1
  volumes:
    - ./videos:/videos
  depends_on:
    - chrome
  environment:
    - DISPLAY_CONTAINER_NAME=chrome
    - FILE_NAME=chrome-test.mp4

Per-Test Capabilities

If different tests need different capabilities, use a custom WebDriver provider:

import com.codeborne.selenide.WebDriverProvider;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.remote.RemoteWebDriver;

public class MyChromeProvider implements WebDriverProvider {
    @Override
    public WebDriver createDriver(org.openqa.selenium.Capabilities capabilities) {
        ChromeOptions opts = new ChromeOptions();
        opts.setCapability("name", "MyTest");
        try {
            return new RemoteWebDriver(new URL(Configuration.remote), opts);
        } catch (Exception e) { throw new RuntimeException(e); }
    }
}

Configuration.browser = MyChromeProvider.class.getName();

Common Pitfalls

Pitfall 1: Browser state between tests. Sessions are reused unless you call Selenide.closeWebDriver() between tests. For full isolation, set Configuration.holdBrowserOpen = false and don't reuse drivers.

Pitfall 2: Capacity issues. Running 20 tests against 4 nodes queues up requests. Match parallelism to grid capacity.

Pitfall 3: Slow first test. Image pull + node startup can take 30 seconds. Pre-warm in CI.

Pitfall 4: Stale Configuration. Setting Configuration.remote mid-test has no effect on already-running drivers.

Pitfall 5: Forgotten cleanup. Cloud Grids charge per session-minute. Ensure drivers quit on test failure.


Conclusion

Selenide + Selenium Grid scales browser testing from minutes to seconds by parallelizing across nodes. Local Docker Grid is great for CI and development; cloud Grids (Sauce, BrowserStack, LambdaTest) extend the matrix to dozens of OS/browser combinations. JUnit 5 parallel execution combined with Selenide's per-thread driver isolation makes the integration almost free.

For complementary patterns, see our headless guide and Testcontainers Selenium guide.

Browse the QA skills directory for related browser automation patterns.

Selenide Grid Parallel Testing — Complete Guide 2026 | QASkills.sh