Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

#788 Add setting to enable/disable proxy server #791

Merged
merged 2 commits into from Aug 28, 2018
Merged
Changes from 1 commit
Commits
File filter...
Filter file types
Jump to…
Jump to file or symbol
Failed to load files and symbols.
+339 −109
Diff settings

Always

Just for now

Copy path View file
@@ -2,6 +2,7 @@

## 4.14.0 (planned to xx.09.2018)
* #784 Enable BasicAuth through Selenide proxy server -- see https://github.com/codeborne/selenide/pull/785
* #788 Add setting to enable/disable proxy server
* #789 Remove `?timestamp` parameter for IE

## 4.13.0 (released 20.08.2018)
@@ -380,6 +380,35 @@ private static String getJenkinsReportsUrl() {
public static FileDownloadMode fileDownload = FileDownloadMode.valueOf(
System.getProperty("selenide.fileDownload", HTTPGET.name()));

/**
* If Selenide should run browser through its own proxy server.
* It allows some additional features which are not possible with plain Selenium.
* But it's not enabled by default because sometimes it would not work (more exactly, if tests and browser and
* executed on different machines, and "test machine" is not accessible from "browser machine"). If it's not your
* case, I recommend to enable proxy.
*
* Default: false
*/
public static boolean proxyEnabled = Boolean.parseBoolean(System.getProperty("selenide.proxyEnabled", "false"));

/**
* Host of Selenide proxy server.
* Used only if proxyEnabled == true.
*
* Default: empty (meaning that Selenide will detect current machine's ip/hostname automatically)
*
* @see net.lightbody.bmp.client.ClientUtil#getConnectableAddress()
*/
public static String proxyHost = System.getProperty("selenide.proxyHost", "");

This comment has been minimized.

Copy link
@rosolko

rosolko Aug 28, 2018

Collaborator

In parent task default value was described as localhost not an empty value

This comment has been minimized.

Copy link
@asolntsev

asolntsev Aug 28, 2018

Author Contributor

Which parent task do you mean? I don't see it.


/**
* Port of Selenide proxy server.
* Used only if proxyEnabled == true.
*
* Default: 0 (meaning that Selenide will choose a random free port on current machine)
*/
public static int proxyPort = Integer.parseInt(System.getProperty("selenide.proxyPort", "0"));

/**
* Controls Selenide and WebDriverManager integration.
* When integration is enabled you don't need to download and setup any browser driver executables.
@@ -10,7 +10,6 @@

import java.io.File;
import java.io.IOException;
import java.util.Objects;
import java.util.logging.Logger;

import static com.codeborne.selenide.Configuration.FileDownloadMode.HTTPGET;
@@ -19,8 +18,17 @@
public class DownloadFile implements Command<File> {
private static final Logger LOG = Logger.getLogger(DownloadFile.class.getName());

DownloadFileWithHttpRequest downloadFileWithHttpRequest = new DownloadFileWithHttpRequest();
DownloadFileWithProxyServer downloadFileWithProxyServer = new DownloadFileWithProxyServer();
private final DownloadFileWithHttpRequest downloadFileWithHttpRequest;
private final DownloadFileWithProxyServer downloadFileWithProxyServer;

public DownloadFile() {
this(new DownloadFileWithHttpRequest(), new DownloadFileWithProxyServer());
}

DownloadFile(DownloadFileWithHttpRequest httpget, DownloadFileWithProxyServer proxy) {
downloadFileWithHttpRequest = httpget;
downloadFileWithProxyServer = proxy;
}

@Override
public File execute(SelenideElement proxy, WebElementSource linkWithHref, Object[] args) throws IOException {
@@ -32,18 +40,20 @@ public File execute(SelenideElement proxy, WebElementSource linkWithHref, Object
LOG.config("selenide.fileDownload = " + System.getProperty("selenide.fileDownload") + " download file via http get");
return downloadFileWithHttpRequest.download(link, timeout);
}
else if (!Configuration.proxyEnabled) {

This comment has been minimized.

Copy link
@rosolko

rosolko Aug 28, 2018

Collaborator

else if using is redundant in this place because each branch do a return or throw

This comment has been minimized.

Copy link
@asolntsev

asolntsev Aug 28, 2018

Author Contributor

done

throw new IllegalStateException("Cannot download file: proxy server is not enabled. Setup Configuration.proxyEnabled");
}
else if (webdriverContainer.getProxyServer() == null) {

This comment has been minimized.

Copy link
@rosolko

rosolko Aug 28, 2018

Collaborator

same here

This comment has been minimized.

Copy link
@asolntsev

asolntsev Aug 28, 2018

Author Contributor

done

LOG.config("Proxy server is not started - download file via http get");
return downloadFileWithHttpRequest.download(link, timeout);
throw new IllegalStateException("Cannot download file: proxy server is not started");
}
else {

This comment has been minimized.

Copy link
@rosolko

rosolko Aug 28, 2018

Collaborator

else is redundant

This comment has been minimized.

Copy link
@asolntsev

asolntsev Aug 28, 2018

Author Contributor

done

return downloadFileWithProxyServer.download(linkWithHref, link, webdriverContainer.getProxyServer(), timeout);
}
}

private long getTimeout(Object[] args) {
long getTimeout(Object[] args) {
try {
if (Objects.nonNull(args) && args.length > 0) {
if (args != null && args.length > 0) {
return (long) args[0];
}
else {
@@ -12,7 +12,6 @@

import java.net.URL;

import static com.codeborne.selenide.Configuration.FileDownloadMode.PROXY;
import static com.codeborne.selenide.Configuration.baseUrl;
import static com.codeborne.selenide.WebDriverRunner.getAndCheckWebDriver;
import static com.codeborne.selenide.WebDriverRunner.getSelenideProxy;
@@ -76,7 +75,7 @@ private void navigateTo(String url, AuthenticationType authenticationType, Strin
}

private void beforeNavigateTo(AuthenticationType authenticationType, String domain, String login, String password) {
if (Configuration.fileDownload == PROXY) {
if (Configuration.proxyEnabled) {
beforeNavigateToWithProxy(authenticationType, domain, login, password);
}
else {
@@ -111,7 +110,7 @@ private String appendBasicAuthIfNeeded(String url, AuthenticationType authType,

private boolean passBasicAuthThroughUrl(AuthenticationType authenticationType, String domain, String login, String password) {
return hasAuthentication(domain, login, password) &&
Configuration.fileDownload != PROXY &&
!Configuration.proxyEnabled &&
authenticationType == AuthenticationType.BASIC;
}

@@ -221,7 +221,13 @@ protected WebDriver createDriver() {

Proxy userProvidedProxy = proxy;

if (Configuration.fileDownload == PROXY) {
if (!Configuration.proxyEnabled && Configuration.fileDownload == PROXY) {
log.warning("Configuration.proxyEnabled == false but Configuration.fileDownload == PROXY. " +
"We will enable proxy server automatically.");
Configuration.proxyEnabled = true;
}

if (Configuration.proxyEnabled) {
SelenideProxyServer selenideProxyServer = new SelenideProxyServer(proxy);
selenideProxyServer.start();
THREAD_PROXY_SERVER.put(currentThread().getId(), selenideProxyServer);
@@ -0,0 +1,25 @@
package com.codeborne.selenide.proxy;

import net.lightbody.bmp.BrowserMobProxyServer;
import net.lightbody.bmp.filters.RequestFilter;
import net.lightbody.bmp.filters.RequestFilterAdapter;
import net.lightbody.bmp.filters.ResponseFilter;
import net.lightbody.bmp.filters.ResponseFilterAdapter;

/**
* By default, BrowserMobProxyServer doesn't allow requests/responses bugger than 2 MB.
* We need this class to enable bigger sizes.
*/
class BrowserMobProxyServerUnlimited extends BrowserMobProxyServer {
private static final int maxSize = 64 * 1024 * 1024; // 64 MB

@Override
public void addRequestFilter(RequestFilter filter) {
addFirstHttpFilterFactory(new RequestFilterAdapter.FilterSource(filter, maxSize));
}

@Override
public void addResponseFilter(ResponseFilter filter) {
addLastHttpFilterFactory(new ResponseFilterAdapter.FilterSource(filter, maxSize));
}
}
@@ -0,0 +1,15 @@
package com.codeborne.selenide.proxy;

import java.net.InetAddress;
import java.net.UnknownHostException;

public class InetAddressResolver {
InetAddress getInetAddressByName(String hostname) {
try {
return InetAddress.getByName(hostname);
}
catch (UnknownHostException e) {
throw new IllegalArgumentException(e);
}
}
}
@@ -1,52 +1,31 @@
package com.codeborne.selenide.proxy;

import com.codeborne.selenide.Configuration;
import net.lightbody.bmp.BrowserMobProxy;
import net.lightbody.bmp.BrowserMobProxyServer;
import net.lightbody.bmp.client.ClientUtil;
import net.lightbody.bmp.filters.RequestFilter;
import net.lightbody.bmp.filters.RequestFilterAdapter;
import net.lightbody.bmp.filters.ResponseFilter;
import net.lightbody.bmp.filters.ResponseFilterAdapter;
import org.openqa.selenium.Proxy;

import java.net.InetSocketAddress;
import java.util.HashMap;
import java.util.Map;

import static java.lang.Integer.parseInt;
import static org.apache.commons.lang3.StringUtils.isEmpty;

/**
* Selenide own proxy server to intercept server responses
*
* It holds map of request and response filters by name.
*/
public class SelenideProxyServer {
protected final Proxy outsideProxy;

protected BrowserMobProxy proxy = new BrowserMobProxyServer() {
int maxSize = 64 * 1024 * 1024; // 64 MB
@Override
public void addRequestFilter(RequestFilter filter) {
addFirstHttpFilterFactory(new RequestFilterAdapter.FilterSource(filter, maxSize));
}

@Override public void addResponseFilter(ResponseFilter filter) {
addLastHttpFilterFactory(new ResponseFilterAdapter.FilterSource(filter, maxSize));
}
};

/**
* Method return current instance of browser mob proxy
*
* @return browser mob proxy instance
*/
public BrowserMobProxy getProxy() {
return proxy;
}

protected int port;
protected Map<String, RequestFilter> requestFilters = new HashMap<>();
protected Map<String, ResponseFilter> responseFilters = new HashMap<>();
private final InetAddressResolver inetAddressResolver;
private final Proxy outsideProxy;
private final BrowserMobProxy proxy;
private final Map<String, RequestFilter> requestFilters = new HashMap<>();
private final Map<String, ResponseFilter> responseFilters = new HashMap<>();
private int port;

/**
* Create server
@@ -55,7 +34,13 @@ public BrowserMobProxy getProxy() {
* @param outsideProxy another proxy server used by test author for his own need (can be null)
*/
public SelenideProxyServer(Proxy outsideProxy) {
this(outsideProxy, new InetAddressResolver(), new BrowserMobProxyServerUnlimited());
}

protected SelenideProxyServer(Proxy outsideProxy, InetAddressResolver inetAddressResolver, BrowserMobProxy proxy) {
this.outsideProxy = outsideProxy;
this.inetAddressResolver = inetAddressResolver;
this.proxy = proxy;
}

/**
@@ -74,7 +59,7 @@ public void start() {
addResponseFilter("responseSizeWatchdog", new ResponseSizeWatchdog());
addResponseFilter("download", new FileDownloadFilter());

proxy.start();
proxy.start(Configuration.proxyPort);
port = proxy.getPort();
}

@@ -121,7 +106,9 @@ static InetSocketAddress getProxyAddress(Proxy proxy) {
* Converts this proxy to a "selenium" proxy that can be used by webdriver
*/
public Proxy createSeleniumProxy() {
return ClientUtil.createSeleniumProxy(proxy);
return isEmpty(Configuration.proxyHost)
? ClientUtil.createSeleniumProxy(proxy)
: ClientUtil.createSeleniumProxy(proxy, inetAddressResolver.getInetAddressByName(Configuration.proxyHost));
}

/**
@@ -131,6 +118,15 @@ public void shutdown() {
proxy.abort();
}

/**
* Method return current instance of browser mob proxy
*
* @return browser mob proxy instance
*/
public BrowserMobProxy getProxy() {
return proxy;
}

@Override
public String toString() {
return String.format("Selenide proxy server :%s", port);
@@ -16,7 +16,6 @@

import java.net.URL;

import static com.codeborne.selenide.Configuration.FileDownloadMode.HTTPGET;
import static com.codeborne.selenide.Selenide.open;
import static com.codeborne.selenide.WebDriverRunner.FIREFOX;
import static com.codeborne.selenide.WebDriverRunner.HTMLUNIT;
@@ -43,7 +42,6 @@ void resetWebDriverContainer() {

WebDriverRunner.webdriverContainer = spy(new WebDriverThreadLocalContainer());
doReturn(null).when((JavascriptExecutor) driver).executeScript(anyString(), any());
Configuration.fileDownload = HTTPGET;
}

@AfterEach
Oops, something went wrong.
ProTip! Use n and p to navigate between commits in a pull request.
You can’t perform that action at this time.