我有一个想法,如果Selenium2在有限的时间内轮询后未能检索到WebElement对象,则将故障转移到JavascriptExecutor。如您所见,该方法的局限性是在调用getElementByLocator时需要预先定义“故障转移” Javascript代码段。我想不出任何办法来动态地做到这一点。如果有人可以帮助我改善这一点,则无论答案多么小,我都会给出最佳建议的答案。
// failover example1: "document.getElementById('gbqfb')"
// failover example2: "document.querySelector("div#gbqfb")"
public static WebElement getElementByLocator(final By locator, String failover) {
Wait<WebDriver> wait = new FluentWait<WebDriver>(driver)
.withTimeout(30, TimeUnit.SECONDS)
.pollingEvery(5, TimeUnit.SECONDS);
.ignoring(NoSuchElementException.class,StaleElementReferenceException.class);
WebElement we = wait.until( ExpectedConditions
.presenceOfElementLocated( locator ) );
if ( we.isNull() ) {
JavascriptExecutor js = (JavascriptExecutor) driver;
if ( !failover.isEmpty() ) {
we = (WebElement)js.executeScript( failover );
if ( we.isNull() ) LOG.info("Still couldn't get element.");
} else {
LOG.info("No failover String available. Cannot try with " +
"a JavascriptExecutor.");
}
}
return we;
}
最佳答案
实际上回答了类似的问题here
我不建议将任何东西委托给javascript这样的东西。使用Selenium给您的东西就足够了。
我在我建立的每个框架中都放了一些东西,这非常有效。.这是从here找到的框架摘录的内容。
在对对象执行任何操作之前,我先实现了一种伪等待类型的方法。自己尝试。非常有效。
这些是AutomationTest类中的方法
/**
* Checks if the element is present or not.<br>
* @param by
* @return <i>this method is not meant to be used fluently.</i><br><br.
* Returns <code>true</code> if the element is present. and <code>false</code> if it's not.
*/
public boolean isPresent(By by) {
if (driver.findElements(by).size() > 0) return true;
return false;
}
/**
* Private method that acts as an arbiter of implicit timeouts of sorts.. sort of like a Wait For Ajax method.
*/
private WebElement waitForElement(By by) {
int attempts = 0;
int size = driver.findElements(by).size();
while (size == 0) {
size = driver.findElements(by).size();
if (attempts == MAX_ATTEMPTS) fail(String.format("Could not find %s after %d seconds",
by.toString(),
MAX_ATTEMPTS));
attempts++;
try {
Thread.sleep(1000); // sleep for 1 second.
} catch (Exception x) {
fail("Failed due to an exception during Thread.sleep!");
x.printStackTrace();
}
}
if (size > 0) System.err.println("WARN: There are more than 1 " + by.toString() + " 's!");
return driver.findElement(by);
}
我所做的就是随时执行某项操作,例如
getText(By.cssSelector("input#someId"))
如果它不是第一次找到它,它将等待1秒钟。如果找到它,则继续。随后执行5次,所以总共要等待5秒钟。这完全可以,因为如果您没有找到所需的元素,那么您的测试实际上应该会失败。
另外,根据经验,我可以告诉您,使用
driver.findElements()
比使用WebDriverWait
更有效。那并不意味着我不使用它们。不幸的是,我没有在Selenium框架入门中添加此功能,所以我只告诉您何时使用Webdriverwait。
所以我的测试看起来像-
@Config(url="http://systemunder.test", browser=CHROME)
public class MyClass extends AutomationTest {
@Test
public void testSomething() {
setText(By.id("blah")) // if <* id="blah" /> doesn't exist, waits 1+ seconds for it to appear before interacting.
.click(By.id("Blah2")) // ^ same thing here.
.waitForPresent(By.cssSelector("ajaxy")); // this method right here would circumvent the hard waits, with webdriverwait's.
}
}
我不记得是为什么以前对我不起作用,但是在这种情况下使用webdriverwaits是完美的。
关于java - Selenium2 findElement失败时故障转移到JavascriptExecutor吗?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/19286092/