问题
My web application has menus that open on MouseOver. I'm writing tests using htmlunitdriver.
Test code to trigger menu is
Actions builder = new Actions(driver);
WebElement menu = driver.findElement(By.xpath("//a[starts-with(@href,'/index.html')]"));
Thread.sleep(2000);
builder.moveToElement(menu).build().perform();
Thread.sleep(2000);
driver.findElement(By.xpath("//a[starts-with(@href,'/submenuitem')]")).click();
driver.manage().timeouts().implicitlyWait(40, TimeUnit.SECONDS);
When I run a single test, it passes just fine. But when I try to run all my 80 tests at once, I get
unable to locate node using //a[starts-with(@href,'/submenuitem'
I guess the submenu is not yet open, htmlunitdriver has too much speed. Somethimes a "You may only interact with elements that are visible is occured on single runs too. Can someone help me fix this issue? Using FirefoxDriver or so is not an option for me.
回答1:
Using a manual Thread.sleep(time) to wait for selenium actions is a dirty solution and should not be used at all.
Instead you could run a check is the element is visible before interacting with it.
public void waitUntilVisible(WebDriver driver, WebElement element){
WebDriverWait waiting = new WebDriverWait(driver, 10);
waiting.until(ExpectedConditions.visibilityOf(element));
}
public void waitUntilClickable(WebDriver driver, By locator){
WebDriverWait waiting = new WebDriverWait(driver, 10);
waiting.until(ExpectedConditions.elementToBeClickable(locator));
}
Actions builder = new Actions(driver);
WebElement menu = driver.findElement(By.xpath("//a[starts-with(@href,'/index.html')]"));
waitUntilVisible(driver, menu);
builder.moveToElement(menu).build().perform();
WebElement menuItem = driver.findElement(By.xpath("//a[starts-with(@href,'/submenuitem')]"));
waitUntilClickable(driver, By.xpath("//a[starts-with(@href,'/submenuitem')]"));
menuItem.click();
回答2:
You are using the implicit wait
after finding the submenu
item. I think there is no use for implicit wait there. The most advisable place to use the implicit wait is to declare after initializing the Driver instance
.
One More solution you can use Explicit Wait
to wait for an element in the Page.
Refer this post for more info about the Selenium waits.
来源:https://stackoverflow.com/questions/14750790/actions-and-htmlunitdriver-speed-issue