WebDriver:更改事件未触发

时间:2013-05-30 20:27:06

标签: javascript testing knockout.js webdriver

我有一个使用KnockoutJS的应用程序,我正在尝试编写一些测试表单的测试。如果您不了解KnockoutJS,那么它的简短故事就是它提供了从我的视图到我的数据模型的绑定。这意味着当我在输入字段中键入值时,我的基础对象会自动使用该输入字段值进行更新。默认情况下,这是通过更改事件完成的。

我遇到的问题是,当我的WebDriver测试在字段中输入时,更改事件未触发,因此我的基础数据模型没有适当的值。这会导致我的表单验证失败,但不应该。

我已经做了我能在互联网上找到的所有工作。我已经:

  1. 发送了标签键
  2. 点击表单字段
  3. 发送JavaScript代码以触发焦点并模糊事件(在模糊时进行验证)
  4. 在输入
  5. 之前点击了表单字段
  6. 设置等待只是因为这是一个时间问题
  7. 将KnockoutJS更改为更新afterkeydown上的输入字段
  8. 这些都不适合我。我需要一些帮助。

    此外,我已经确认这不是事件冒泡问题,因为我明确删除了所有其他事件,只留下了KnockoutJS更改事件。

    我正在寻找的解决方案是适用于所有浏览器驱动程序的解决方案(...至少是主要的解决方案,例如IE,FF,Chrome,Safari),并且不需要使用jQuery。

    非常感谢任何帮助。

    以下是我用于在字段中键入值的相关代码:

    // find element
    WebElement input = this.element.findElement(By.className("controls"))
                                   .findElement(By.tagName("input"));
    
    // to set focus?
    input.click();
    
    // erase any existing value (because clear does not send any events
    for (int i = 0; i < input.getAttribute("value").length(); i++) {
        input.sendKeys(Keys.BACK_SPACE);
    }
    
    // type in value
    input.sendKeys(text);
    
    // to fire change & blur? (doesnt fire change)
    //input.sendKeys(Keys.TAB);
    
    // to fire change & blur? (doesnt fire change)
    driver.findElement(By.tagName("body")).click();
    

2 个答案:

答案 0 :(得分:4)

所以我相信我已经发现了我的问题。我完全承认这是PEBKAC。如果浏览器窗口没有主动关注计算机(我仍然很奇怪),我忘记了WebDriver有问题。当我调试问题时,我正在使用我的编辑器来逐步完成代码。通过正常运行代码而不从浏览器中移除焦点,事件使用所有三种解决方案(tab,click-away和javascript)按预期激发。

我有一个显示所有三种方法的示例项目,但是我是git和github的主要菜鸟,并且在交付项目时遇到了问题。一旦我明白了,我将与大家分享这个项目。

编辑:在GitHub上获取示例代码(https://github.com/loesak/knockout.webdriver.change.event.test)。您可以将项目作为服务器中的webapp启动并手动运行测试,也可以通过maven(mvn clean install)运行测试。我并没有付出太多努力让这个工作变得健壮,所以假设你安装了Firefox并且端口 0808 8080已经打开。

编辑:修正了已声明的端口号

答案 1 :(得分:3)

所以我现在找到了解决这个问题的方法,但到目前为止,我认为这是正确的解决方案。这确实打破了我不使用jQuery的规则,但我觉得这对我来说没问题,因为KnockoutJS需要加载jQuery。可能有一种简单的'JavaScript方式来做到这一点。我用FireFox,Safari和PhantomJS对此进行了测试。我认为它在Chrome中也能正常工作。我对Internet Explorer没有任何承诺。

将此答案标记为正确答案。正确的解决方案应该是通过WebDriver浏览器触发正确的事件。只有当我相信通过WebDriver无法做到这一点时,才会将此标记为正确答案。

// find element in question
WebElement input = this.element.findElement(By.className("controls"))
                               .findElement(By.tagName("input"));

// click it to fire focus event
input.click();

// erase any existing value
for (int i = 0; i < input.getAttribute("value").length(); i++) {
    input.sendKeys(Keys.BACK_SPACE);
}

// enter in desired text
input.sendKeys(text);

// fire on change event (WebDriver SHOULD DO THIS)
((JavascriptExecutor) driver).executeScript(
        "$(arguments[0]).change(); return true;"
    , input);

// click away to fire blur event
driver.findElement(By.tagName("body")).click();