Selenium Grid is a distributed testing infrastructure that allows running WebDriver tests in parallel across multiple machines and browsers.
npx @tessl/cli install tessl/maven-org-seleniumhq-selenium--selenium-grid@4.33.0Selenium Grid is a distributed testing infrastructure that enables running WebDriver tests in parallel across multiple machines and browsers. It provides a scalable solution for automating web browser testing with centralized session management, load balancing, and support for multiple browser types.
pom.xml:
<dependency>
<groupId>org.seleniumhq.selenium</groupId>
<artifactId>selenium-grid</artifactId>
<version>4.33.0</version>
</dependency>import org.openqa.selenium.grid.Main;
import org.openqa.selenium.grid.config.Config;
import org.openqa.selenium.grid.config.MemoizedConfig;
import org.openqa.selenium.grid.config.MapConfig;
import org.openqa.selenium.grid.distributor.Distributor;
import org.openqa.selenium.grid.distributor.local.LocalDistributor;
import org.openqa.selenium.grid.node.Node;
import org.openqa.selenium.grid.node.local.LocalNode;
import org.openqa.selenium.grid.router.Router;
import org.openqa.selenium.grid.sessionmap.SessionMap;
import org.openqa.selenium.grid.sessionmap.local.LocalSessionMap;
import org.openqa.selenium.grid.sessionqueue.NewSessionQueue;
import org.openqa.selenium.grid.sessionqueue.local.LocalNewSessionQueue;
import org.openqa.selenium.events.EventBus;
import org.openqa.selenium.remote.tracing.Tracer;import org.openqa.selenium.grid.config.Config;
import org.openqa.selenium.grid.config.MemoizedConfig;
import org.openqa.selenium.grid.config.MapConfig;
import org.openqa.selenium.grid.distributor.local.LocalDistributor;
import org.openqa.selenium.grid.node.local.LocalNode;
import org.openqa.selenium.grid.sessionmap.local.LocalSessionMap;
import org.openqa.selenium.grid.sessionqueue.local.LocalNewSessionQueue;
import org.openqa.selenium.events.EventBus;
import org.openqa.selenium.remote.tracing.Tracer;
import org.openqa.selenium.grid.security.Secret;
import java.net.URI;
import java.time.Duration;
import java.util.Map;
// Create basic configuration
Config config = new MemoizedConfig(new MapConfig(Map.of()));
// Create required dependencies
Tracer tracer = Tracer.builder().build();
EventBus eventBus = EventBus.builder().build();
Secret registrationSecret = new Secret("secret");
// Create grid components
SessionMap sessionMap = new LocalSessionMap(tracer, eventBus);
NewSessionQueue sessionQueue = new LocalNewSessionQueue(
tracer,
slotMatcher,
Duration.ofSeconds(300),
Duration.ofSeconds(300),
Duration.ofSeconds(5),
registrationSecret,
10
);
LocalDistributor distributor = new LocalDistributor(
tracer,
eventBus,
httpClientFactory,
sessionMap,
sessionQueue,
slotSelector,
registrationSecret,
Duration.ofSeconds(120),
false,
Duration.ofSeconds(5),
4,
slotMatcher,
Duration.ofMinutes(5)
);
// Register node with distributor
distributor.add(node);Selenium Grid uses a modular, distributed architecture consisting of:
Components can run in the same process (Standalone mode) or distributed across multiple machines (Hub and Node mode).
Flexible configuration system supporting multiple sources (files, environment variables, command-line flags) with role-based configuration and type-safe access.
interface Config {
Set<String> getSectionNames();
Set<String> getOptions(String section);
Optional<String> get(String section, String option);
Optional<Integer> getInt(String section, String option);
Optional<Boolean> getBool(String section, String option);
<X> X getClass(String section, String option, Class<X> typeOfClass, String defaultClazz);
}
class Role implements Comparable<Role> {
Role(String roleName);
static Role of(String name);
String getRoleName();
}Core session management and distribution across grid nodes with load balancing, capacity management, and slot selection strategies.
abstract class Distributor {
protected Distributor(Tracer tracer, HttpClient.Factory httpClientFactory, Secret registrationSecret);
abstract Either<SessionNotCreatedException, CreateSessionResponse> newSession(SessionRequest request);
abstract Distributor add(Node node);
abstract boolean drain(NodeId nodeId);
abstract void remove(NodeId nodeId);
abstract DistributorStatus getStatus();
}
@FunctionalInterface
interface SlotSelector {
Set<SlotId> selectSlot(Capabilities capabilities, Set<NodeStatus> nodes, SlotMatcher slotMatcher);
}WebDriver session execution and browser lifecycle management with support for local and remote execution, Docker integration, and health monitoring.
abstract class Node {
protected Node(Tracer tracer, NodeId id, URI uri, Secret registrationSecret, Duration sessionTimeout);
abstract Either<WebDriverException, CreateSessionResponse> newSession(CreateSessionRequest sessionRequest);
abstract HttpResponse executeWebDriverCommand(HttpRequest req);
abstract Session getSession(SessionId id);
abstract void stop(SessionId id);
abstract boolean isSessionOwner(SessionId id);
abstract boolean isSupporting(Capabilities capabilities);
abstract NodeStatus getStatus();
abstract HealthCheck getHealthCheck();
abstract void drain();
NodeId getId();
URI getUri();
}HTTP request routing and WebDriver command processing with session resolution, WebSocket proxying, and status endpoints.
class Router {
Router(Tracer tracer, HttpClient.Factory clientFactory, SessionMap sessions,
NewSessionQueue queue, Distributor distributor);
boolean isReady();
boolean matches(HttpRequest req);
HttpResponse execute(HttpRequest req);
void close();
}Persistent session mapping and storage with support for in-memory, JDBC, and Redis backends for tracking active sessions across the grid.
interface SessionMap {
boolean isReady();
boolean add(Session session);
Session get(SessionId id);
void remove(SessionId id);
Set<Session> getSessions();
}Request queuing system for managing session creation requests when nodes are at capacity, with timeout handling and prioritization.
interface NewSessionQueue {
boolean isReady();
boolean offerLast(SessionRequest request, RequestId requestId);
Optional<SessionRequest> poll(Duration timeout);
int clear();
List<SessionRequest> getNextAvailable(Map<Capabilities, Long> stereotypes);
}Authentication and authorization framework with secret management, basic authentication, and request filtering for securing grid endpoints.
class Secret {
// Implementation hidden for security
}
class BasicAuthenticationFilter implements Filter {
// HTTP Basic Authentication implementation
}
class RequiresSecretFilter implements Filter {
// Secret validation filter
}Command-line interface for starting and managing grid components with configuration support and help system.
class Main {
public static void main(String[] args);
}
@AutoService(CliCommand.class)
class Hub extends TemplateGridServerCommand {
String getName();
Set<Role> getConfigurableRoles();
Set<Object> getFlagObjects();
Config getDefaultConfig();
Handlers<Route> createHandlers(Config config);
}class Session {
Session(SessionId id, URI uri, Capabilities stereotype, Capabilities capabilities, Instant startTime);
SessionId getId();
URI getUri();
Capabilities getStereotype();
Capabilities getCapabilities();
Instant getStartTime();
}
class NodeStatus {
NodeStatus(NodeId nodeId, URI externalUri, int maxSessionCount, Set<Slot> slots,
Availability availability, Duration heartbeatPeriod, Duration sessionTimeout,
String version, Map<String, String> osInfo);
boolean hasCapability(Capabilities caps, SlotMatcher slotMatcher);
boolean hasCapacity();
boolean hasCapacity(Capabilities caps, SlotMatcher slotMatcher);
NodeId getNodeId();
URI getExternalUri();
Set<Slot> getSlots();
Availability getAvailability();
float getLoad();
}
class Slot {
Slot(SlotId id, Capabilities stereotype, Instant lastStarted, Session session);
SlotId getId();
Capabilities getStereotype();
Session getSession();
boolean isSupporting(Capabilities caps, SlotMatcher slotMatcher);
}
enum Availability {
UP, DOWN, DRAINING
}
// Typed identifiers
class NodeId { /* UUID-based implementation */ }
class SlotId { /* UUID-based implementation */ }
class SessionId { /* UUID-based implementation */ }
class RequestId { /* UUID-based implementation */ }