这个问题在过去已经被问过好几次了,而我要回答的问题甚至都不是最近的。但是我仍然会继续发布答案,因为最近我被与同一浏览器会话相关的问题所困扰。我如何能够利用已经打开的浏览器,以便我可以继续我的测试运行,而不是从头开始重新启动它。在浏览大量页面之后,当您遇到重新启动 Selenium 测试的问题时,在某些情况下甚至会很费力。相反,我想知道“银弹在哪里?”。终于看到了“ http://tarunlalwani.com/post/reusing-existing-browser-session-selenium/ ”写的一篇文章“。但是仍然有一些缺失的链接。所以我想在这里借助一个合适的例子来解开它。在下面的代码片段中,我试图在 Chrome 浏览器的 Selenium 会话中启动 SeleniumHQ 并单击下载链接.
System.setProperty("webdriver.chrome.driver","C:\\Selenium\\chromedriver.exe");
//First Session
ChromeDriver driver = new ChromeDriver();
HttpCommandExecutor executor = (HttpCommandExecutor)
driver.getCommandExecutor();
URL url = executor.getAddressOfRemoteServer();
SessionId session_id = driver.getSessionId();
storeSessionAttributesToFile("Id",session_id.toString());
storeSessionAttributesToFile("URL",url.toString());
driver.get("https://docs.seleniumhq.org/");
WebElement download = driver.findElementByLinkText("Download");
download.click();
如果您阅读了上面的代码,我将捕获 Selenium 远程服务器的 URL 和当前 selenium(浏览器)会话的会话 ID,并将其写入属性文件。现在,如果我需要继续在同一个浏览器窗口/会话中执行,尽管停止了当前的测试运行,我需要做的就是在上述代码片段中注释第一个会话下面的代码,并从下面的代码继续你的测试:
System.setProperty("webdriver.chrome.driver","C:\\Selenium\\chromedriver.exe");
//First Session
//ChromeDriver driver = new ChromeDriver();
//HttpCommandExecutor executor = (HttpCommandExecutor) driver.getCommandExecutor();
//URL url = executor.getAddressOfRemoteServer();
//SessionId session_id = driver.getSessionId();
//storeSessionAttributesToFile("Id",session_id.toString());
// storeSessionAttributesToFile("URL",url.toString());
// driver.get("https://docs.seleniumhq.org/");
// WebElement download = driver.findElementByLinkText("Download");
// download.click();
//Attaching to the session
String existingSession = readSessionId("Id");
String url1 = readSessionId("URL");
URL existingDriverURL = new URL(url1);
RemoteWebDriver attachToDriver = createDriverFromSession(existingSession, existingDriverURL);
WebElement previousReleases = attachToDriver.findElementByLinkText("Previous Releases");
previousReleases.click();
现在您可能必须重构并重命名驱动程序对象(即使保留名称仍然可以,但我只是想区分将其附加到现有驱动程序和启动驱动程序)。在上面的代码块中,我在读取并分配 URL 和 sessionid 并从会话创建驱动程序以继续利用浏览器和会话之后继续我的测试。请查看下面的完整代码:
package org.openqa.selenium.example;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.lang.reflect.Field;
import java.net.URL;
import java.util.Collections;
import java.util.Properties;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.remote.Command;
import org.openqa.selenium.remote.CommandExecutor;
import org.openqa.selenium.remote.DesiredCapabilities;
import org.openqa.selenium.remote.HttpCommandExecutor;
import org.openqa.selenium.remote.RemoteWebDriver;
import org.openqa.selenium.remote.Response;
import org.openqa.selenium.remote.SessionId;
import org.openqa.selenium.remote.http.W3CHttpCommandCodec;
import org.openqa.selenium.remote.http.W3CHttpResponseCodec;
public class AttachingToSession {
public static String SESSION_FILE = "C:\\example\\Session.Properties";
public static Properties prop = new Properties();
public static void main(String[] args) throws Exception {
System.setProperty("webdriver.chrome.driver","C:\\Selenium\\chromedriver.exe");
//First Session
ChromeDriver driver = new ChromeDriver();
HttpCommandExecutor executor = (HttpCommandExecutor) driver.getCommandExecutor();
URL url = executor.getAddressOfRemoteServer();
SessionId session_id = driver.getSessionId();
storeSessionAttributesToFile("Id",session_id.toString());
storeSessionAttributesToFile("URL",url.toString());
driver.get("https://docs.seleniumhq.org/");
WebElement download = driver.findElementByLinkText("Download");
download.click();
//Attaching to the session
String existingSession = readSessionId("Id");
String url1 = readSessionId("URL");
URL existingDriverURL = new URL(url1);
RemoteWebDriver attachToDriver = createDriverFromSession(existingSession, existingDriverURL);
WebElement previousReleases = attachToDriver.findElementByLinkText("Previous Releases");
previousReleases.click();
}
public static RemoteWebDriver createDriverFromSession(final String sessionId, URL command_executor){
CommandExecutor executor = new HttpCommandExecutor(command_executor) {
@Override
public Response execute(Command command) throws IOException {
Response response = null;
if (command.getName() == "newSession") {
response = new Response();
response.setSessionId(sessionId);
response.setStatus(0);
response.setValue(Collections.<String, String>emptyMap());
try {
Field commandCodec = null;
commandCodec = this.getClass().getSuperclass().getDeclaredField("commandCodec");
commandCodec.setAccessible(true);
commandCodec.set(this, new W3CHttpCommandCodec());
Field responseCodec = null;
responseCodec = this.getClass().getSuperclass().getDeclaredField("responseCodec");
responseCodec.setAccessible(true);
responseCodec.set(this, new W3CHttpResponseCodec());
} catch (NoSuchFieldException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
} else {
response = super.execute(command);
}
return response;
}
};
return new RemoteWebDriver(executor, new DesiredCapabilities());
}
public static void storeSessionAttributesToFile(String key,String value) throws Exception{
OutputStream output = null;
try{
output = new FileOutputStream(SESSION_FILE);
//prop.load(output);
prop.setProperty(key, value);
prop.store(output, null);
}
catch(IOException e){
e.printStackTrace();
}
finally {
if(output !=null){
output.close();
}
}
}
public static String readSessionId(String ID) throws Exception{
Properties prop = new Properties();
InputStream input = null;
String SessionID = null;
try {
input = new FileInputStream(SESSION_FILE);
// load a properties file
prop.load(input);
// get the property value and print it out
System.out.println(prop.getProperty(ID));
SessionID = prop.getProperty(ID);
} catch (IOException ex) {
ex.printStackTrace();
} finally {
if (input != null) {
try {
input.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
return SessionID;
}
}