2013-05-30 82 views
10

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

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

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

  1. 发送Tab键
  2. 点击从表单字段
  3. 远送JavaScript代码火焦点和模糊事件(上模糊时验证)
  4. 输入之前单击窗体域
  5. 组等待只是柜面这是一个时机的问题
  6. 改变KnockoutJS对afterkeydown
更新输入字段

这些都没有为我工作。我需要一些帮助。

此外,我已经证实,这不是一个事件冒泡问题,因为我显式删除了所有其他事件,只剩下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(); 
+0

所以,如果我的理解,它更新'input'场与每个键中风? – Brian

+0

请原谅我提出一个潜在的愚蠢问题,但当您在浏览器中手动与之交互时,问题页面是否正常工作?即如果您在浏览器中查看页面,请输入文本字段并在文本字段中输入标签,模型是否正在更新? – RodneyTrotter

+1

@Brian输入字段由用户更新。当onchange事件触发时(至少应该这样),底层数据模型会更新为输入字段中的值。如果我更改数据模型中的基础值,输入字段将自动更新为新值。这全部由KnockoutJS提供。 – loesak

回答

4

所以我相信我已经发现了我的问题。我会完全承认这是PEBKAC。如果浏览器窗口未在机器上处于活动焦点(我仍然很奇怪),我忘记了WebDriver存在问题。当我调试问题时,我使用我的编辑器遍历代码。通过正常运行代码并且不从浏览器中移除焦点,事件按照预期使用所有三种解决方案(选项卡,点击和JavaScript)进行触发。

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

编辑:得到了GitHub上的示例代码(https://github.com/loesak/knockout.webdriver.change.event.test)。您可以将项目作为webapp在服务器中启动并手动运行测试,也可以通过maven运行测试(mvn clean install)。我没有花费很多精力来使其稳定工作,因此假设您已安装Firefox并且端口 8080处于打开状态。

编辑:固定表示端口号

+0

祝贺解决问题,+1。 – Brian

3

所以我已经找到一种方法来解决这个问题,现在,但截至目前为止我相信这是解决方案正确这确实违反了我关于不使用jQuery的规则,但是我觉得这对我来说没问题,因为KnockoutJS需要加载jQuery。这可能是一种简单的JavaScript方法。我已经使用FireFox,Safari和PhantomJS进行了测试。我认为它在Chrome中也会起作用。我对IE浏览器没有任何承诺。

我是不是去标记这个答案是正确的答案。正确的解决方案应该是通过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(); 
+0

如果您可以提供可重现的场景并**证明**这是WebDriver的问题,那么请提交一个错误。 – Arran

+0

所以我创建了一个项目来重现这一点,并在这样做,我想出了问题。总之,它是一个新手的错误。我会链接到演示项目,但我的git noobness阻止我检查项目。 – loesak