Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
93 commits
Select commit Hold shift + click to select a range
97a1606
test(fixtures): add the harness for porting the upstream page and lib…
yury-s Oct 25, 2026
639663e
test(fixtures): add the ssim-cie94 image comparator of the upstream s…
yury-s Oct 25, 2026
105a967
test(fixtures): add the proxy and SOCKS servers of the upstream harness
yury-s Oct 25, 2026
e23a1da
test(fixtures): document launch option defaults and driver-version fi…
yury-s Oct 25, 2026
631d2bb
test(fixtures): compare ported titles with the it() title of the regi…
yury-s Oct 25, 2026
0bfc176
test(page): port elementhandle-*, page-emulate-media, page-event-page…
yury-s Oct 25, 2026
80a5adc
test(page): port page-aria-snapshot*, to-match-aria-snapshot, page-ad…
yury-s Oct 25, 2026
c0024a6
test(page): port page-click*, page-event-console, page-drag, page-dro…
yury-s Oct 25, 2026
e84982c
test(fixtures): document event futures and the concurrency caveat of …
yury-s Oct 25, 2026
3896730
test(page): port page-evaluate*, expect-boolean
yury-s Oct 25, 2026
e117bb5
test(page): port page-network-*, page-event-network, page-event-reque…
yury-s Oct 25, 2026
d90d849
test(fixtures): support status messages, repeated headers and route-s…
yury-s Oct 25, 2026
b8d6c52
test(page): port selectors-get-by, selectors-frame, selectors-misc, s…
yury-s Oct 25, 2026
43f079a
test(page): port expect-misc, expect-timeout, expect-to-have-*, page-…
yury-s Oct 25, 2026
6ddd74d
test(page): drop the markdown escapes of the registry from the page-f…
yury-s Oct 25, 2026
60dc444
fix(client): dispatch driver messages in order when several threads u…
yury-s Oct 25, 2026
359c4ff
test(fixtures): note the ordered dispatch of the client in the async …
yury-s Oct 26, 2026
883eba5
test(page): port locator-frame, locator-highlight, locator-is-visible…
yury-s Oct 26, 2026
84cc3b5
test(page): port page-route, page-request-*, interception, selectors-…
yury-s Oct 26, 2026
259081a
test(page): port frame-hierarchy, page-set-input-files, page-add-init…
yury-s Oct 26, 2026
85ae119
test(page): port the network and screenshot tests the harness now sup…
yury-s Oct 26, 2026
a6abfc3
test(page): port page-wait-for-selector-*, page-wait-for-load-state, …
yury-s Oct 26, 2026
84cd2a2
test(page): drop a duplicated not-ported entry
yury-s Oct 26, 2026
9f15c0b
test(page): mark the wait log assertions of WA-033 and WA-109 as Java…
yury-s Oct 26, 2026
4e24a7c
test(library): port browsercontext-{credentials,webauthn,basic,events…
yury-s Oct 26, 2026
2c131ad
test: drop the not-ported entries duplicated by the batch merge
yury-s Oct 26, 2026
f58aa57
test(library): port tracing, chromium/tracing, browsercontext-{timezo…
yury-s Oct 26, 2026
ce3fe37
fix(browser): send the screenSize context option as the protocol's sc…
yury-s Oct 26, 2026
8bcfac7
test(library): port chromium/{connect-over-cdp,session,chromium,launc…
yury-s Oct 26, 2026
58a2d41
test(library): port defaultbrowsercontext-*, download, downloads-path…
yury-s Oct 26, 2026
73ad2e5
test(fixtures): track the zip files of the upstream assets despite .g…
yury-s Oct 26, 2026
ba821ea
test(fixtures): let @Fixme expect the failure of some parameters of a…
yury-s Oct 26, 2026
b52afbb
test(fixtures): notice a browser closing the connection while a route…
yury-s Oct 26, 2026
dcbe472
test(library): port browsercontext-proxy, fetch-proxy, browsercontext…
yury-s Oct 26, 2026
f7d1f81
test(library): port browsercontext-fetch*, firefox/launcher, geolocat…
yury-s Oct 26, 2026
eb6adcb
fix(context): attach HAR content for a .zip path and tolerate a dispo…
yury-s Oct 26, 2026
045e598
test(fixtures): add the remote server and child process utilities of …
yury-s Oct 26, 2026
9def1d8
test(fixtures): let @Fixme expect a hang, used for the connect() call…
yury-s Oct 26, 2026
23085ce
test(library): port headful, hit-target, browsercontext-{add-init-scr…
yury-s Oct 26, 2026
84c96c5
test: time out a test method after two minutes so that a hang cannot …
yury-s Oct 26, 2026
f8f2d22
test: port promises awaited later without a second thread, the Java A…
yury-s Oct 26, 2026
7588d3b
test: port TestSelectorsText, TestPageSetContent and 13 more without …
yury-s Oct 26, 2026
4ccb7f8
test: port TestPageClick, TestPageWaitForSelector1, TestPageAutowaiti…
yury-s Oct 26, 2026
231b2d7
fix(screenshot): reject a path with an unsupported extension like the…
yury-s Oct 26, 2026
7f24e7b
test: port TestPageWaitForSelector2, TestElementhandleWaitForElementS…
yury-s Oct 26, 2026
74dc25d
test(library): expect CO-054 to fail on the Firefox build of the bund…
yury-s Oct 26, 2026
2243df3
test: port TestPageWaitForNavigation, TestPageWaitForFunction, TestPa…
yury-s Oct 26, 2026
69f91ab
test: port TestExpectBoolean, TestExpectMisc, TestExpectToHaveText, T…
yury-s Oct 26, 2026
2cb048a
test: port TestTracing and 16 other library test classes without a se…
yury-s Oct 26, 2026
cd67675
test: port page tests without a second thread
yury-s Oct 26, 2026
646512a
chore(test): remove a stray copy of MockSocksServer left by an agent
yury-s Oct 26, 2026
2279d4d
fix(screenshot): only derive the type from the path when no type opti…
yury-s Oct 26, 2026
1eb1201
Revert "fix(client): dispatch driver messages in order when several t…
yury-s Oct 26, 2026
fbe9b37
test: port TestUnrouteBehavior, TestPageClose, TestBrowsertypeConnect…
yury-s Oct 26, 2026
7cd39e9
test(fixtures): drop the thread helper, every ported test uses Playwr…
yury-s Oct 26, 2026
2fe7741
test: drop the unused imports of the removed thread helper
yury-s Oct 26, 2026
34b624b
docs(fixtures): describe the servers, remote server and child process…
yury-s Oct 26, 2026
dbdb7b7
chore(fixtures): remove the stray agent copies of harness files
yury-s Oct 26, 2026
fc0f8c9
test(fixtures): complete waitForRequest after the route handler has run
yury-s Oct 26, 2026
48d4993
test(fixtures): register the fixme interceptor only for @Fixme tests
yury-s Oct 26, 2026
2c31722
test(page): mark pagePauseShouldNotThrow as an expected failure under…
yury-s Oct 26, 2026
c9fe83c
test(port): port 25 concurrent tests with callback waits and page-sid…
yury-s Oct 26, 2026
7aff0ef
docs(port): prompt for rewriting upstream tests that await an evaluat…
yury-s Oct 26, 2026
ad71749
docs(port): keep the tests about rejected pending calls out of the up…
yury-s Oct 26, 2026
adb8a58
test(library): port TR-041 from the upstream rewrite around a console…
yury-s Oct 26, 2026
fd35106
fix(tracing): title the waits in the trace like the Node.js client
yury-s Oct 26, 2026
4c1459a
docs(port): record the upstream commit the test port is based on
yury-s Oct 26, 2026
84478ba
test(port): list NA-078 as concurrent instead of porting it with timers
yury-s Oct 27, 2026
47c3956
devops: use JUnit 5.14.1 in the local installation test project
yury-s Oct 27, 2026
7475c7d
devops: run the Linux tests under xvfb and allow 90 minutes per job
yury-s Oct 27, 2026
2ff0980
test(port): restore the default test id attribute after each test
yury-s Oct 27, 2026
d3891bf
test(port): make paths relative to the working directory like Node.js
yury-s Oct 27, 2026
eb64614
test(port): expect the Fixme failures only on the platforms where the…
yury-s Oct 27, 2026
93cdd84
test(port): collect the sources of the ported tests in traces
yury-s Oct 27, 2026
6524fa9
fix(driver): pass the env of each Playwright instance to its driver p…
yury-s Oct 27, 2026
9f65b31
fix(route): ignore close errors of the pattern update after a route
yury-s Oct 27, 2026
6249534
test(port): kill the child process on Windows when Java 8 can not tel…
yury-s Oct 27, 2026
1caeb80
test(port): print the threads when a test with its fixtures runs 5 mi…
yury-s Oct 27, 2026
fda7b2b
test: disable pagePauseShouldNotThrow until the driver roll
yury-s Oct 27, 2026
2f7a40e
test(port): fix TZ-006 and NE-024 on Windows
yury-s Oct 27, 2026
cdc5373
fix(navigation): fail the navigation waits at once on a closed page
yury-s Oct 27, 2026
f148616
test(port): remove the Fixme of the CDP tests that pass with the env fix
yury-s Oct 27, 2026
e3ea36a
test(port): use a free port for the CDP tests
yury-s Oct 27, 2026
a7fe6c6
test(port): quote the child process arguments on Windows
yury-s Oct 27, 2026
6333c39
test(port): run one test per core at a time
yury-s Oct 27, 2026
4dbba5b
test(port): collect only log messages in CL-017, Edge on macOS logs t…
yury-s Oct 27, 2026
dd6d685
test(port): disable SS-027 in Chromium
yury-s Oct 27, 2026
d90d726
test(port): interrupt the test thread after a Fixme timeout
yury-s Oct 27, 2026
d3cc43e
test(port): expect PR-024 localhost to fail in WebKit on macOS 26
yury-s Oct 27, 2026
a20c98f
fix(driver): extract the driver on one thread at a time
yury-s Oct 27, 2026
754f980
test: run the test methods in parallel
yury-s Oct 27, 2026
5fe2bf0
test: run 16 tests at once on Windows, like upstream
yury-s Oct 27, 2026
3ffc091
test: let the OS pick the port of the old test server
yury-s Oct 27, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
14 changes: 7 additions & 7 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ env:
PW_MAX_RETRIES: 3
jobs:
dev:
timeout-minutes: 30
timeout-minutes: 90
strategy:
fail-fast: false
matrix:
Expand All @@ -34,11 +34,11 @@ jobs:
- name: Install browsers
run: mvn exec:java -e -D exec.mainClass=com.microsoft.playwright.CLI -D exec.args="install --with-deps" -f playwright/pom.xml --no-transfer-progress
- name: Run tests
run: mvn test --no-transfer-progress --fail-at-end -D org.slf4j.simpleLogger.showDateTime=true -D org.slf4j.simpleLogger.dateTimeFormat=HH:mm:ss
run: ${{ runner.os == 'Linux' && 'xvfb-run --auto-servernum --server-args="-screen 0 1280x960x24"' || '' }} mvn test --no-transfer-progress --fail-at-end ${{ runner.os == 'Windows' && '-D junit.parallel.factor=0.25' || '' }} -D org.slf4j.simpleLogger.showDateTime=true -D org.slf4j.simpleLogger.dateTimeFormat=HH:mm:ss
env:
BROWSER: ${{ matrix.browser }}
- name: Run tracing tests w/ sources
run: mvn test --no-transfer-progress --fail-at-end --projects=playwright -D test=*TestTracing* -D org.slf4j.simpleLogger.showDateTime=true -D org.slf4j.simpleLogger.dateTimeFormat=HH:mm:ss
run: ${{ runner.os == 'Linux' && 'xvfb-run --auto-servernum --server-args="-screen 0 1280x960x24"' || '' }} mvn test --no-transfer-progress --fail-at-end --projects=playwright -D test=*TestTracing* -D org.slf4j.simpleLogger.showDateTime=true -D org.slf4j.simpleLogger.dateTimeFormat=HH:mm:ss
env:
BROWSER: ${{ matrix.browser }}
PLAYWRIGHT_JAVA_SRC: src/test/java
Expand All @@ -52,7 +52,7 @@ jobs:
java -jar target/test-spring-boot*.jar

stable:
timeout-minutes: 30
timeout-minutes: 90
strategy:
fail-fast: false
matrix:
Expand Down Expand Up @@ -81,13 +81,13 @@ jobs:
- name: Install browsers
run: mvn exec:java -e -D exec.mainClass=com.microsoft.playwright.CLI -D exec.args="install --with-deps" -f playwright/pom.xml --no-transfer-progress
- name: Run tests
run: mvn test --no-transfer-progress --fail-at-end -D org.slf4j.simpleLogger.showDateTime=true -D org.slf4j.simpleLogger.dateTimeFormat=HH:mm:ss
run: ${{ runner.os == 'Linux' && 'xvfb-run --auto-servernum --server-args="-screen 0 1280x960x24"' || '' }} mvn test --no-transfer-progress --fail-at-end ${{ runner.os == 'Windows' && '-D junit.parallel.factor=0.25' || '' }} -D org.slf4j.simpleLogger.showDateTime=true -D org.slf4j.simpleLogger.dateTimeFormat=HH:mm:ss
env:
BROWSER: chromium
BROWSER_CHANNEL: ${{ matrix.browser-channel }}

Java_25:
timeout-minutes: 30
timeout-minutes: 90
strategy:
fail-fast: false
matrix:
Expand All @@ -111,7 +111,7 @@ jobs:
- name: Install browsers
run: mvn exec:java -e -D exec.mainClass=com.microsoft.playwright.CLI -D exec.args="install --with-deps" -f playwright/pom.xml --no-transfer-progress
- name: Run tests
run: mvn test --no-transfer-progress --fail-at-end
run: xvfb-run --auto-servernum --server-args="-screen 0 1280x960x24" mvn test --no-transfer-progress --fail-at-end
env:
BROWSER: ${{ matrix.browser }}
- name: Test Spring Boot Starter
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -139,16 +139,19 @@ public static URI getDriverResourceURI() throws URISyntaxException {
}

void extractDriverToTempDir() throws URISyntaxException, IOException {
extractResourceToDir("driver/package", driverTempDir.resolve("package"));
if (preinstalledNodePath == null) {
String platformResource = "driver/" + platformDir();
if (DriverJar.class.getClassLoader().getResource(platformResource) == null) {
throw new RuntimeException("Failed to find the bundled Node.js for platform '" + platformDir()
+ "'. Add the com.microsoft.playwright:driver-bundle dependency, or set the "
+ PLAYWRIGHT_NODEJS_PATH + " environment variable (or the playwright.nodejs.path system "
+ "property) to point at a preinstalled Node.js.");
// Concurrent extractions would share the zip file system of the jar, and the first one to finish closes it.
synchronized (DriverJar.class) {
extractResourceToDir("driver/package", driverTempDir.resolve("package"));
if (preinstalledNodePath == null) {
String platformResource = "driver/" + platformDir();
if (DriverJar.class.getClassLoader().getResource(platformResource) == null) {
throw new RuntimeException("Failed to find the bundled Node.js for platform '" + platformDir()
+ "'. Add the com.microsoft.playwright:driver-bundle dependency, or set the "
+ PLAYWRIGHT_NODEJS_PATH + " environment variable (or the playwright.nodejs.path system "
+ "property) to point at a preinstalled Node.js.");
}
extractResourceToDir(platformResource, driverTempDir);
}
extractResourceToDir(platformResource, driverTempDir);
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -743,7 +743,14 @@ private void updateWebSocketInterceptionPatterns() {
void handleRoute(RouteImpl route) {
Router.HandleResult handled = routes.handle(route);
if (handled != Router.HandleResult.NoMatchingHandler) {
updateInterceptionPatterns();
try {
updateInterceptionPatterns();
} catch (PlaywrightException e) {
// Like the Node.js client, ignore the error when the page or the context was closed meanwhile.
if (!isSafeCloseError(e)) {
throw e;
}
}
}
if (handled == Router.HandleResult.NoMatchingHandler || handled == Router.HandleResult.Fallback) {
route.resume(null, true);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -847,8 +847,8 @@ private void waitForLoadStateImpl(WaitUntilState state, WaitForLoadStateOptions
}

List<Waitable<Void>> waitables = new ArrayList<>();
waitables.add(page.createWaitForCloseHelper(true));
waitables.add(new WaitForLoadStateHelper(state, logger));
waitables.add(page.createWaitForCloseHelper());
waitables.add(page.createWaitableTimeout(options.timeout));
runUntil(() -> {}, new WaitableRace<>(waitables));
}
Expand Down Expand Up @@ -982,7 +982,7 @@ private Response waitForNavigationImpl(Logger logger, Runnable code, WaitForNavi
}
logger.log("waiting for navigation " + matcher);
waitables.add(new WaitForNavigationHelper(matcher, options.waitUntil, logger));
waitables.add(page.createWaitForCloseHelper());
waitables.add(page.createWaitForCloseHelper(true));
waitables.add(page.createWaitableFrameDetach(this));
waitables.add(page.createWaitableNavigationTimeout(options.timeout));
return runUntil(code, new WaitableRace<>(waitables));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -225,7 +225,14 @@ protected void handleEvent(String event, JsonObject params) {
route.browserContext = browserContext;
Router.HandleResult handled = routes.handle(route);
if (handled != Router.HandleResult.NoMatchingHandler) {
updateInterceptionPatterns();
try {
updateInterceptionPatterns();
} catch (PlaywrightException e) {
// Like the Node.js client, ignore the error when the page or the context was closed meanwhile.
if (!isSafeCloseError(e)) {
throw e;
}
}
}
if (handled == Router.HandleResult.NoMatchingHandler || handled == Router.HandleResult.Fallback) {
browserContext.handleRoute(route);
Expand Down Expand Up @@ -1513,12 +1520,25 @@ <T> Waitable<T> createWaitableFrameDetach(Frame frame) {
}

<T> Waitable<T> createWaitForCloseHelper() {
return new WaitableRace<T>(asList(new WaitablePageClose(), new WaitablePageCrash()));
return createWaitForCloseHelper(false);
}

/** With {@code rejectIfClosed}, it is done at once when the page is already closed, like the navigation waiter of the Node.js client. */
<T> Waitable<T> createWaitForCloseHelper(boolean rejectIfClosed) {
return new WaitableRace<T>(asList(new WaitablePageClose(rejectIfClosed && isClosed), new WaitablePageCrash()));
}

private class WaitablePageClose<T> extends WaitableEvent<EventType, T> {
WaitablePageClose() {
private final boolean closedBefore;

WaitablePageClose(boolean closedBefore) {
super(PageImpl.this.listeners, EventType.CLOSE);
this.closedBefore = closedBefore;
}

@Override
public boolean isDone() {
return closedBefore || super.isDone();
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,8 @@ public static PlaywrightImpl createImpl(CreateOptions options, boolean forceNewD
Driver.ensureDriverInstalled(env, true);
try {
ProcessBuilder pb = driver.createProcessBuilder();
// The driver is installed once per JVM with the env of the first instance, so add the env of this one.
pb.environment().putAll(env);
pb.command().add("run-driver");
pb.redirectError(ProcessBuilder.Redirect.INHERIT);
Process p = pb.start();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,8 @@ JsonArray currentStackTrace() {
// Find Playwright API call
while (index < stack.length && stack[index].getClassName().startsWith("com.microsoft.playwright.")) {
// hack for tests
if (stack[index].getClassName().startsWith("com.microsoft.playwright.Test")) {
if (stack[index].getClassName().startsWith("com.microsoft.playwright.Test")
|| stack[index].getClassName().startsWith("com.microsoft.playwright.tests.")) {
break;
}
index++;
Expand Down
Loading
Loading