2

我使用 selenium IDE 最初记录测试并将它们保存为 Java WebDriver 测试。

当我进入输入字段时,删除所有文本并输入一个新值,它会将其记录为 2 个命令:

driver.findElement(By.id("username")).clear();
driver.findElement(By.id("username")).sendKeys("johnnyleitrim");

对我来说,这个问题的一个问题是 clear() 事件为“用户名”字段触发了一个 Javascript 更改事件。当我使用浏览器本身时,这不会发生 - 它会等到字段失去焦点后再触发 change javascript 事件,这就是我想在 Selenium 中模拟的。

我需要这个的原因是我对 change() 事件进行验证,当使用空值调用 change 时,它​​会显示一个警报,告诉用户信息无效 - 这个警报会停止 Selenium

那么如何在不使用的情况下清除该字段WebElement.clear()

4

3 回答 3

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();
}
于 2013-11-08T05:23:09.277 回答
1

您可以尝试使用它JavaScriptExecutor(虽然我还没有测试过)。

JavaScriptExecutor js = (JavaScriptExecutor) driver;
js.executeScript("document.querySelector(\"input[id='username']\").value = ''");
于 2013-11-07T11:50:54.217 回答
0

似乎这是一个已知的 Selenium 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);
    }
}
于 2013-11-07T14:39:38.380 回答