selenium:element.clear()在sendkeys()之前触发javascript

vxbzzdmp  于 2021-07-13  发布在  Java
关注(0)|答案(4)|浏览(428)

我有一个应该包含日期的输入字段。
假设表单在字段内加载了一个值,例如“2015/04/28”。我使用webdriver选择元素,然后使用:

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方法运行在“更改”、“模糊”和“焦点”上,用于更新字段值。
所以我跑了 element.clear() 它必须触发这三个中的一个,因为在清除之后,代码将插入模板数据。
当我到达element.sendkeys()时,损坏已经完成。
所以不知怎么的,在clear()和sendkeys()之间,在网站上调用“change”、“blur”或“focus”,对我来说最合理的解释是,字段不知怎么会失去焦点。

z9gpfhce

z9gpfhce1#

您可以尝试通过发送backspace来清除输入。

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

(或者是你发送正确数量的 BACK_SPACE 在一个单独的 sendKeys 调用。)
或者,使用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);
    }
}
gpfsuwkq

gpfsuwkq2#

这个问题实际上是在这篇文章中描述的,它链接到一个selenium bug,不幸的是它被设置为“workingasintended”。
基本上是 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()

2q5ifsrm

2q5ifsrm3#

看看这个,可能有用。类似于ekuusela的建议,但您可以尝试ctrl+a,然后键入。
https://groups.google.com/forum/#!topic/selenium用户/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)).
rnmwe5a2

rnmwe5a24#

几周前我自己也有类似的问题。问题是我只是偶尔遇到这个问题。通过将进程封闭在while循环中,检索sendkeys()发送后的日期来解决此问题。然后将检索到的日期与正则表达式进行比较,如果日期与正则表达式不匹配,则再次重复clear()->sendkeys()操作。
为了回答您的第一个问题,我使用了一个自定义方法,该方法将等待活动请求数==0。你的第二个问题不太清楚。

相关问题