feat: remaining baseUrl implementation bits (#515)
This commit is contained in:
@@ -26,6 +26,8 @@ import com.microsoft.playwright.options.FunctionCallback;
|
||||
import com.microsoft.playwright.options.Geolocation;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.MalformedURLException;
|
||||
import java.net.URL;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.nio.file.Path;
|
||||
import java.util.ArrayList;
|
||||
@@ -53,6 +55,7 @@ class BrowserContextImpl extends ChannelOwner implements BrowserContext {
|
||||
private final ListenerCollection<EventType> listeners = new ListenerCollection<>();
|
||||
final TimeoutSettings timeoutSettings = new TimeoutSettings();
|
||||
Path videosDir;
|
||||
URL baseUrl;
|
||||
|
||||
enum EventType {
|
||||
CLOSE,
|
||||
@@ -73,6 +76,14 @@ class BrowserContextImpl extends ChannelOwner implements BrowserContext {
|
||||
this.tracing = new TracingImpl(this);
|
||||
}
|
||||
|
||||
void setBaseUrl(String spec) {
|
||||
try {
|
||||
this.baseUrl = new URL(spec);
|
||||
} catch (MalformedURLException e) {
|
||||
this.baseUrl = null;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onClose(Consumer<BrowserContext> handler) {
|
||||
listeners.add(EventType.CLOSE, handler);
|
||||
@@ -307,7 +318,7 @@ class BrowserContextImpl extends ChannelOwner implements BrowserContext {
|
||||
|
||||
@Override
|
||||
public void route(String url, Consumer<Route> handler) {
|
||||
route(new UrlMatcher(url), handler);
|
||||
route(new UrlMatcher(this.baseUrl, url), handler);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -406,7 +417,7 @@ class BrowserContextImpl extends ChannelOwner implements BrowserContext {
|
||||
|
||||
@Override
|
||||
public void unroute(String url, Consumer<Route> handler) {
|
||||
unroute(new UrlMatcher(url), handler);
|
||||
unroute(new UrlMatcher(this.baseUrl, url), handler);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -171,6 +171,9 @@ class BrowserImpl extends ChannelOwner implements Browser {
|
||||
if (options.recordVideoDir != null) {
|
||||
context.videosDir = options.recordVideoDir;
|
||||
}
|
||||
if (options.baseURL != null) {
|
||||
context.setBaseUrl(options.baseURL);
|
||||
}
|
||||
contexts.add(context);
|
||||
return context;
|
||||
}
|
||||
|
||||
@@ -189,6 +189,9 @@ class BrowserTypeImpl extends ChannelOwner implements BrowserType {
|
||||
if (options.recordVideoDir != null) {
|
||||
context.videosDir = options.recordVideoDir;
|
||||
}
|
||||
if (options.baseURL != null) {
|
||||
context.setBaseUrl(options.baseURL);
|
||||
}
|
||||
return context;
|
||||
}
|
||||
|
||||
|
||||
@@ -885,7 +885,7 @@ public class FrameImpl extends ChannelOwner implements Frame {
|
||||
|
||||
List<Waitable<Response>> waitables = new ArrayList<>();
|
||||
if (matcher == null) {
|
||||
matcher = UrlMatcher.forOneOf(options.url);
|
||||
matcher = UrlMatcher.forOneOf(page.context().baseUrl, options.url);
|
||||
}
|
||||
waitables.add(new WaitForNavigationHelper(matcher, convertViaJson(options.waitUntil, LoadState.class)));
|
||||
waitables.add(page.createWaitForCloseHelper());
|
||||
@@ -930,7 +930,7 @@ public class FrameImpl extends ChannelOwner implements Frame {
|
||||
|
||||
@Override
|
||||
public void waitForURL(String url, WaitForURLOptions options) {
|
||||
waitForURL(new UrlMatcher(url), options);
|
||||
waitForURL(new UrlMatcher(page.context().baseUrl, url), options);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -716,7 +716,7 @@ public class PageImpl extends ChannelOwner implements Page {
|
||||
|
||||
@Override
|
||||
public Frame frameByUrl(String glob) {
|
||||
return frameFor(new UrlMatcher(glob));
|
||||
return frameFor(new UrlMatcher(browserContext.baseUrl, glob));
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -931,7 +931,7 @@ public class PageImpl extends ChannelOwner implements Page {
|
||||
|
||||
@Override
|
||||
public void route(String url, Consumer<Route> handler) {
|
||||
route(new UrlMatcher(url), handler);
|
||||
route(new UrlMatcher(browserContext.baseUrl, url), handler);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -1139,7 +1139,7 @@ public class PageImpl extends ChannelOwner implements Page {
|
||||
|
||||
@Override
|
||||
public void unroute(String url, Consumer<Route> handler) {
|
||||
unroute(new UrlMatcher(url), handler);
|
||||
unroute(new UrlMatcher(browserContext.baseUrl, url), handler);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -1276,7 +1276,7 @@ public class PageImpl extends ChannelOwner implements Page {
|
||||
|
||||
@Override
|
||||
public Request waitForRequest(String urlGlob, WaitForRequestOptions options, Runnable code) {
|
||||
return waitForRequest(toRequestPredicate(new UrlMatcher(urlGlob)), options, code);
|
||||
return waitForRequest(toRequestPredicate(new UrlMatcher(browserContext.baseUrl, urlGlob)), options, code);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -1325,7 +1325,7 @@ public class PageImpl extends ChannelOwner implements Page {
|
||||
|
||||
@Override
|
||||
public Response waitForResponse(String urlGlob, WaitForResponseOptions options, Runnable code) {
|
||||
return waitForResponse(toResponsePredicate(new UrlMatcher(urlGlob)), options, code);
|
||||
return waitForResponse(toResponsePredicate(new UrlMatcher(browserContext.baseUrl, urlGlob)), options, code);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -1367,7 +1367,7 @@ public class PageImpl extends ChannelOwner implements Page {
|
||||
|
||||
@Override
|
||||
public void waitForURL(String url, WaitForURLOptions options) {
|
||||
waitForURL(new UrlMatcher(url), options);
|
||||
waitForURL(new UrlMatcher(browserContext.baseUrl, url), options);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -18,6 +18,8 @@ package com.microsoft.playwright.impl;
|
||||
|
||||
import com.microsoft.playwright.PlaywrightException;
|
||||
|
||||
import java.net.MalformedURLException;
|
||||
import java.net.URL;
|
||||
import java.util.Objects;
|
||||
import java.util.function.Predicate;
|
||||
import java.util.regex.Pattern;
|
||||
@@ -33,15 +35,15 @@ class UrlMatcher {
|
||||
}
|
||||
|
||||
static UrlMatcher any() {
|
||||
return new UrlMatcher(null, null);
|
||||
return new UrlMatcher((Object) null, null);
|
||||
}
|
||||
|
||||
static UrlMatcher forOneOf(Object object) {
|
||||
static UrlMatcher forOneOf(URL baseUrl, Object object) {
|
||||
if (object == null) {
|
||||
return UrlMatcher.any();
|
||||
}
|
||||
if (object instanceof String) {
|
||||
return new UrlMatcher((String) object);
|
||||
return new UrlMatcher(baseUrl, (String) object);
|
||||
}
|
||||
if (object instanceof Pattern) {
|
||||
return new UrlMatcher((Pattern) object);
|
||||
@@ -52,8 +54,19 @@ class UrlMatcher {
|
||||
throw new PlaywrightException("Url must be String, Pattern or Predicate<String>, found: " + object.getClass().getTypeName());
|
||||
}
|
||||
|
||||
UrlMatcher(String url) {
|
||||
this(url, toPredicate(Pattern.compile(globToRegex(url))).or(s -> url == null || url.equals(s)));
|
||||
private static String resolveUrl(URL baseUrl, String spec) {
|
||||
if (baseUrl == null) {
|
||||
return spec;
|
||||
}
|
||||
try {
|
||||
return new URL(baseUrl, spec).toString();
|
||||
} catch (MalformedURLException e) {
|
||||
return spec;
|
||||
}
|
||||
}
|
||||
|
||||
UrlMatcher(URL base, String url) {
|
||||
this(url, toPredicate(Pattern.compile(globToRegex(resolveUrl(base, url)))).or(s -> url == null || url.equals(s)));
|
||||
}
|
||||
|
||||
UrlMatcher(Pattern pattern) {
|
||||
|
||||
@@ -189,6 +189,9 @@ public class Server implements HttpHandler {
|
||||
if (csp.containsKey(path)) {
|
||||
exchange.getResponseHeaders().add("Content-Security-Policy", csp.get(path));
|
||||
}
|
||||
if ("/".equals(path)) {
|
||||
path = "/index.html";
|
||||
}
|
||||
File file = new File(resourcesDir, path.substring(1));
|
||||
if (!file.exists()) {
|
||||
exchange.sendResponseHeaders(404, 0);
|
||||
|
||||
@@ -2,21 +2,78 @@ package com.microsoft.playwright;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import java.net.MalformedURLException;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertNotNull;
|
||||
|
||||
public class TestBrowserContextBaseUrl extends TestBase {
|
||||
@Test
|
||||
void shouldConstructANewURLWhenABaseURLInBrowserNewContextIsPassedToPageGoto() {
|
||||
BrowserContext context = browser.newContext(new Browser.NewContextOptions().setBaseURL(server.PREFIX));
|
||||
Page page = context.newPage();
|
||||
assertEquals(server.EMPTY_PAGE, (page.navigate("/empty.html")).url());
|
||||
context.close();
|
||||
void shouldConstructANewURLWhenABaseURLInBrowserNewContextIsPassedToPageGoto() throws MalformedURLException {
|
||||
try (BrowserContext context = browser.newContext(new Browser.NewContextOptions().setBaseURL(server.PREFIX))) {
|
||||
Page page = context.newPage();
|
||||
assertEquals(server.EMPTY_PAGE, page.navigate("/empty.html").url());
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldConstructANewURLWhenABaseURLInBrowserNewPageIsPassedToPageGoto() {
|
||||
Page page = browser.newPage(new Browser.NewPageOptions().setBaseURL(server.PREFIX));
|
||||
assertEquals(server.EMPTY_PAGE, (page.navigate("/empty.html")).url());
|
||||
page.close();
|
||||
try (Page page = browser.newPage(new Browser.NewPageOptions().setBaseURL(server.PREFIX))) {
|
||||
assertEquals(server.EMPTY_PAGE, page.navigate("/empty.html").url());
|
||||
}
|
||||
}
|
||||
@Test
|
||||
void shouldConstructTheURLsCorrectlyWhenABaseURLWithoutATrailingSlashInBrowserNewPageIsPassedToPageGoto() {
|
||||
try (Page page = browser.newPage(new Browser.NewPageOptions().setBaseURL(server.PREFIX + "/url-construction"))) {
|
||||
assertEquals(server.PREFIX + "/mypage.html", page.navigate("mypage.html").url());
|
||||
assertEquals(server.PREFIX + "/mypage.html", page.navigate("./mypage.html").url());
|
||||
assertEquals(server.PREFIX + "/mypage.html", page.navigate("/mypage.html").url());
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldConstructTheURLsCorrectlyWhenABaseURLWithATrailingSlashInBrowserNewPageIsPassedToPageGoto() {
|
||||
try (Page page = browser.newPage(new Browser.NewPageOptions().setBaseURL(server.PREFIX + "/url-construction/"))) {
|
||||
assertEquals(server.PREFIX + "/url-construction/mypage.html", page.navigate("mypage.html").url());
|
||||
assertEquals(server.PREFIX + "/url-construction/mypage.html", page.navigate("./mypage.html").url());
|
||||
assertEquals(server.PREFIX + "/mypage.html", page.navigate("/mypage.html").url());
|
||||
assertEquals(server.PREFIX + "/url-construction/", page.navigate(".").url());
|
||||
assertEquals(server.PREFIX + "/", page.navigate("/").url());
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldNotConstructANewURLWhenValidURLsArePassed() {
|
||||
try (Page page = browser.newPage(new Browser.NewPageOptions().setBaseURL("http://microsoft.com"))) {
|
||||
assertEquals(server.EMPTY_PAGE, page.navigate(server.EMPTY_PAGE).url());
|
||||
|
||||
page.navigate("data:text/html,Hello world");
|
||||
assertEquals("data:text/html,Hello world", page.evaluate("window.location.href"));
|
||||
|
||||
page.navigate("about:blank");
|
||||
assertEquals("about:blank", page.evaluate("window.location.href"));
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldBeAbleToMatchAURLRelativeToItsGivenURLWithUrlMatcher() {
|
||||
try (Page page = browser.newPage(new Browser.NewPageOptions().setBaseURL(server.PREFIX + "/foobar/"))) {
|
||||
page.navigate("/kek/index.html");
|
||||
page.waitForURL("/kek/index.html");
|
||||
assertEquals(server.PREFIX + "/kek/index.html", page.url());
|
||||
|
||||
page.route("./kek/index.html", route -> route.fulfill(new Route.FulfillOptions().setBody("base-url-matched-route")));
|
||||
Request[] request = {null};
|
||||
Response response = page.waitForResponse("./kek/index.html", () -> {
|
||||
request[0] = page.waitForRequest("./kek/index.html", () -> {
|
||||
page.navigate("./kek/index.html");
|
||||
});
|
||||
});
|
||||
assertNotNull(request[0]);
|
||||
assertNotNull(response);
|
||||
assertEquals(server.PREFIX + "/foobar/kek/index.html", request[0].url());
|
||||
assertEquals(server.PREFIX + "/foobar/kek/index.html", response.url());
|
||||
assertEquals("base-url-matched-route", response.text());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user