维护和重用现有的 webdriver 浏览器实例 - java
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/18212389/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Maintain and re-use existing webdriver browser instance - java
提问by pelican
Basically every time I run my java code from eclipse, webdriver launches a new ie browser and executes my tests successfully for the most part. However, I have a lot of tests to run, and it's a pain that webdriver starts up a new browser session every time. I need a way to re-use a previously opened browser; so webdriver would open ie the first time, then the second time, i run my eclipse program, I want it to simply pick up the previous browser instance and continue to run my tests on that same instance. That way, I am NOT starting up a new browser session every time I run my program.
Say you have 100 tests to run in eclipse, you hit that run button and they all run, then at about the 87th test you get an error. You then go back to eclipse, fix that error, but then you have to re-run all 100 test again from scratch.
It would be nice to fix the error on that 87th test and then resume the execution from that 87th test as opposed to re-executing all tests from scratch, i.e from test 0 all the way to 100.
Hopefully, I am clear enough to get some help from you guys, thanks btw.
Here's my attempt below at trying to maintain and re-use a webdriver internet explorer browser instance:
基本上每次我从 eclipse 运行我的 java 代码时,webdriver 都会启动一个新的 ie 浏览器并成功执行我的大部分测试。但是,我有很多测试要运行,而且每次 webdriver 都启动一个新的浏览器会话很痛苦。我需要一种方法来重用以前打开的浏览器;所以 webdriver 第一次打开,然后第二次,我运行我的 eclipse 程序,我希望它简单地选择以前的浏览器实例并继续在同一个实例上运行我的测试。这样,每次运行我的程序时,我都不会启动新的浏览器会话。
假设你有 100 个测试要在 eclipse 中运行,你点击了运行按钮,它们都运行了,然后在第 87 个测试中你得到一个错误。然后您返回到 eclipse,修复该错误,但是您必须从头开始重新运行所有 100 个测试。
最好在第 87 次测试中修复错误,然后从第 87 次测试恢复执行,而不是从头开始重新执行所有测试,即从测试 0 一直到 100。希望我足够清楚来自你们的一些帮助,谢谢 btw。
下面是我尝试维护和重用 webdriver Internet Explorer 浏览器实例的尝试:
public class demo extends RemoteWebDriver {
public static WebDriver driver;
public Selenium selenium;
public WebDriverWait wait;
public String propertyFile;
String getSessionId;
public demo() { // constructor
DesiredCapabilities ieCapabilities = DesiredCapabilities
.internetExplorer();
ieCapabilities
.setCapability(
InternetExplorerDriver.INTRODUCE_FLAKINESS_BY_IGNORING_SECURITY_DOMAINS,
true);
driver = new InternetExplorerDriver(ieCapabilities);
this.saveSessionIdToSomeStorage(getSessionId);
this.startSession(ieCapabilities);
driver.manage().window().maximize();
}
@Override
protected void startSession(Capabilities desiredCapabilities) {
String sid = getPreviousSessionIdFromSomeStorage();
if (sid != null) {
setSessionId(sid);
try {
getCurrentUrl();
} catch (WebDriverException e) {
// session is not valid
sid = null;
}
}
if (sid == null) {
super.startSession(desiredCapabilities);
saveSessionIdToSomeStorage(getSessionId().toString());
}
}
private void saveSessionIdToSomeStorage(String session) {
session=((RemoteWebDriver) driver).getSessionId().toString();
}
private String getPreviousSessionIdFromSomeStorage() {
return getSessionId;
}
}
My hope here was that by overriding the startSession() method from remoteWebdriver, it would somehow check that I already had an instance of webdriver browser opened in i.e and it would instead use that instance as opposed to re-creating a new instance everytime I hit that "run" button in eclipse.
I can also see that because I am creating a "new driver instance" from my constructor, since constructor always execute first, it creates that new driver instance automatically, so I might need to alter that somehow, but don't know how.
我的希望是,通过覆盖 remoteWebdriver 的 startSession() 方法,它会以某种方式检查我是否已经在 ie 中打开了一个 webdriver 浏览器实例,它会改为使用该实例,而不是每次点击时重新创建一个新实例eclipse中的“运行”按钮。
我还可以看到,因为我正在从我的构造函数创建一个“新驱动程序实例”,因为构造函数总是首先执行,它会自动创建该新驱动程序实例,所以我可能需要以某种方式更改它,但不知道如何更改。
I am a newbie on both stackoverflow and with selenium webdriver and hope someone here can help.
我是 stackoverflow 和 selenium webdriver 的新手,希望这里有人可以提供帮助。
Thanks!
谢谢!
采纳答案by Nathan Merrill
To answer your question:
回答你的问题:
No. You can't use a browser that is currently running on your computer. You can use the same browser for the different tests, however, as long as it is on the same execution.
不可以。您不能使用当前在您的计算机上运行的浏览器。但是,您可以对不同的测试使用相同的浏览器,只要它在同一执行中即可。
However, it sounds like your real problem is running 100 tests over and over again. I would recommend using a testing framework (like TestNG or JUnit). With these, you can specify which tests you want to run (TestNG will generate an XML file of all of the tests that fail, so when you run it, it will only execute the failed tests).
但是,听起来您真正的问题是一遍又一遍地运行 100 次测试。我建议使用测试框架(如 TestNG 或 JUnit)。通过这些,您可以指定要运行的测试(TestNG 将生成所有失败测试的 XML 文件,因此当您运行它时,它只会执行失败的测试)。
回答by sunder kandasamy
Actually you can re-use the same session again..
其实你可以再次使用同一个会话..
In node client you can use following code to attach to existing selenium session
在节点客户端中,您可以使用以下代码附加到现有的 selenium 会话
var browser = wd.remote('http://localhost:4444/wd/hub');
browser.attach('df606fdd-f4b7-4651-aaba-fe37a39c86e3', function(err, capabilities) {
// The 'capabilities' object as returned by sessionCapabilities
if (err) { /* that session doesn't exist */ }
else {
browser.elementByCss("button.groovy-button", function(err, el) {
...
});
}
});
...
browser.detach();
To get selenium session id,
要获取硒会话 ID,
driver.getSessionId();
Note: This is available in Node Client only.. To do the same thing in JAVA or C#, you have to override execute method of selenium to capture the sessionId and save it in local file and read it again to attach with existing selenium session
注意:这仅在 Node Client 中可用。要在 JAVA 或 C# 中执行相同的操作,您必须覆盖 selenium 的 execute 方法以捕获 sessionId 并将其保存在本地文件中,然后再次读取以附加现有的 selenium 会话
回答by Mohit Baluja
I have tried the below steps to use the same browser instance and it worked for me:
我已经尝试了以下步骤来使用相同的浏览器实例,它对我有用:
If you are having generic or Class 1 in different package the below code snippet will work -
如果您在不同的包中使用通用或 1 类,则以下代码片段将起作用 -
package zgenerics;
import java.io.IOException;
import java.util.concurrent.TimeUnit;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.testng.annotations.BeforeTest;
import org.openqa.selenium.WebDriver;
// Class 1 :
// 第 1 类:
public class Generics {
public Generics(){}
protected WebDriver driver;
@BeforeTest
public void maxmen() throws InterruptedException, IOException{
driver = new FirefoxDriver();
driver.manage().window().maximize();
driver.manage().timeouts().implicitlyWait(30, TimeUnit.SECONDS);
String appURL= "url";
driver.get(appURL);
String expectedTitle = "Title";
String actualTitle= driver.getTitle();
if(actualTitle.equals(expectedTitle)){
System.out.println("Verification passed");
}
else {
System.out.println("Verification failed");
} }
// Class 2 :
// 类 2 :
package automationScripts;
import org.openqa.selenium.By;
import org.testng.annotations.*;
import zgenerics.Generics;
import org.openqa.selenium.support.ui.WebDriverWait;
import org.openqa.selenium.support.ui.ExpectedConditions;
public class Login extends Generics {
@Test
public void Login() throws InterruptedException, Exception {
WebDriverWait wait = new WebDriverWait(driver,25);
wait.until(ExpectedConditions.visibilityOfElementLocated(By.cssSelector("")));
driver.findElement(By.cssSelector("")).sendKeys("");
wait.until(ExpectedConditions.visibilityOfElementLocated(By.xpath("")));
driver.findElement(By.xpath("")).sendKeys("");
}
}
If your Generics class is in the same package you just need to make below change in your code:
如果您的泛型类在同一个包中,您只需要在代码中进行以下更改:
public class Generics {
public Generics(){}
WebDriver driver; }
Just remove the protected word from Webdriver code line. Rest code of class 1 remain as it is.
只需从 Webdriver 代码行中删除受保护的词即可。第 1 类的其余代码保持原样。
Regards, Mohit Baluja
问候, Mohit Baluja
回答by Mohit Baluja
I have tried it by extension of classes(Java Inheritance) and creating an xml file. I hope below examples will help:
我已经通过类的扩展(Java 继承)和创建一个 xml 文件来尝试它。我希望下面的例子会有所帮助:
Class 1 :
第 1 类:
package zgenerics;
import java.io.IOException;
import java.util.concurrent.TimeUnit;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.testng.annotations.BeforeTest;
import org.openqa.selenium.WebDriver;
public class SetUp {
public Generics(){}
protected WebDriver driver;
@BeforeTest
public void maxmen() throws InterruptedException, IOException{
driver = new FirefoxDriver();
driver.manage().window().maximize();
driver.manage().timeouts().implicitlyWait(30, TimeUnit.SECONDS);
String appURL= "URL";
driver.get(appURL);
String expectedTitle = "Title";
String actualTitle= driver.getTitle();
if(actualTitle.equals(expectedTitle)){
System.out.println("Verification passed");
}
else {
System.out.println("Verification failed");
} }
Class 2 :
第 2 类:
package automationScripts;
import org.openqa.selenium.By;
import org.testng.annotations.Test;
import zgenerics.SetUp
public class Conditions extends SetUp {
@Test
public void visible() throws InterruptedException{
Thread.sleep(5000);
boolean signINbutton=driver.findElement(By.xpath("xpath")).isEnabled();
System.out.println(signINbutton);
boolean SIGNTEXT=driver.findElement(By.xpath("xpath")).isDisplayed();
System.out.println(SIGNTEXT);
if (signINbutton==true && SIGNTEXT==true){
System.out.println("Text and button is present");
}
else{
System.out.println("Nothing is visible");
}
}
}
Class 3:
第 3 类:
package automationScripts;
import java.io.IOException;
import java.util.concurrent.TimeUnit;
import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;
import org.testng.annotations.Test;
public class Footer extends Conditions {
@Test
public void footerNew () throws InterruptedException{
WebElement aboutUs = driver.findElement(By.cssSelector("CssSelector"));
aboutUs.click();
WebElement cancel = driver.findElement(By.xpath("xpath"));
cancel.click();
Thread.sleep(1000);
WebElement TermsNCond = driver.findElement(By.xpath("xpath"));
TermsNCond.click();
}
}
Now Create an xml file with below code for example and run the testng.xml as testng suite: copy and paste below code and edit it accordingly.
现在用下面的代码创建一个 xml 文件,并运行 testng.xml 作为 testng 套件:复制并粘贴下面的代码并相应地编辑它。
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd">
<suite name="TestSuite" parallel="classes" thread-count="3">
<test name="PackTest">
<classes>
<class name="automationScripts.Footer"/>
</classes>
This will run above three classes. That means one browser and different tests. We can set the execution sequence by setting the class names in alphabetical order as i have done in above classes.
这将运行在三个类之上。这意味着一种浏览器和不同的测试。我们可以通过按字母顺序设置类名来设置执行顺序,就像我在上面的类中所做的那样。