- Documentation
- Quick Start Guide
- Selenium Grid Configuration
- Auto Scaling
- Spot Instance Nodes
- Selenium Grid Integration
- Pre Launch API Integration
- Selenium Grid V4 Examples
- Selenium Grid V3 Examples
- Performance Testing
Playwright Selenium Grid Example
The Playwright selenium grid example below can quickly be run on a free Gridlastic selenium grid and at much lower cost per minute than other cloud services.
PlaywrightGridTests.java
package com.gridlastic.samples;
import com.microsoft.playwright.Browser;
import com.microsoft.playwright.BrowserContext;
import com.microsoft.playwright.BrowserType;
import com.microsoft.playwright.Page;
import com.microsoft.playwright.Playwright;
import com.microsoft.playwright.Playwright.CreateOptions;
import org.testng.Assert;
import org.testng.ITestContext;
import org.testng.ITestResult;
import org.testng.annotations.AfterMethod;
import org.testng.annotations.BeforeSuite;
import org.testng.annotations.Parameters;
import org.testng.annotations.Test;
import java.util.Base64;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class PlaywrightGridTests {
private String browserChannel;
private CreateOptions createOptions;
private String seleniumCapabilities;
private String videoUrlBase;
private String videoUrl;
@Parameters({"browserChannel"})
@BeforeSuite
public void initializeTestSuite(String browserChannel) {
this.browserChannel = browserChannel;
String seleniumRemoteUrl = System.getenv("SELENIUM_REMOTE_URL");
seleniumCapabilities = System.getenv("SELENIUM_REMOTE_CAPABILITIES");
videoUrlBase = System.getenv("VIDEO_URL_BASE");
String gridUsername = System.getenv("GRIDLASTIC_GRID_USERNAME");
String gridPassword = System.getenv("GRIDLASTIC_GRID_PASSWORD");
if (seleniumRemoteUrl == null
|| gridUsername == null
|| gridPassword == null
|| seleniumCapabilities == null
|| videoUrlBase == null) {
throw new IllegalStateException("Missing required environment variables: SELENIUM_REMOTE_URL, GRIDLASTIC_GRID_USERNAME, GRIDLASTIC_GRID_PASSWORD, SELENIUM_REMOTE_CAPABILITIES, or VIDEO_URL_BASE");
}
String credentials = gridUsername + ":" + gridPassword;
String encoded = Base64.getEncoder().encodeToString(credentials.getBytes());
String seleniumRemoteHeaders = "{\"Authorization\":\"Basic " + encoded + "\"}";
Map env = new HashMap<>(System.getenv());
env.put("SELENIUM_REMOTE_HEADERS", seleniumRemoteHeaders);
this.createOptions = new CreateOptions().setEnv(env);
}
@Test
public void test_1() {
try (Playwright playwright = createRemotePlaywright()) {
BrowserType.LaunchOptions launchOptions = createLaunchOptions();
try (Browser browser = playwright.chromium().launch(launchOptions);
BrowserContext context = browser.newContext(createNewContextOptions());
Page page = context.newPage()) {
logRemoteSession(page);
page.navigate("https://www.gridlastic.com/?demo");
Assert.assertTrue(page.title().toLowerCase().contains("selenium grid"),
browserChannel + " should open the Gridlastic demo page");
page.waitForTimeout(5000); // Wait 5 seconds for demo purposes
}
}
}
@Test
public void test_2_bidi() {
try (Playwright playwright = createRemotePlaywright()) {
BrowserType.LaunchOptions launchOptions = createLaunchOptions();
try (Browser browser = playwright.chromium().launch(launchOptions);
BrowserContext context = browser.newContext(createNewContextOptions());
Page page = context.newPage()) {
logRemoteSession(page);
// 1. BiDi Demo Feature: Asynchronous Console Listener
page.onConsoleMessage(msg -> System.out.println(String.format(
"[BiDi Console Event] [%s] Text: %s",
msg.type().toUpperCase(),
msg.text()
)));
// 2. BiDi Demo Feature: Asynchronous Network Request Listener
page.onRequest(request -> System.out.println(String.format(
"[BiDi Network Event] Outbound -> Method: %s | URL: %s",
request.method(),
request.url()
)));
System.out.println("--- Starting BiDi Traffic Interception ---");
// Navigate to a page to trigger network requests and intrinsic page logs
page.navigate("https://www.gridlastic.com/?demo");
// Execute some JavaScript to manually fire a browser log action
page.evaluate("console.error('Simulated Critical App Failure message via BiDi!');");
// Give the async WebSocket streams a brief window to complete delivery
page.waitForTimeout(2000);
System.out.println("--- Demonstration Complete ---");
}
}
}
private Playwright createRemotePlaywright() {
return Playwright.create(createOptions);
}
private BrowserType.LaunchOptions createLaunchOptions() {
return new BrowserType.LaunchOptions()
.setChannel(browserChannel)
.setHeadless(false)
.setArgs(List.of("--start-maximized"))
.setTimeout(600000); // give time to launch grid nodes and start session
}
private Browser.NewContextOptions createNewContextOptions() {
Browser.NewContextOptions options = new Browser.NewContextOptions();
if ("linux".equalsIgnoreCase(getCapabilityValue("platformName"))) {
options.setViewportSize(1920, 1080);
} else {
options.setViewportSize(null);
}
return options;
}
@AfterMethod(alwaysRun = true)
public void logTestCompletion(ITestResult result, ITestContext context) {
String suiteName = context.getSuite().getName();
String testName = result.getMethod().getMethodName();
String platformName = getCapabilityValue("platformName");
String browserName = getCapabilityValue("browserName");
String browserVersion = getCapabilityValue("browserVersion");
boolean videoEnabled = isVideoEnabled();
StringBuilder output = new StringBuilder()
.append("Test suite: ").append(suiteName)
.append(", Test name: ").append(testName)
.append(", Capabilities: platformName=").append(platformName)
.append(", browserName=").append(browserName)
.append(", browserVersion=").append(browserVersion)
.append(", video=").append(videoEnabled);
if (videoEnabled) {
output.append(", Video URL=")
.append(videoUrl != null ? videoUrl : "not available");
}
System.out.println(output.toString());
}
private String getCapabilityValue(String key) {
if (seleniumCapabilities == null) {
return "unknown";
}
String regex = "[\\\"']" + key + "[\\\"']\\s*:\\s*[\\\"']([^\\\"']+)[\\\"']";
java.util.regex.Matcher matcher = java.util.regex.Pattern.compile(regex).matcher(seleniumCapabilities);
return matcher.find() ? matcher.group(1) : "unknown";
}
private boolean isVideoEnabled() {
return seleniumCapabilities != null && seleniumCapabilities.matches("(?i).*\\\"video\\\"\\s*:\\s*true.*");
}
private String logRemoteSession(Page page) {
page.navigate("http://localhost:62000/get-selenium-session-id");
String seleniumSessionId = page.innerText("body").trim();
videoUrl = videoUrlBase + seleniumSessionId;
return seleniumSessionId;
}
}
Example Resources - EdgeSuite.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE suite SYSTEM "https://testng.org/testng-1.0.dtd">
<suite name="EdgeGridSuite" parallel="methods" thread-count="2">
<parameter name="browserChannel" value="msedge"/>
<test name="EdgeRemoteTests">
<classes>
<class name="com.gridlastic.samples.PlaywrightGridTests"/>
</classes>
</test>
</suite>
Main POM
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.gridlastic.samples</groupId>
<artifactId>Playwright_Selenium_Bridge</artifactId>
<version>1.0-SNAPSHOT</version>
<properties>
<maven.compiler.source>17</maven.compiler.source>
<maven.compiler.target>17</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<dependency>
<groupId>com.microsoft.playwright</groupId>
<artifactId>playwright</artifactId>
<version>1.59.0</version>
</dependency>
<dependency>
<groupId>org.testng</groupId>
<artifactId>testng</artifactId>
<version>7.8.0</version>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>3.2.5</version>
<configuration>
<skipTests>true</skipTests>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-invoker-plugin</artifactId>
<version>3.6.0</version>
<configuration>
<projectsDirectory>${project.basedir}</projectsDirectory>
<cloneProjectsTo>${project.build.directory}/invoker-tests</cloneProjectsTo>
<pomIncludes>
<pomInclude>test-poms/chrome-win10-pom.xml</pomInclude>
<pomInclude>test-poms/chrome-win11-pom.xml</pomInclude>
<pomInclude>test-poms/chrome-linux-pom.xml</pomInclude>
<pomInclude>test-poms/edge-win10-pom.xml</pomInclude>
<pomInclude>test-poms/edge-win11-pom.xml</pomInclude>
<pomInclude>test-poms/edge-linux-pom.xml</pomInclude>
</pomIncludes>
<parallelThreads>6</parallelThreads>
<goals>
<goal>test</goal>
</goals>
<streamLogs>true</streamLogs>
</configuration>
<executions>
<execution>
<id>integration-test</id>
<phase>test</phase>
<goals>
<goal>run</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
Example test POM
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.gridlastic.samples</groupId>
<artifactId>test-edge-linux</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>jar</packaging>
<properties>
<maven.compiler.source>17</maven.compiler.source>
<maven.compiler.target>17</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<dependency>
<groupId>com.microsoft.playwright</groupId>
<artifactId>playwright</artifactId>
<version>1.59.0</version>
</dependency>
<dependency>
<groupId>org.testng</groupId>
<artifactId>testng</artifactId>
<version>7.8.0</version>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<sourceDirectory>../src/main/java</sourceDirectory>
<testSourceDirectory>../src/test/java</testSourceDirectory>
<testResources>
<testResource>
<directory>../src/test/resources</directory>
</testResource>
</testResources>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>3.1.2</version>
<configuration>
<suiteXmlFiles>
<suiteXmlFile>../src/test/resources/EdgeSuite.xml</suiteXmlFile>
</suiteXmlFiles>
<environmentVariables>
<SELENIUM_REMOTE_CAPABILITIES>{"webSocketUrl":true,"platformName":"linux","browserName":"MicrosoftEdge","browserVersion":"latest","gridlastic:options":{"video":true}}</SELENIUM_REMOTE_CAPABILITIES>
</environmentVariables>
</configuration>
</plugin>
</plugins>
</build>
</project>
The Gridlastic grid hub, credentials and video url used in these code examples are presented after launching your Gridlastic selenium grid.
Get a free account and launch your Gridlastic selenium grid, then run this code locally and test your grid!
Try our
SELENIUM GRID DEMO
