如何从公司代理后面通过 RemoteWebDriver 连接到 Selenium 网格(例如 BrowserStack)?
被测试的应用程序位于代理之外,可以从 BrowserStack 自由访问。
这个 Using Selenium RemoteWebDriver Behind Corporate proxy (Java) stackoverflow 问题提出了同样的问题,但我无法遵循已接受的答案。
我设法根据链接的 stackoverflow 问题中接受的答案得到一些工作,这是我的实现,以防其他人遇到同样的问题:
示例
import java.net.InetAddress;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.UnknownHostException;
import java.util.HashMap;
import java.util.Map;
import org.apache.http.HttpHost;
import org.apache.http.auth.AuthScope;
import org.apache.http.auth.NTCredentials;
import org.apache.http.auth.UsernamePasswordCredentials;
import org.apache.http.client.CredentialsProvider;
import org.apache.http.impl.client.BasicCredentialsProvider;
import org.apache.http.impl.client.HttpClientBuilder;
import org.openqa.selenium.remote.CommandInfo;
import org.openqa.selenium.remote.DesiredCapabilities;
import org.openqa.selenium.remote.HttpCommandExecutor;
import org.openqa.selenium.remote.RemoteWebDriver;
import org.openqa.selenium.remote.http.HttpClient.Factory;
public class Example {
public RemoteWebDriver connectViaProxy(DesiredCapabilities caps) {
String proxyHost = "?";
int proxyPort = 8080;
String proxyUserDomain = "?";
String proxyUser = "?";
String proxyPassword = "?";
URL url;
try {
url = new URL("http://bsuser:[email protected]/wd/hub");
} catch (MalformedURLException e) {
throw new RuntimeException(e.getMessage(), e);
}
HttpClientBuilder builder = HttpClientBuilder.create();
HttpHost proxy = new HttpHost(proxyHost, proxyPort);
CredentialsProvider credsProvider = new BasicCredentialsProvider();
credsProvider.setCredentials(new AuthScope(proxyHost, proxyPort), new NTCredentials(proxyUser, proxyPassword, getWorkstation(), proxyUserDomain));
if (url.getUserInfo() != null && !url.getUserInfo().isEmpty()) {
credsProvider.setCredentials(new AuthScope(url.getHost(), (url.getPort() > 0 ? url.getPort() : url.getDefaultPort())), new UsernamePasswordCredentials(url.getUserInfo()));
}
builder.setProxy(proxy);
builder.setDefaultCredentialsProvider(credsProvider);
Factory factory = new MyHttpClientFactory(builder);
HttpCommandExecutor executor = new HttpCommandExecutor(new HashMap<String, CommandInfo>(), url, factory);
return new RemoteWebDriver(executor, caps);
}
private String getWorkstation() {
Map<String, String> env = System.getenv();
if (env.containsKey("COMPUTERNAME")) {
// Windows
return env.get("COMPUTERNAME");
} else if (env.containsKey("HOSTNAME")) {
// Unix/Linux/MacOS
return env.get("HOSTNAME");
} else {
// From DNS
try
{
return InetAddress.getLocalHost().getHostName();
}
catch (UnknownHostException ex)
{
return "Unknown";
}
}
}
}
MyHttpClientFactory
import java.net.URL;
import org.apache.http.impl.client.HttpClientBuilder;
import org.openqa.selenium.remote.internal.ApacheHttpClient;
public class MyHttpClientFactory implements org.openqa.selenium.remote.http.HttpClient.Factory {
final HttpClientBuilder builder;
public MyHttpClientFactory(HttpClientBuilder builder) {
this.builder = builder;
}
@Override
public org.openqa.selenium.remote.http.HttpClient createClient(URL url) {
return new ApacheHttpClient(builder.build(), url);
}
}
添加 Andrew 上面的答案,为了使其与 Appium 一起工作,更改
HttpCommandExecutor executor = new HttpCommandExecutor(new HashMap<String, CommandInfo>(), url, factory);
到
HttpCommandExecutor executor = new HttpCommandExecutor(MobileCommand.commandRepository, url, factory);
我稍微修改了 Andrew Sumner 的解决方案,并删除了一些解决方案,以防像我这样的人想要通过 Fiddler 快速汇集其 WebDriver 流量以查看流量。
import java.net.MalformedURLException;
import java.net.URL;
import java.util.HashMap;
import org.apache.http.HttpHost;
import org.apache.http.impl.client.HttpClientBuilder;
import org.openqa.selenium.ie.InternetExplorerOptions;
import org.openqa.selenium.remote.CommandInfo;
import org.openqa.selenium.remote.HttpCommandExecutor;
import org.openqa.selenium.remote.RemoteWebDriver;
import org.openqa.selenium.remote.http.HttpClient;
import org.openqa.selenium.remote.http.HttpClient.Factory;
import org.openqa.selenium.remote.internal.ApacheHttpClient;
public class ProxiedRemoteExample {
private static final String PROXY_HOST = "localhost";
private static final int PROXY_PORT = 8888;
public ProxiedRemoteExample() throws MalformedURLException {
InternetExplorerOptions ieOptions = new InternetExplorerOptions();
RemoteWebDriver driver = new RemoteWebDriver(new HttpCommandExecutor(new HashMap<String, CommandInfo>(),
new URL("http://localhost:5555/"), new Factory() {
private HttpClientBuilder builder;
{
builder = HttpClientBuilder.create();
builder.setProxy(new HttpHost(PROXY_HOST, PROXY_PORT));
}
@Override
public HttpClient createClient(URL url) {
return new ApacheHttpClient(builder.build(), url);
}
}), ieOptions);
}
}
与
org.seleniumhq.selenium:selenium-java:4.0.0-beta-3
我必须通过以下方式应用代理设置:
ahc.properties
文件夹下创建org/asynchttpclient/config
文件org.asynchttpclient.useProxyProperties = true
在
v4.0.0-alpha-7
之后,http客户端的OkHttp实现已被删除。
但是在重读安德鲁的答案后,我找到了一种设置代理的简单方法:
var url = new URL("Your grid endpoint like browserstack or saucelabs");
var proxy = new java.net.Proxy(java.net.Proxy.Type.HTTP,
new InetSocketAddress("Your proxy", 8080));
var executor = new HttpCommandExecutor(ClientConfig.defaultConfig().baseUrl(url).proxy(proxy));
var driver = new RemoteWebDriver(executor, browserOptions);
对于使用 Selenium 和 Java 并希望在 RemoteWebdriver 中添加身份验证代理的人。 我测试过,它对我有用。希望它可以节省您的时间。
DesiredCapabilities capabilities = new DesiredCapabilities();
Proxy proxy = new Proxy();
proxy.setHttpProxy(proxyItem);
proxy.setSslProxy(proxyItem);
proxy.setFtpProxy(proxyItem);
proxy.setSocksUsername(userProx);
proxy.setSocksPassword(passProx);
proxy.setAutodetect(false);
proxy.setProxyType(Proxy.ProxyType.MANUAL);
capabilities.setCapability(CapabilityType.PROXY, proxy);
RemoteWebDriver.builder();
WebDriver driver = RemoteWebDriver.builder()
.oneOf(chromeOptions)
.address(new URI("http://localhost:4444/wd/hub"))
.setCapability(CapabilityType.PROXY, proxy)
.build();
AddHasAuthentication addHasAuthentication = new AddHasAuthentication();
addHasAuthentication.getImplementation(
capabilities, new RemoteExecuteMethod((RemoteWebDriver) driver))
.register(UsernameAndPassword.of(userProxy, passProxy));
driver.get("https://www.whatismyip.com");