Issue #15 Selenium2.0使用升级
使用WebDriverWait与ExpectedConditions实现灵活等待。 取消对Selenium1.0的依赖,通过加大implicitlyWait解决waitForPageLoad的问题。
This commit is contained in:
@@ -40,7 +40,7 @@
|
||||
<!-- Spring Data Jpa配置 -->
|
||||
<jpa:repositories base-package="org.springside.examples.miniweb" transaction-manager-ref="transactionManager" entity-manager-factory-ref="entityManagerFactory"/>
|
||||
|
||||
<!-- JPpa 事务配置 -->
|
||||
<!-- Jpa 事务配置 -->
|
||||
<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
|
||||
<property name="entityManagerFactory" ref="entityManagerFactory"/>
|
||||
</bean>
|
||||
@@ -103,6 +103,7 @@
|
||||
</property>
|
||||
</bean>
|
||||
|
||||
<!-- 非Pool的简单data source -->
|
||||
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
|
||||
<property name="driverClassName" value="${jdbc.driver}" />
|
||||
<property name="url" value="${jdbc.url}" />
|
||||
@@ -110,6 +111,7 @@
|
||||
<property name="password" value="${jdbc.password}" />
|
||||
</bean>
|
||||
|
||||
<!-- 初始化数据结构 -->
|
||||
<jdbc:initialize-database data-source="dataSource" ignore-failures="ALL">
|
||||
<jdbc:script location="classpath:sql/h2/schema.sql" />
|
||||
</jdbc:initialize-database>
|
||||
|
||||
+2
-2
@@ -94,7 +94,7 @@ public class BaseFunctionalTestCase {
|
||||
s.type(By.name("username"), "admin");
|
||||
s.type(By.name("password"), "admin");
|
||||
s.check(By.name("rememberMe"));
|
||||
s.clickTo(By.id("submit"));
|
||||
s.click(By.id("submit"));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -105,6 +105,6 @@ public class BaseFunctionalTestCase {
|
||||
s.open("/logout");
|
||||
s.type(By.name("username"), user);
|
||||
s.type(By.name("password"), password);
|
||||
s.clickTo(By.id("submit"));
|
||||
s.click(By.id("submit"));
|
||||
}
|
||||
}
|
||||
+6
-6
@@ -26,7 +26,7 @@ public class GroupManagerIT extends BaseFunctionalTestCase {
|
||||
*/
|
||||
@Test
|
||||
public void viewGroupList() {
|
||||
s.clickTo(By.linkText(Gui.MENU_GROUP));
|
||||
s.click(By.linkText(Gui.MENU_GROUP));
|
||||
WebElement table = s.findElement(By.xpath("//table[@id='contentTable']"));
|
||||
assertEquals("管理员", s.getTable(table, 1, GroupColumn.NAME.ordinal()));
|
||||
assertEquals("查看用戶,修改用户,查看权限组,修改权限组", s.getTable(table, 1, GroupColumn.PERMISSIONS.ordinal()));
|
||||
@@ -37,8 +37,8 @@ public class GroupManagerIT extends BaseFunctionalTestCase {
|
||||
*/
|
||||
@Test
|
||||
public void createGroup() {
|
||||
s.clickTo(By.linkText(Gui.MENU_GROUP));
|
||||
s.clickTo(By.linkText("创建权限组"));
|
||||
s.click(By.linkText(Gui.MENU_GROUP));
|
||||
s.click(By.linkText("创建权限组"));
|
||||
|
||||
//生成测试数据
|
||||
Group group = AccountData.getRandomGroupWithPermissions();
|
||||
@@ -55,7 +55,7 @@ public class GroupManagerIT extends BaseFunctionalTestCase {
|
||||
}
|
||||
}
|
||||
|
||||
s.clickTo(By.id("submit"));
|
||||
s.click(By.id("submit"));
|
||||
|
||||
//校验结果
|
||||
assertTrue(s.isTextPresent("创建权限组" + group.getName() + "成功"));
|
||||
@@ -63,8 +63,8 @@ public class GroupManagerIT extends BaseFunctionalTestCase {
|
||||
}
|
||||
|
||||
private void verifyGroup(Group group) {
|
||||
s.clickTo(By.linkText(Gui.MENU_GROUP));
|
||||
s.clickTo(By.id("editLink-" + group.getName()));
|
||||
s.click(By.linkText(Gui.MENU_GROUP));
|
||||
s.click(By.id("editLink-" + group.getName()));
|
||||
assertEquals(group.getName(), s.getValue(By.id("name")));
|
||||
|
||||
List<WebElement> checkBoxes = s.findElements(By.name("permissionList"));
|
||||
|
||||
+2
-2
@@ -41,10 +41,10 @@ public class SecurityIT extends BaseFunctionalTestCase {
|
||||
//登录普通用户
|
||||
s.type(By.name("username"), "user");
|
||||
s.type(By.name("password"), "user");
|
||||
s.clickTo(By.id("submit"));
|
||||
s.click(By.id("submit"));
|
||||
|
||||
//校验用户权限组的操作单元格只有查看
|
||||
s.clickTo(By.linkText(Gui.MENU_USER));
|
||||
s.click(By.linkText(Gui.MENU_USER));
|
||||
assertEquals("", s.getTable(By.id("contentTable"), 1, UserColumn.OPERATIONS.ordinal()));
|
||||
}
|
||||
}
|
||||
|
||||
+8
-8
@@ -28,7 +28,7 @@ public class UserManagerIT extends BaseFunctionalTestCase {
|
||||
*/
|
||||
@Test
|
||||
public void viewUserList() {
|
||||
s.clickTo(By.linkText(Gui.MENU_USER));
|
||||
s.click(By.linkText(Gui.MENU_USER));
|
||||
WebElement table = s.findElement(By.id("contentTable"));
|
||||
assertEquals("admin", s.getTable(table, 1, UserColumn.LOGIN_NAME.ordinal()));
|
||||
assertEquals("Admin", s.getTable(table, 1, UserColumn.NAME.ordinal()));
|
||||
@@ -41,8 +41,8 @@ public class UserManagerIT extends BaseFunctionalTestCase {
|
||||
@Test
|
||||
public void createUser() {
|
||||
//打开新增用户页面
|
||||
s.clickTo(By.linkText(Gui.MENU_USER));
|
||||
s.clickTo(By.linkText("创建用户"));
|
||||
s.click(By.linkText(Gui.MENU_USER));
|
||||
s.click(By.linkText("创建用户"));
|
||||
|
||||
//生成待输入的测试用户数据
|
||||
User user = AccountData.getRandomUserWithGroup();
|
||||
@@ -61,7 +61,7 @@ public class UserManagerIT extends BaseFunctionalTestCase {
|
||||
}
|
||||
|
||||
}
|
||||
s.clickTo(By.id("submit"));
|
||||
s.click(By.id("submit"));
|
||||
|
||||
//校验结果
|
||||
assertTrue(s.isTextPresent("创建用户" + user.getLoginName() + "成功"));
|
||||
@@ -73,7 +73,7 @@ public class UserManagerIT extends BaseFunctionalTestCase {
|
||||
*/
|
||||
private void verifyUser(User user) {
|
||||
|
||||
s.clickTo(By.id("editLink-" + user.getLoginName()));
|
||||
s.click(By.id("editLink-" + user.getLoginName()));
|
||||
|
||||
assertEquals(user.getLoginName(), s.getValue(By.id("loginName")));
|
||||
assertEquals(user.getName(), s.getValue(By.id("name")));
|
||||
@@ -103,8 +103,8 @@ public class UserManagerIT extends BaseFunctionalTestCase {
|
||||
*/
|
||||
@Test
|
||||
public void inputInValidateUser() {
|
||||
s.clickTo(By.linkText(Gui.MENU_USER));
|
||||
s.clickTo(By.linkText("创建用户"));
|
||||
s.click(By.linkText(Gui.MENU_USER));
|
||||
s.click(By.linkText("创建用户"));
|
||||
|
||||
s.type(By.id("loginName"), "admin");
|
||||
s.type(By.id("name"), "");
|
||||
@@ -112,7 +112,7 @@ public class UserManagerIT extends BaseFunctionalTestCase {
|
||||
s.type(By.id("passwordConfirm"), "abc");
|
||||
s.type(By.id("email"), "abc");
|
||||
|
||||
s.clickTo(By.id("submit"));
|
||||
s.click(By.id("submit"));
|
||||
|
||||
Threads.sleep(2000);
|
||||
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
<context-param>
|
||||
<param-name>contextConfigLocation</param-name>
|
||||
<param-value>
|
||||
classpath*:/applicationContext-test.xml
|
||||
classpath*:/applicationContext.xml
|
||||
classpath*:/applicationContext-shiro.xml
|
||||
</param-value>
|
||||
</context-param>
|
||||
@@ -50,7 +50,6 @@
|
||||
<url-pattern>/*</url-pattern>
|
||||
</filter-mapping>
|
||||
|
||||
|
||||
<!-- Shiro Security filter-->
|
||||
<filter>
|
||||
<filter-name>shiroFilter</filter-name>
|
||||
|
||||
+3
-3
@@ -16,10 +16,10 @@ public class AjaxIT extends BaseSeleniumTestCase {
|
||||
@Test
|
||||
public void mashup() {
|
||||
s.open("/");
|
||||
s.clickTo(By.linkText("Web演示"));
|
||||
s.clickTo(By.linkText("跨域名Mashup演示"));
|
||||
s.click(By.linkText("Web演示"));
|
||||
s.click(By.linkText("跨域名Mashup演示"));
|
||||
|
||||
s.clickTo(By.xpath("//input[@value='获取内容']"));
|
||||
s.click(By.xpath("//input[@value='获取内容']"));
|
||||
s.waitForVisible(By.id("mashupContent"), 5000);
|
||||
assertEquals("Hello World!", s.getText(By.id("mashupContent")));
|
||||
}
|
||||
|
||||
+5
-5
@@ -16,20 +16,20 @@ public class UserManagerIT extends BaseSeleniumTestCase {
|
||||
@Test
|
||||
public void editUser() {
|
||||
s.open("/");
|
||||
s.clickTo(By.linkText("综合演示"));
|
||||
s.clickTo(By.id("editLink-user"));
|
||||
s.click(By.linkText("综合演示"));
|
||||
s.click(By.id("editLink-user"));
|
||||
|
||||
//修改用户需要登录管理员权限
|
||||
s.type(By.name("username"), "admin");
|
||||
s.type(By.name("password"), "admin");
|
||||
s.clickTo(By.id("submit"));
|
||||
s.click(By.id("submit"));
|
||||
|
||||
//点击提交按钮
|
||||
s.type(By.name("name"), "user_foo");
|
||||
s.clickTo(By.id("submit"));
|
||||
s.click(By.id("submit"));
|
||||
|
||||
//重新进入用户修改页面, 检查最后修改者
|
||||
s.clickTo(By.id("editLink-user"));
|
||||
s.click(By.id("editLink-user"));
|
||||
assertEquals("user_foo", s.getValue(By.name("name")));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,15 +6,15 @@
|
||||
package org.springside.modules.test.functional;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import org.openqa.selenium.By;
|
||||
import org.openqa.selenium.NoSuchElementException;
|
||||
import org.openqa.selenium.WebDriver;
|
||||
import org.openqa.selenium.WebDriverBackedSelenium;
|
||||
import org.openqa.selenium.WebElement;
|
||||
import org.springside.modules.utils.Threads;
|
||||
|
||||
import com.thoughtworks.selenium.Selenium;
|
||||
import org.openqa.selenium.support.ui.ExpectedCondition;
|
||||
import org.openqa.selenium.support.ui.ExpectedConditions;
|
||||
import org.openqa.selenium.support.ui.WebDriverWait;
|
||||
|
||||
/**
|
||||
* 融合了Selenium 1.0 API与Selenium 2.0的By选择器的API.
|
||||
@@ -23,32 +23,30 @@ import com.thoughtworks.selenium.Selenium;
|
||||
*/
|
||||
public class Selenium2 {
|
||||
|
||||
public static final int DEFAULT_TIMEOUT = 5000;
|
||||
public static final int DEFAULT_PAUSE_TIME = 250;
|
||||
|
||||
public static int DEFAULT_WAIT_TIME = 20;
|
||||
private WebDriver driver;
|
||||
private Selenium selenium;
|
||||
private int defaultTimeout = DEFAULT_TIMEOUT;
|
||||
private String baseUrl;
|
||||
|
||||
public Selenium2(WebDriver driver, String baseUrl) {
|
||||
this.driver = driver;
|
||||
this.selenium = new WebDriverBackedSelenium(driver, baseUrl);
|
||||
this.baseUrl = baseUrl;
|
||||
setImplicitlyWait(DEFAULT_WAIT_TIME);
|
||||
}
|
||||
|
||||
/**
|
||||
* 不设置baseUrl的构造函数, 调用open函数时必须使用绝对路径.
|
||||
*/
|
||||
public Selenium2(WebDriver driver) {
|
||||
this(driver, "");
|
||||
this(driver, null);
|
||||
}
|
||||
|
||||
// Driver 函數 //
|
||||
/**
|
||||
* 打开地址,如果url为相对地址, 自动添加baseUrl.
|
||||
* @param url
|
||||
*/
|
||||
public void open(String url) {
|
||||
selenium.open(url);
|
||||
waitForPageToLoad();
|
||||
final String urlToOpen = url.indexOf("://") == -1 ? baseUrl + (!url.startsWith("/") ? "/" : "") + url : url;
|
||||
driver.get(urlToOpen);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -59,12 +57,28 @@ public class Selenium2 {
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取页面地址.
|
||||
* 退出Selenium.
|
||||
*/
|
||||
public String getLocation() {
|
||||
return driver.getCurrentUrl();
|
||||
public void quit() {
|
||||
driver.quit();
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置如果查找不到Element时的默认最大等待时间。
|
||||
*/
|
||||
public void setImplicitlyWait(int seconds) {
|
||||
driver.manage().timeouts().implicitlyWait(seconds, TimeUnit.SECONDS);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取WebDriver实例, 调用未封装的函数.
|
||||
*/
|
||||
public WebDriver getDriver() {
|
||||
return driver;
|
||||
}
|
||||
|
||||
//Elemenet 函數//
|
||||
|
||||
/**
|
||||
* 查找Element.
|
||||
*/
|
||||
@@ -79,17 +93,10 @@ public class Selenium2 {
|
||||
return driver.findElements(by);
|
||||
}
|
||||
|
||||
/**
|
||||
* 判断页面内是否存在文本内容.
|
||||
*/
|
||||
public boolean isTextPresent(String text) {
|
||||
return selenium.isTextPresent(text);
|
||||
}
|
||||
|
||||
/**
|
||||
* 判断页面内是否存在Element.
|
||||
*/
|
||||
public boolean isElementPresent(By by) {
|
||||
public boolean isPresent(By by) {
|
||||
try {
|
||||
driver.findElement(by);
|
||||
return true;
|
||||
@@ -121,14 +128,6 @@ public class Selenium2 {
|
||||
driver.findElement(by).click();
|
||||
}
|
||||
|
||||
/**
|
||||
* 点击Element, 跳转到新页面.
|
||||
*/
|
||||
public void clickTo(By by) {
|
||||
driver.findElement(by).click();
|
||||
waitForPageToLoad();
|
||||
}
|
||||
|
||||
/**
|
||||
* 选中Element.
|
||||
*/
|
||||
@@ -168,7 +167,7 @@ public class Selenium2 {
|
||||
*/
|
||||
public boolean isChecked(By by) {
|
||||
WebElement element = driver.findElement(by);
|
||||
return element.isSelected();
|
||||
return isChecked(element);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -199,6 +198,47 @@ public class Selenium2 {
|
||||
return element.getAttribute("value");
|
||||
}
|
||||
|
||||
// WaitFor 函數 //
|
||||
/**
|
||||
* 等待Element的内容可见, timeout单位为秒.
|
||||
*/
|
||||
public void waitForVisible(By by, int timeout) {
|
||||
(new WebDriverWait(driver, timeout)).until(ExpectedConditions.visibilityOfElementLocated(by));
|
||||
}
|
||||
|
||||
/**
|
||||
* 等待Element的内容为text, timeout单位为秒.
|
||||
*/
|
||||
public void waitForTextPresent(By by, String text, int timeout) {
|
||||
(new WebDriverWait(driver, timeout)).until(ExpectedConditions.textToBePresentInElement(by, text));
|
||||
}
|
||||
|
||||
/**
|
||||
* 等待Element的value值为value, timeout单位为秒.
|
||||
*/
|
||||
public void waitForValuePresent(By by, String value, int timeout) {
|
||||
(new WebDriverWait(driver, timeout)).until(ExpectedConditions.textToBePresentInElementValue(by, value));
|
||||
}
|
||||
|
||||
/**
|
||||
* 等待其他Conditions, timeout单位为秒.
|
||||
*
|
||||
* @see ExpectedConditions
|
||||
*/
|
||||
public void waitForCondition(ExpectedCondition conditon, int timeout) {
|
||||
(new WebDriverWait(driver, timeout)).until(conditon);
|
||||
}
|
||||
|
||||
// Selenium1.0 函數 //
|
||||
|
||||
/**
|
||||
* 简单判断页面内是否存在文本内容.
|
||||
*/
|
||||
public boolean isTextPresent(String text) {
|
||||
String bodyText = driver.findElement(By.tagName("body")).getText();
|
||||
return bodyText.contains(text);
|
||||
}
|
||||
|
||||
/**
|
||||
* 取得单元格的内容, 序列从0开始, Selnium1.0的常用函数.
|
||||
*/
|
||||
@@ -212,61 +252,4 @@ public class Selenium2 {
|
||||
public String getTable(By by, int rowIndex, int columnIndex) {
|
||||
return getTable(driver.findElement(by), rowIndex, columnIndex);
|
||||
}
|
||||
|
||||
/**
|
||||
* 等待页面载入完成, timeout时间为defaultTimeout的值.
|
||||
*/
|
||||
public void waitForPageToLoad() {
|
||||
waitForPageToLoad(defaultTimeout);
|
||||
}
|
||||
|
||||
/**
|
||||
* 等待页面载入完成, timeout单位为毫秒.
|
||||
*/
|
||||
public void waitForPageToLoad(int timeout) {
|
||||
selenium.waitForPageToLoad(String.valueOf(timeout));
|
||||
}
|
||||
|
||||
/**
|
||||
* 等待Element的内容展现, timeout单位为毫秒.
|
||||
*/
|
||||
public void waitForVisible(By by, int timeout) {
|
||||
long timeoutTime = System.currentTimeMillis() + timeout;
|
||||
while (System.currentTimeMillis() < timeoutTime) {
|
||||
if (isDisplayed(by)) {
|
||||
return;
|
||||
}
|
||||
Threads.sleep(DEFAULT_PAUSE_TIME);
|
||||
}
|
||||
throw new RuntimeException("waitForVisible timeout");
|
||||
}
|
||||
|
||||
/**
|
||||
* 退出Selenium.
|
||||
*/
|
||||
public void quit() {
|
||||
driver.close();
|
||||
driver.quit();
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取WebDriver实例, 调用未封装的函数.
|
||||
*/
|
||||
public WebDriver getDriver() {
|
||||
return driver;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取Selenium实例,调用未封装的函数.
|
||||
*/
|
||||
public Selenium getSelenium() {
|
||||
return selenium;
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置默认页面超时.
|
||||
*/
|
||||
public void setDefaultTimeout(int defaultTimeout) {
|
||||
this.defaultTimeout = defaultTimeout;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user