Selenium中的waitForCondition 使用和编写自己的waitForElementDisplay方法
在我们在页面跳转的时候或者进行了一些操作的时候,我们需要等待某个页面或者元素的出现。 对与页面的跳转我们可以用selenium.waitForPageLoad 方法,但是对于等待某个元素的出现并没有提供,只提供了一个waitForCondition 的方法。
waitForCondition 方法会执行传入的js代码,直到条件成立,或者 timout时间到。
selenium.waitForCondition("var value = selenium.browserbot.findElementOrNull(“id1”); value.style.display == 'none'", "10000");
waitForCondition 方法中也可以有运算符的操作
selenium.waitForCondition("var value = selenium.browserbot.findElementOrNull(id1); value.style.display == 'none'", || var value = selenium.browserbot.findElementOrNull(id2); value.style.display == 'none' “, "10000");
当然每次我们都去写js 代码,这样会很麻烦,而且上面的代码只能判断display属性为none, 我们可以用selenium 自带的 isVisible方法来判断一个Element是否存在。 因为isVisible方法判断的跟全面,它还判断了visibility 和 hiden 属性。 所以我们可以创建一个更加通用的方法叫做waitForEelementDisplay 方法。 下面是代码实现:
package com.safx.selenium;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.ScheduledThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import com.safx.utility.CommonTool;
import com.thoughtworks.selenium.SeleniumException;
public class DriveSelenium
{
ScheduledThreadPoolExecutor executor = null;
public boolean waitForElementDisplay(String locator, String time) {
SheduleEntity entity = new SheduleEntity(CommonTool.String2Int(time));
this.schedule(entity);
int tempTime = 1000;
while (!entity.isTimeout()) {
if (selenium.isVisible(locator)) { // call selenium.isVisable method
this.shutdownAndAwaitTermination(executor);
return true;
}
Thread.sleep(tempTime);
}
throw new SeleniumException("ERROR: wait for '" + locator + "' " + time + "s time out!");
}
private void schedule(final SheduleEntity shedule) {
executor = new ScheduledThreadPoolExecutor(1);
executor.schedule(new Runnable() {
@Override
public void run() {
shedule.setTimeout(true);
}
}, shedule.getTempTime(), TimeUnit.SECONDS);
}
private void shutdownAndAwaitTermination(ExecutorService pool) {
pool.shutdown(); // Disable new tasks from being submitted
try {
// Wait a while for existing tasks to terminate
if (!pool.awaitTermination(5, TimeUnit.SECONDS)) {
pool.shutdownNow(); // Cancel currently executing tasks
// Wait a while for tasks to respond to being cancelled
if (!pool.awaitTermination(5, TimeUnit.SECONDS))
System.err.println("Pool did not terminate");
}
} catch (InterruptedException ie) {
// (Re-)Cancel if current thread also interrupted
pool.shutdownNow();
// Preserve interrupt status
Thread.currentThread().interrupt();
}
}
class SheduleEntity{
private boolean isTimeout = false;
private int tempTime;
public SheduleEntity( int tempTime ) {
this.tempTime = tempTime;
}
public void setTimeout(boolean isTimeout) {
this.isTimeout = isTimeout;
}
public boolean isTimeout() {
return isTimeout;
}
public int getTempTime() {
return tempTime;
}
}
}
在上面的代码中,
1. 定义一个scheduleEntiy类 用来保存,timout 延时时间 和 isTimeout 是否已经延时
2. 通过 ScheduledThreadPoolExecutor 类 当定时器使用,当timeout时间到是,把 ScheduleEntiy类中的isTimeout设置为True。
3. 我们定义了一个 waitForElementDisplay 方法。 在这个方法中做一个每隔一秒的无限循环,循环调用isVisible这个方法。如果改Element出现则返回true,如果不出现直到timeout时间到,则抛个异常出来。