From 62c61c98148fa8450e78422c716c8740fc6e871f Mon Sep 17 00:00:00 2001 From: Max Schmitt Date: Mon, 27 Jan 2025 16:24:42 +0100 Subject: [PATCH] fix(urlMatcher): normalize URLs to align with Node.js parser behavior --- .../microsoft/playwright/impl/UrlMatcher.java | 18 +++++++- .../playwright/TestRouteWebSocket.java | 42 +++++++++++++++++++ 2 files changed, 59 insertions(+), 1 deletion(-) diff --git a/playwright/src/main/java/com/microsoft/playwright/impl/UrlMatcher.java b/playwright/src/main/java/com/microsoft/playwright/impl/UrlMatcher.java index 1fde5359..0129146d 100644 --- a/playwright/src/main/java/com/microsoft/playwright/impl/UrlMatcher.java +++ b/playwright/src/main/java/com/microsoft/playwright/impl/UrlMatcher.java @@ -21,6 +21,7 @@ import java.net.URI; import java.net.URISyntaxException; import java.net.URL; +import java.util.Arrays; import java.util.function.Predicate; import java.util.regex.Pattern; @@ -65,6 +66,21 @@ private static String resolveUrl(String baseUrl, String spec) { } } + private static String normaliseUrl(String spec) { + try { + // Align with the Node.js URL parser which automatically adds a slash to the path if it is empty. + URI url = new URI(spec); + if (url.getScheme() != null && + Arrays.asList("http", "https", "ws", "wss").contains(url.getScheme()) && + url.getPath().isEmpty()) { + return new URI(url.getScheme(), url.getAuthority(), "/", url.getQuery(), url.getFragment()).toString(); + } + return url.toString(); + } catch (URISyntaxException e) { + return spec; + } + } + UrlMatcher(URL baseURL, String glob) { this(baseURL, glob, null, null); } @@ -101,7 +117,7 @@ private static boolean testImpl(String baseURL, Pattern pattern, Predicate log = new ArrayList<>(); + + // No trailing slash in the route pattern + page.routeWebSocket("ws://localhost:" + webSocketServer.getPort(), ws -> { + ws.onMessage(message -> { + log.add(message.text()); + ws.send("response"); + }); + }); + + page.navigate("about:blank"); + page.evaluate("({ port }) => {\n" + + " window.log = [];\n" + + " // No trailing slash in WebSocket URL\n" + + " window.ws = new WebSocket('ws://localhost:' + port);\n" + + " window.ws.addEventListener('message', event => window.log.push(event.data));\n" + + "}", mapOf("port", webSocketServer.getPort())); + + // Wait for WebSocket to be ready (readyState === 1) + page.waitForCondition(() -> { + Integer result = (Integer) page.evaluate("() => window.ws.readyState"); + return result == 1; + }); + + page.evaluate("() => window.ws.send('query')"); + + // Wait and verify server received message + page.waitForCondition(() -> log.size() >= 1); + assertEquals(asList("query"), log); + + // Wait and verify client received response + page.waitForCondition(() -> { + Boolean result = (Boolean) page.evaluate("() => window.log.length >= 1"); + return result; + }); + assertEquals(asList("response"), page.evaluate("window.log")); + } }