From 755c1e190d0515d78130f26c5380cb2b39645126 Mon Sep 17 00:00:00 2001 From: Max Schmitt Date: Thu, 12 Dec 2024 14:49:49 -0800 Subject: [PATCH] make tests pass --- .../PageRouteWebSocketTests.cs | 35 +++++++++++++++++ src/Playwright/Core/PageAssertions.cs | 2 +- src/Playwright/Helpers/URLMatch.cs | 39 ++++++++++--------- 3 files changed, 57 insertions(+), 19 deletions(-) diff --git a/src/Playwright.Tests/PageRouteWebSocketTests.cs b/src/Playwright.Tests/PageRouteWebSocketTests.cs index beea6a0bf..a529a99c8 100644 --- a/src/Playwright.Tests/PageRouteWebSocketTests.cs +++ b/src/Playwright.Tests/PageRouteWebSocketTests.cs @@ -311,4 +311,39 @@ await AssertAreEqualWithRetriesAsync(() => page.EvaluateAsync("() => w $"message: data=echo origin=ws://localhost:{Server.Port} lastEventId=", }); } + + [PlaywrightTest("page-route-web-socket.spec.ts", "should work with no trailing slash")] + public async Task ShouldWorkWithNoTrailingSlash() + { + var log = new List(); + // No trailing slash! + await Page.RouteWebSocketAsync($"ws://localhost:{Server.Port}", ws => + { + ws.OnMessage(message => + { + log.Add(message.Text); + ws.Send("response"); + }); + }); + + await Page.GotoAsync("about:blank"); + await Page.EvaluateAsync(@"({ port }) => { + window.log = []; + // No trailing slash in WebSocket URL + window.ws = new WebSocket('ws://localhost:' + port); + window.ws.addEventListener('message', event => window.log.push(event.data)); + }", new Dictionary + { + ["port"] = Server.Port + }); + + await Page.WaitForFunctionAsync("() => window.ws.readyState === 1"); + await Page.EvaluateAsync("() => window.ws.send('query')"); + await AssertAreEqualWithRetriesAsync( + () => Task.FromResult(log.ToArray()), + ["query"]); + await AssertAreEqualWithRetriesAsync( + () => Page.EvaluateAsync("() => window.log"), + ["response"]); + } } diff --git a/src/Playwright/Core/PageAssertions.cs b/src/Playwright/Core/PageAssertions.cs index 5512e5bf0..b909433ef 100644 --- a/src/Playwright/Core/PageAssertions.cs +++ b/src/Playwright/Core/PageAssertions.cs @@ -58,7 +58,7 @@ public Task ToHaveTitleAsync(Regex titleOrRegExp, PageAssertionsToHaveTitleOptio ExpectImplAsync("to.have.title", ExpectedRegex(titleOrRegExp, new() { NormalizeWhiteSpace = true }), titleOrRegExp, "Page title expected to be", ConvertToFrameExpectOptions(options)); public Task ToHaveURLAsync(string urlOrRegExp, PageAssertionsToHaveURLOptions options = null) => - ExpectImplAsync("to.have.url", new ExpectedTextValue() { String = URLMatch.JoinWithBaseURL(_page.Context.Options.BaseURL, urlOrRegExp), IgnoreCase = options?.IgnoreCase }, urlOrRegExp, "Page URL expected to be", ConvertToFrameExpectOptions(options)); + ExpectImplAsync("to.have.url", new ExpectedTextValue() { String = URLMatch.ConstructURLBasedOnBaseURL(_page.Context.Options.BaseURL, urlOrRegExp), IgnoreCase = options?.IgnoreCase }, urlOrRegExp, "Page URL expected to be", ConvertToFrameExpectOptions(options)); public Task ToHaveURLAsync(Regex urlOrRegExp, PageAssertionsToHaveURLOptions options = null) => ExpectImplAsync("to.have.url", ExpectedRegex(urlOrRegExp, new() { IgnoreCase = options?.IgnoreCase }), urlOrRegExp, "Page URL expected to match regex", ConvertToFrameExpectOptions(options)); diff --git a/src/Playwright/Helpers/URLMatch.cs b/src/Playwright/Helpers/URLMatch.cs index ff5c60922..3e22721ee 100644 --- a/src/Playwright/Helpers/URLMatch.cs +++ b/src/Playwright/Helpers/URLMatch.cs @@ -38,6 +38,11 @@ public class URLMatch public string baseURL { get; set; } public bool Match(string url) + { + return MatchImpl(url, re, func, glob, baseURL); + } + + private static bool MatchImpl(string url, Regex re, Func func, string glob, string baseURL) { if (re != null) { @@ -51,33 +56,31 @@ public bool Match(string url) if (glob != null) { - var globWithBaseURL = JoinWithBaseURL(baseURL, glob); - // Allow http(s) baseURL to match ws(s) urls. - if (new Regex("^https?://").IsMatch(globWithBaseURL) && new Regex("^wss?://").IsMatch(url)) + if (string.IsNullOrEmpty(glob)) + { + return true; + } + if (!glob.StartsWith("*", StringComparison.InvariantCultureIgnoreCase)) { - globWithBaseURL = new Regex("^http").Replace(globWithBaseURL, "ws"); + // Allow http(s) baseURL to match ws(s) urls. + if (new Regex("^https?://").IsMatch(baseURL) && new Regex("^wss?://").IsMatch(url)) + { + baseURL = new Regex("^http").Replace(baseURL, "ws"); + } + glob = ConstructURLBasedOnBaseURL(baseURL, glob); } - return new Regex(globWithBaseURL.GlobToRegex()).IsMatch(url); + return new Regex(glob.GlobToRegex()).IsMatch(url); } return true; } - internal static string JoinWithBaseURL(string baseUrl, string url) + internal static string ConstructURLBasedOnBaseURL(string baseUrl, string url) { - if (string.IsNullOrEmpty(baseUrl) - || (url?.StartsWith("*", StringComparison.InvariantCultureIgnoreCase) ?? false) - || !Uri.IsWellFormedUriString(url, UriKind.RelativeOrAbsolute)) + if (string.IsNullOrEmpty(baseUrl)) { - return url; + return new Uri(url, UriKind.Absolute).ToString(); } - - var mUri = new Uri(url, UriKind.RelativeOrAbsolute); - if (!mUri.IsAbsoluteUri) - { - return new Uri(new Uri(baseUrl), mUri).ToString(); - } - - return url; + return new Uri(new Uri(baseUrl), new Uri(url, UriKind.RelativeOrAbsolute)).ToString(); } public bool Equals(string globMatch, Regex reMatch, Func funcMatch, string baseURL)