C# Selenium WebDriver跨测试用例共享同一会话
我正在使用SeleniumWebDriver(又称Selenium2),希望在所有测试用例中只保留一个窗口,并避免每个测试用例创建的新窗口,以便在web上处理一致的数据 我已经完成了搜索,但大多数都使用Selenium RC,这似乎与WebDriver非常不同(因为我不知道如何保持会话ID等)。而且,我正在使用c# 请您提供任何简单的示例代码来演示您的想法。我真的很感激C# Selenium WebDriver跨测试用例共享同一会话,c#,selenium,webdriver,C#,Selenium,Webdriver,我正在使用SeleniumWebDriver(又称Selenium2),希望在所有测试用例中只保留一个窗口,并避免每个测试用例创建的新窗口,以便在web上处理一致的数据 我已经完成了搜索,但大多数都使用Selenium RC,这似乎与WebDriver非常不同(因为我不知道如何保持会话ID等)。而且,我正在使用c# 请您提供任何简单的示例代码来演示您的想法。我真的很感激 提前谢谢 我想分享一下我目前在项目中使用的方法。尝试使用webdriver的静态初始化。希望这对你有帮助。 我的结构很简单:
提前谢谢 我想分享一下我目前在项目中使用的方法。尝试使用webdriver的静态初始化。希望这对你有帮助。 我的结构很简单: 我有
BaseSeleniumTest.java
存储所有基本方法。我还有其他TestSuite.java
,它们继承了BaseSeleniumTest.java
中的所有方法:
BaseSeleniumTest.java:
package simulator.selenium;
import com.google.common.base.Function;
import com.thoughtworks.selenium.SeleneseTestBase;
import org.apache.commons.lang.RandomStringUtils;
import org.junit.AfterClass;
import org.junit.Before;
import org.junit.BeforeClass;
import org.openqa.selenium.*;
import org.openqa.selenium.remote.DesiredCapabilities;
import org.openqa.selenium.remote.RemoteWebDriver;
import org.openqa.selenium.support.ui.FluentWait;
import org.openqa.selenium.support.ui.Wait;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.beans.factory.config.PropertyPlaceholderConfigurer;
import org.springframework.core.io.support.PropertiesLoaderUtils;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.Properties;
import java.util.concurrent.TimeUnit;
public class BaseSeleniumTest extends SeleneseTestBase {
static WebDriver driver;
private static Logger log = LoggerFactory.getLogger(BaseSeleniumTest.class);
private String loginBaseUrl;
@BeforeClass
public static void firefoxSetUp() throws MalformedURLException {
DesiredCapabilities capability = DesiredCapabilities.firefox();
driver = new FirefoxDriver();
driver.manage().timeouts().implicitlyWait(20, TimeUnit.SECONDS);
driver.manage().timeouts().pageLoadTimeout(30, TimeUnit.SECONDS);
driver.manage().window().setSize(new Dimension(1920, 1080));
}
@Before
public void homePageRefresh() throws IOException {
driver.manage().deleteAllCookies();
driver.get(propertyKeysLoader("login.base.url"));
}
@AfterClass
public static void closeFirefox(){
driver.quit();
}
public WebElement findElementByXpath(String key) throws IOException {
int i=0;
while(!isElementPresent(By.xpath(propertyKeysLoader(key))) && i<5){
driver.manage().timeouts().implicitlyWait(1, TimeUnit.SECONDS);
i++;
}
return fluentWait(By.xpath(propertyKeysLoader(key)));
}
public WebElement findElementByCssSelector(String key) throws IOException {
int i=0;
while(!isElementPresent(By.cssSelector(propertyKeysLoader(key))) && i<5){
driver.manage().timeouts().implicitlyWait(1, TimeUnit.SECONDS);
i++;
}
}
public void locatorFindingHandling(String key) throws IOException /*throws IOException*/ {
fluentWait(By.cssSelector(propertyKeysLoader(key))).click();
}
public void locatorFindingHandling(String key, String key1) throws IOException {
driver.findElement(By.xpath(propertyKeysLoader(key))).sendKeys(propertyKeysLoader(key1));
}
public String propertyKeysLoader(String key) throws IOException {
Properties props = PropertiesLoaderUtils.loadAllProperties("selenium-config.properties");
PropertyPlaceholderConfigurer props2 = new PropertyPlaceholderConfigurer();
props2.setProperties(props);
return (String)props.get(key) ;
}
public WebElement fluentWait(final By locator){
Wait<WebDriver> wait = new FluentWait<WebDriver>(driver)
.withTimeout(30, TimeUnit.SECONDS)
.pollingEvery(5, TimeUnit.SECONDS)
.ignoring(org.openqa.selenium.NoSuchElementException.class);
WebElement foo = wait.until(
new Function<WebDriver, WebElement>() {
public WebElement apply(WebDriver driver) {
return driver.findElement(locator);
}
}
);
return foo; } ;
public boolean isElementPresent(By selector)
{
return driver.findElements(selector).size()>0;
}
public boolean isElementVisible(By selector){
return driver.findElement(selector).isDisplayed();
}
public void jsDirectClickUsingDOM_GEBi(String key) throws IOException {
JavascriptExecutor js = (JavascriptExecutor) driver;
StringBuilder stringBuilder = new StringBuilder();
stringBuilder.append("document.getElementById(\'"+propertyKeysLoader(key) +"\').click();");
js.executeScript(stringBuilder.toString());
}
public void jsCodeExecution(String jsCode){
JavascriptExecutor js = (JavascriptExecutor)driver;
StringBuilder stringBuilder = new StringBuilder();
stringBuilder.append(jsCode);
js.executeScript(stringBuilder.toString());
}
public void jsDirectClickUsingDOM_GEBTagName(String tagName,int argNum) throws IOException {
JavascriptExecutor js = (JavascriptExecutor) driver;
StringBuilder stringBuilder = new StringBuilder();
// stringBuilder.append("document.getElementsByClassName(\'"+propertyKeysLoader(key) +"\')["+argArrNum+"].click();");
// stringBuilder.append("document.getElementsByTagName(\'"+tagName+"\')[document.getElementsByTagName('div').length-"+argNum+"].click()");
stringBuilder.append("document.getElementsByTagName(\'"+tagName+"\')[document.getElementsByTagName(\'"+tagName+"\').length-"+argNum+"].click()");
js.executeScript(stringBuilder.toString());
}
public String jsGetColor(String css){
JavascriptExecutor js = (JavascriptExecutor) driver;
StringBuilder stringBuilder = new StringBuilder();
stringBuilder.append("var x=$(\'"+css+"\');");
stringBuilder.append("return x.css('color')");
String res= (String) js.executeScript(stringBuilder.toString());
return res;
}
public String randomStringGenerator(){
return RandomStringUtils.randomAlphabetic(8);
}
public String randomIntSequenceGenerator(){
return RandomStringUtils.randomNumeric(6);
}
}
希望这对您有所帮助。好吧,我想分享一下我目前在项目中使用的方法。尝试使用webdriver的静态初始化。希望这对你有帮助。 我的结构很简单: 我有
BaseSeleniumTest.java
存储所有基本方法。我还有其他TestSuite.java
,它们继承了BaseSeleniumTest.java
中的所有方法:
BaseSeleniumTest.java:
package simulator.selenium;
import com.google.common.base.Function;
import com.thoughtworks.selenium.SeleneseTestBase;
import org.apache.commons.lang.RandomStringUtils;
import org.junit.AfterClass;
import org.junit.Before;
import org.junit.BeforeClass;
import org.openqa.selenium.*;
import org.openqa.selenium.remote.DesiredCapabilities;
import org.openqa.selenium.remote.RemoteWebDriver;
import org.openqa.selenium.support.ui.FluentWait;
import org.openqa.selenium.support.ui.Wait;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.beans.factory.config.PropertyPlaceholderConfigurer;
import org.springframework.core.io.support.PropertiesLoaderUtils;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.Properties;
import java.util.concurrent.TimeUnit;
public class BaseSeleniumTest extends SeleneseTestBase {
static WebDriver driver;
private static Logger log = LoggerFactory.getLogger(BaseSeleniumTest.class);
private String loginBaseUrl;
@BeforeClass
public static void firefoxSetUp() throws MalformedURLException {
DesiredCapabilities capability = DesiredCapabilities.firefox();
driver = new FirefoxDriver();
driver.manage().timeouts().implicitlyWait(20, TimeUnit.SECONDS);
driver.manage().timeouts().pageLoadTimeout(30, TimeUnit.SECONDS);
driver.manage().window().setSize(new Dimension(1920, 1080));
}
@Before
public void homePageRefresh() throws IOException {
driver.manage().deleteAllCookies();
driver.get(propertyKeysLoader("login.base.url"));
}
@AfterClass
public static void closeFirefox(){
driver.quit();
}
public WebElement findElementByXpath(String key) throws IOException {
int i=0;
while(!isElementPresent(By.xpath(propertyKeysLoader(key))) && i<5){
driver.manage().timeouts().implicitlyWait(1, TimeUnit.SECONDS);
i++;
}
return fluentWait(By.xpath(propertyKeysLoader(key)));
}
public WebElement findElementByCssSelector(String key) throws IOException {
int i=0;
while(!isElementPresent(By.cssSelector(propertyKeysLoader(key))) && i<5){
driver.manage().timeouts().implicitlyWait(1, TimeUnit.SECONDS);
i++;
}
}
public void locatorFindingHandling(String key) throws IOException /*throws IOException*/ {
fluentWait(By.cssSelector(propertyKeysLoader(key))).click();
}
public void locatorFindingHandling(String key, String key1) throws IOException {
driver.findElement(By.xpath(propertyKeysLoader(key))).sendKeys(propertyKeysLoader(key1));
}
public String propertyKeysLoader(String key) throws IOException {
Properties props = PropertiesLoaderUtils.loadAllProperties("selenium-config.properties");
PropertyPlaceholderConfigurer props2 = new PropertyPlaceholderConfigurer();
props2.setProperties(props);
return (String)props.get(key) ;
}
public WebElement fluentWait(final By locator){
Wait<WebDriver> wait = new FluentWait<WebDriver>(driver)
.withTimeout(30, TimeUnit.SECONDS)
.pollingEvery(5, TimeUnit.SECONDS)
.ignoring(org.openqa.selenium.NoSuchElementException.class);
WebElement foo = wait.until(
new Function<WebDriver, WebElement>() {
public WebElement apply(WebDriver driver) {
return driver.findElement(locator);
}
}
);
return foo; } ;
public boolean isElementPresent(By selector)
{
return driver.findElements(selector).size()>0;
}
public boolean isElementVisible(By selector){
return driver.findElement(selector).isDisplayed();
}
public void jsDirectClickUsingDOM_GEBi(String key) throws IOException {
JavascriptExecutor js = (JavascriptExecutor) driver;
StringBuilder stringBuilder = new StringBuilder();
stringBuilder.append("document.getElementById(\'"+propertyKeysLoader(key) +"\').click();");
js.executeScript(stringBuilder.toString());
}
public void jsCodeExecution(String jsCode){
JavascriptExecutor js = (JavascriptExecutor)driver;
StringBuilder stringBuilder = new StringBuilder();
stringBuilder.append(jsCode);
js.executeScript(stringBuilder.toString());
}
public void jsDirectClickUsingDOM_GEBTagName(String tagName,int argNum) throws IOException {
JavascriptExecutor js = (JavascriptExecutor) driver;
StringBuilder stringBuilder = new StringBuilder();
// stringBuilder.append("document.getElementsByClassName(\'"+propertyKeysLoader(key) +"\')["+argArrNum+"].click();");
// stringBuilder.append("document.getElementsByTagName(\'"+tagName+"\')[document.getElementsByTagName('div').length-"+argNum+"].click()");
stringBuilder.append("document.getElementsByTagName(\'"+tagName+"\')[document.getElementsByTagName(\'"+tagName+"\').length-"+argNum+"].click()");
js.executeScript(stringBuilder.toString());
}
public String jsGetColor(String css){
JavascriptExecutor js = (JavascriptExecutor) driver;
StringBuilder stringBuilder = new StringBuilder();
stringBuilder.append("var x=$(\'"+css+"\');");
stringBuilder.append("return x.css('color')");
String res= (String) js.executeScript(stringBuilder.toString());
return res;
}
public String randomStringGenerator(){
return RandomStringUtils.randomAlphabetic(8);
}
public String randomIntSequenceGenerator(){
return RandomStringUtils.randomNumeric(6);
}
}
希望这对您有所帮助。您可以像这样扩展RemoteWebDriver并覆盖startSession方法:
@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());
}
}
将此代码放在创建驱动程序的类中。您可以像这样扩展RemoteWebDriver并重写startSession方法:
@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());
}
}
将此代码放在创建驱动程序的类中。这对我来说很有用
这对我来说很有用
这似乎很有帮助!我稍后会尝试一下,但它是有意义的!非常感谢。嗯,只是一个问题,你的情况下SeleneTestBase是什么?你有BaseSeleniumTest扩展它。我假设BaseSeleniumTest是一个抽象类,在这个抽象类中有其他东西对其进行了扩展?那么,com.thoughtworks.selenium(SeleniumFramework类)中的类SeleneseTestBase提供了一个基类,该基类实现了一些方便的selenium测试功能(您不需要扩展这个类)。这个类添加了许多“verify”命令,它们类似于“assert”命令,但是当它们失败时不会停止测试。相反,在拆卸过程中会一次性抛出所有验证错误。详细信息:事实证明,我所要求的答案相当简单:只需使用[TestFixtureTearDown]而不是[TearDown],它将为同一类中定义的所有测试用例保留一个窗口:)注释掉驱动程序。退出();在测试脚本中,它有条件地调用webdriver,比如if(driver==null){//code调用所需的webdriver}或者{//do nothing}……您的测试将在单个会话中进行。这似乎非常有用!我稍后会尝试一下,但它是有意义的!非常感谢。嗯,只是一个问题,你的情况下SeleneTestBase是什么?你有BaseSeleniumTest扩展它。我假设BaseSeleniumTest是一个抽象类,在这个抽象类中有其他东西对其进行了扩展?那么,com.thoughtworks.selenium(SeleniumFramework类)中的类SeleneseTestBase提供了一个基类,该基类实现了一些方便的selenium测试功能(您不需要扩展这个类)。这个类添加了许多“verify”命令,它们类似于“assert”命令,但是当它们失败时不会停止测试。相反,在拆卸过程中会一次性抛出所有验证错误。详细信息:事实证明,我所要求的答案相当简单:只需使用[TestFixtureTearDown]而不是[TearDown],它将为同一类中定义的所有测试用例保留一个窗口:)注释掉驱动程序。退出();在测试脚本中,它有条件地调用webdriver,比如if(driver==null){//code来调用所需的webdriver}或者{//do nothing}……您的测试将在单个会话中进行。嗯,似乎C#对startSession和GetPreviousSessiondFromSomeStorage等有另一个命名约定……这看起来也不错。嗯,似乎C#对startSession和GetPreviousSessiondFromsomeStorage等有另一种命名约定……这看起来也不错。