Selenium:element.clear()在sendKeys()

时间:2015-04-28 12:30:09

标签: java selenium webdriver

我有一个应该包含日期的输入字段。

假设表单在字段内部加载了值,例如" 2015/04/28 34#;.我使用webdriver使用By选择元素,然后我执行:

element.clear();
element.sendKeys("2015/04/29");

不幸的是,当我清除元素时,会触发一些加载模板的javascript" yyyy / MM / dd"并把它放在字段中,所以当sendKeys()出现时,结果是" yyyy / MM / dd2015 / 04/29"。

当您手动执行这些步骤时不会发生这种情况,如果您转到该字段并选择其中的所有内容并将其删除,则在切换到其他元素之前,它不会加载模板

因此,javascript似乎不是简单地通过改变字段而是与失去焦点相结合而触发的。我已经尝试了很多方法来关注输入元素:

new Actions(driver).moveToElement(element).perform();
new Actions(driver).moveToElement(element).click().perform();
element.click()
element.sendKeys("")    // before the other sendKeys

但是当我使用webdriver时,同样的事情仍在发生。 所以有两个问题:

  • 您如何处理由您执行的操作触发但可能影响您正在执行的操作的异步JavaScript调用?等待?
  • 在这个特定的问题中,似乎是焦点驱动的,是否有某种方式该字段在clear()和sendKeys()之间失去焦点?

更新

详细说明:它是一个"文本"输入字段,其上运行javascript方法"更改","模糊"和#34;焦点"更新字段值。

所以我运行element.clear() 必须触发这三个中的一个,因为在清除代码后插入模板数据。

当我到达element.sendKeys()时,损坏已经完成。

所以不知何故,在clear()和sendKeys()之间,"更改","模糊"或者"专注"在网站上被调用,对我来说最合乎逻辑的解释是该领域不知何故失去了焦点。

4 个答案:

答案 0 :(得分:1)

您可以尝试通过发送退格键来清除输入。

public static void clearWithBackspace(WebElement input) {
    while(input.getAttribute("value").length() > 0) {
        input.sendKeys(Keys.BACK_SPACE);
    }
}

(或者您在单BACK_SPACE次调用中发送正确数量的sendKeys s后跟您想要的文本的某种变体。)

或者,也可以使用JavascriptExecutor执行的JavaScript设置输入值。

您如何处理异步JavaScript调用

我等了要么是一些估计数量,要么我想要具体:执行我自己的脚本并等待完成。这是有效的,因为JavaScript的事件循环只有在其他所有内容都已完成时才会执行您的脚本。像这样:

public static void waitForScriptExecution() {
    executeJs("var sc = document.createElement('script'); sc.innerHTML = 'window.allDone = true;'; document.body.appendChild(sc);");
    int maxWait = 6000;
    int waitTimeSoFar = 0;
    int waitIntervalMs = 500;
    do {
        if (executeJs("return window.allDone").equals("true")) {
            break;
        }
        waitFor(waitIntervalMs, MILLISECONDS);
        waitTimeSoFar = waitTimeSoFar + waitIntervalMs;
    } while (waitTimeSoFar < maxWait);
    if (waitTimeSoFar >= maxWait) {
        // TODO handle timeout
    }
}

public static String executeJs(String script) {
    JavascriptExecutor js = (JavascriptExecutor) driver;
    Object result = js.executeScript(script);
    return result != null ? result.toString() : null;
}

public static void waitFor(long count, TimeUnit timeUnit) {
    try {
        Thread.sleep(timeUnit.toMillis(count));
    } catch (InterruptedException e) {
        throw new RuntimeException(e);
    }
}

答案 1 :(得分:1)

检查出来,可能有所帮助。 类似于ekuusela建议的, 但您可以尝试Ctrl + A然后键入。

https://groups.google.com/forum/#!topic/selenium-users/OqRAQmmABJY

此处添加示例以确保完整性,

 element.sendKeys(Keys.chord(Keys.CONTROL, "a"), value));
 element.sendKeys(Keys.chord(Keys.END, Keys.BACKSPACE, Keys.BACKSPACE, ... (enough backspaces to erase the field)), value)).

答案 2 :(得分:1)

问题实际上是in this post,它链接到selenium bug,不幸的是设置为&#34; WorkingAsIntended&#34;。

基本上:clear()会触发change事件。

我的解决方案(根据上述帖子中的答案)是:

    Actions navigator = new Actions(driver);
    navigator.click(element)
        .sendKeys(Keys.END)
        .keyDown(Keys.SHIFT)
        .sendKeys(Keys.HOME)
        .keyUp(Keys.SHIFT)
        .sendKeys(Keys.BACK_SPACE)
        .perform();

之后我执行element.sendKeys()

答案 3 :(得分:0)

几个星期前我自己也遇到过类似的问题。事情是我偶尔只遇到问题。通过将进程封闭在while循环中解决它,在sendkeys()发送后检索日期。然后将检索到的日期与正则表达式进行比较,如果日期与正则表达式不匹配,则重复clear() - &gt;再次发送sendKeys()动作。

要回答您的第一个问题,我使用自定义方法,等待活动请求的数量== 0.在第二个问题上不确定。