我使用selenium IDE来初始记录测试并将它们保存为Java WebDriver测试。
当我进入输入字段时,删除所有文本并输入新值,它将其记录为2个命令:
driver.findElement(By.id("username")).clear();
driver.findElement(By.id("username")).sendKeys("johnnyleitrim");
对我来说,一个问题是clear()事件会触发“username”字段的Javascript更改事件。当我使用浏览器本身时不会发生这种情况 - 它会等到字段在触发更改javascript事件之前失去焦点,这就是我想在Selenium中模拟的内容。
我需要这个的原因是我对change()事件进行了验证,并且当使用空值调用change时,它会显示一条警告,告诉用户信息无效 - 此警报会停止Selenium
那么如何在不使用WebElement.clear()
的情况下清除字段?
答案 0 :(得分:8)
您可以避免使用clear()
方法并使用Actions
类一次清除和设置文本,因此只有在设置文本后才会触发onchange()
事件。
请调用以下方法:
ClearAndSetText(By.id("username"),"johnnyleitrim");
该方法单击元素,使用shift + home键选择现有文本,使用退格键清除,然后键入新文本 - 就像用户的行为一样。
public void ClearAndSetText(By by, string text)
{
WebElement element = driver.findElement(by);
Actions navigator = new Actions(driver);
navigator.click(element)
.sendKeys(Keys.END)
.keyDown(Keys.SHIFT)
.sendKeys(Keys.HOME)
.keyUp(Keys.SHIFT)
.sendKeys(Keys.BACK_SPACE)
.sendKeys(text)
.perform();
}
答案 1 :(得分:1)
您可以使用JavaScriptExecutor
进行尝试(虽然我尚未对其进行测试)。
JavaScriptExecutor js = (JavaScriptExecutor) driver;
js.executeScript("document.querySelector(\"input[id='username']\").value = ''");
答案 2 :(得分:0)
好像是known Selenium bug。在bug页面上提到的解决方法有一些选项,但它们都意味着必须“大量”修改从Selenium IDE返回的代码。相反,我决定创建一个代理,它可以为我完成工作,而无需对IDE生成的代码进行太多修改:
protected WebElement findElement(By criteria) {
try {
WebElementHandler webElementHander = new WebElementHandler(seleniumWebDriver.findElement(criteria));
return (WebElement) Proxy.newProxyInstance(getClass().getClassLoader(), new Class[]{WebElement.class}, webElementHander);
} catch (NoSuchElementException e) {
logger.error("Could not find " + criteria + " on page " + seleniumWebDriver.getCurrentUrl());
throw e;
}
}
private class WebElementHandler implements InvocationHandler {
private WebElement proxiedElement;
private WebElementHandler(WebElement proxiedElement) {
this.proxiedElement = proxiedElement;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
if (method.getName().equals("clear")) {
Keys[] keys = new Keys[proxiedElement.getAttribute("value").length()];
for (int i = 0; i < keys.length; i++)
keys[i] = Keys.BACK_SPACE;
proxiedElement.sendKeys(Keys.chord(keys));
return null;
}
return method.invoke(proxiedElement, args);
}
}