* Open a browser window with given URL and credentials for basic authentication - * + *
* If browser window was already opened before, it will be reused. - * + *
* Don't bother about closing the browser - it will be closed automatically when all your tests are done. - * - * @param relativeOrAbsoluteUrl - * @param domain - * @param login - * @param password - * If not starting with "http://" or "https://" or "file://", it's considered to be relative URL. - * In this case, it's prepended by baseUrl + *
+ * If not starting with "http://" or "https://" or "file://", it's considered to be relative URL. + *
+ * In this case, it's prepended by baseUrl */ public static void open(String relativeOrAbsoluteUrl, String domain, String login, String password) { navigator.open(relativeOrAbsoluteUrl, domain, login, password); mockModalDialogs(); } + /** + * The main starting point in your tests. + *
+ * Open browser and pass authentication using build-in proxy. + *
+ * A common authenticationType is "Basic". See Web HTTP reference for other types. + *
+ * This method can only work if - {@code Configuration.fileDownload == Configuration.FileDownloadMode.PROXY;} + * + * @see Web HTTP reference + * @see AuthenticationType + */ + public static void open(String relativeOrAbsoluteUrl, AuthenticationType authenticationType, String login, String password) { + Credentials credentials = new Credentials(login, password); + open(relativeOrAbsoluteUrl, authenticationType, credentials); + } + + /** + * The main starting point in your tests. + *
+ * Open browser and pass authentication using build-in proxy. + *
+ * A common authenticationType is "Basic". See Web HTTP reference for other types. + *
+ * This method can only work if - {@code Configuration.fileDownload == Configuration.FileDownloadMode.PROXY;} + * + * @see Web HTTP reference + * @see AuthenticationType + * @see Credentials + */ + public static void open(String relativeOrAbsoluteUrl, AuthenticationType authenticationType, Credentials credentials) { + navigator.open(relativeOrAbsoluteUrl, authenticationType, credentials); + } + /** * @see Selenide#open(URL, String, String, String) */ diff --git a/src/main/java/com/codeborne/selenide/impl/Navigator.java b/src/main/java/com/codeborne/selenide/impl/Navigator.java index 2ac471af09..8829175931 100644 --- a/src/main/java/com/codeborne/selenide/impl/Navigator.java +++ b/src/main/java/com/codeborne/selenide/impl/Navigator.java @@ -1,7 +1,11 @@ package com.codeborne.selenide.impl; +import com.codeborne.selenide.AuthenticationType; +import com.codeborne.selenide.Credentials; import com.codeborne.selenide.logevents.SelenideLog; import com.codeborne.selenide.logevents.SelenideLogger; +import com.codeborne.selenide.proxy.SelenideProxyServer; +import io.netty.handler.codec.http.HttpHeaders; import org.openqa.selenium.JavascriptExecutor; import org.openqa.selenium.WebDriver; import org.openqa.selenium.WebDriverException; @@ -12,6 +16,7 @@ import static com.codeborne.selenide.Configuration.baseUrl; import static com.codeborne.selenide.Configuration.captureJavascriptErrors; import static com.codeborne.selenide.WebDriverRunner.getAndCheckWebDriver; +import static com.codeborne.selenide.WebDriverRunner.getSelenideProxy; import static com.codeborne.selenide.WebDriverRunner.getWebDriver; import static com.codeborne.selenide.WebDriverRunner.isIE; import static com.codeborne.selenide.logevents.LogEvent.EventStatus.PASS; @@ -39,6 +44,20 @@ public void open(URL url, String domain, String login, String password) { navigateToAbsoluteUrl(url.toExternalForm()); } + public void open(String relativeOrAbsoluteUrl, AuthenticationType authenticationType, Credentials credentials) { + getAndCheckWebDriver(); + String authorization = String.format("%s %s", authenticationType.getValue(), credentials.encode()); + SelenideProxyServer selenideProxy = getSelenideProxy(); + selenideProxy.addRequestFilter("headers.request", (request, contents, messageInfo) -> { + HttpHeaders headers = request.headers(); + headers.add("Authorization", authorization); + headers.add("Proxy-Authorization", authorization); + return null; + }); + open(relativeOrAbsoluteUrl); + selenideProxy.removeRequestFilter("headers.request"); + } + protected String absoluteUrl(String relativeUrl) { return baseUrl + relativeUrl; } diff --git a/src/main/java/com/codeborne/selenide/proxy/SelenideProxyServer.java b/src/main/java/com/codeborne/selenide/proxy/SelenideProxyServer.java index 683ac4d128..6b30bb47ad 100644 --- a/src/main/java/com/codeborne/selenide/proxy/SelenideProxyServer.java +++ b/src/main/java/com/codeborne/selenide/proxy/SelenideProxyServer.java @@ -77,7 +77,6 @@ public void start() { port = proxy.getPort(); } - /** * Add a custom request filter which allows to track/modify all requests from browser to server * @@ -85,14 +84,30 @@ public void start() { * @param requestFilter the filter */ public void addRequestFilter(String name, RequestFilter requestFilter) { - if (requestFilters.containsKey(name)) { + if (isRequestFilterAdded(name)) { throw new IllegalArgumentException("Duplicate request filter: " + name); } - proxy.addRequestFilter(requestFilter); requestFilters.put(name, requestFilter); } + private boolean isRequestFilterAdded(String name) { + return requestFilters.containsKey(name); + } + + /** + * Remove a custom request filter by name + * + * @param name unique name of filter + */ + public void removeRequestFilter(String name) { + if (isRequestFilterAdded(name)) { + requestFilters.remove(name); + } else { + throw new IllegalArgumentException("Missing request filter: " + name); + } + } + /** * Add a custom response filter which allows to track/modify all server responses to browser * diff --git a/src/test/java/integration/BasicAuthTest.java b/src/test/java/integration/BasicAuthTest.java index c08e413e9c..0353c6c125 100644 --- a/src/test/java/integration/BasicAuthTest.java +++ b/src/test/java/integration/BasicAuthTest.java @@ -1,5 +1,9 @@ package integration; +import com.codeborne.selenide.AuthenticationType; +import com.codeborne.selenide.Configuration; +import com.codeborne.selenide.Configuration.FileDownloadMode; +import com.codeborne.selenide.Credentials; import org.junit.jupiter.api.Test; import static com.codeborne.selenide.Condition.text; @@ -12,4 +16,19 @@ void canPassBasicAuth() { open("/basic-auth/hello", "", "scott", "tiger"); $("body").shouldHave(text("Hello, scott:tiger!")); } + + @Test + void canAuthUsingProxyWithLoginAndPassword() { + Configuration.fileDownload = FileDownloadMode.PROXY; + open("/basic-auth/hello", AuthenticationType.BASIC, "scott", "tiger"); + $("body").shouldHave(text("Hello, scott:tiger!")); + } + + @Test + void canAuthUsingProxyWithCredentials() { + Configuration.fileDownload = FileDownloadMode.PROXY; + Credentials credentials = new Credentials("scott", "tiger"); + open("/basic-auth/hello", AuthenticationType.BASIC, credentials); + $("body").shouldHave(text("Hello, scott:tiger!")); + } }