clear()触发javascript更改事件-可选方案?
我使用SeleniumIDE最初记录测试并将它们保存为JavaWebDriver测试 当我进入一个输入字段时,删除所有文本并输入一个新值,它会记录为两个命令:clear()触发javascript更改事件-可选方案?,java,selenium,webdriver,selenium-webdriver,Java,Selenium,Webdriver,Selenium Webdriver,我使用SeleniumIDE最初记录测试并将它们保存为JavaWebDriver测试 当我进入一个输入字段时,删除所有文本并输入一个新值,它会记录为两个命令: driver.findElement(By.id("username")).clear(); driver.findElement(By.id("username")).sendKeys("johnnyleitrim"); 对我来说,这方面的一个问题是clear()事件为“username”字段触发一个Javascript更改事件。这在
driver.findElement(By.id("username")).clear();
driver.findElement(By.id("username")).sendKeys("johnnyleitrim");
对我来说,这方面的一个问题是clear()事件为“username”字段触发一个Javascript更改事件。这在我使用浏览器本身时不会发生——它会等到字段失去焦点后再触发ChangeJavaScript事件,这正是我想在Selenium中模拟的
我之所以需要这样做,是因为我对change()事件进行了验证,当使用空值调用change时,它会显示一个警报,告诉用户该信息无效,并且该警报会停止
那么,如何在不使用
WebElement.clear()
的情况下清除该字段呢?您可以使用JavaScriptExecutor
来尝试它(尽管我还没有测试它)
看起来像是一场比赛。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);
}
}
受保护的WebElement findElement(按标准){
试一试{
WebElementHandler webElementHander=新的WebElementHandler(seleniumWebDriver.findElement(标准));
return(WebElement)Proxy.newProxyInstance(getClass().getClassLoader(),新类[]{WebElement.Class},webElementHander);
}捕获(无接触元素例外e){
logger.error(“在“+seleniumWebDriver.getCurrentUrl()页上找不到“+criteria+”);
投掷e;
}
}
私有类WebElementHandler实现调用处理程序{
私有WebElement proxiedElement;
私有WebElementHandler(WebElement proxiedElement){
this.proxiedElement=proxiedElement;
}
@凌驾
公共对象调用(对象代理、方法、对象[]args)抛出Throwable{
if(method.getName().equals(“clear”)){
Keys[]Keys=新键[proxiedElement.getAttribute(“值”).length()];
for(int i=0;i
您可以避免使用clear()
方法,并使用操作
类一次性清除和设置文本,因此只有在设置文本后才会触发onchange()
事件
调用以下方法,如:
ClearAndSetText(By.id("username"),"johnnyleitrim");
该方法单击元素,使用shift+home键选择现有文本,使用backspace清除,然后键入新文本,就像用户所做的那样
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();
}
非常感谢您的修复!我创造了这个问题:
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();
}