为什么我的测试中没有触发我的(javascript)更改事件?

时间:2014-07-11 21:50:08

标签: ruby-on-rails-3.2 selenium-webdriver capybara

我有一个包含许多类似文本框的页面,我在Javascript中安装了一个更改侦听器(尽管我编写了Coffeescript)。

示例HTML:

<td class="team" data-node="64" id="team_64">
  <label for="bracket_teams_attributes_(1)">(1)</label>
  <input id="bracket_teams_attributes_name" 
     name="bracket[teams_attributes][name]" size="30" type="text" value="Team 1">
  <input id="bracket_teams_attributes_id" 
     name="bracket[teams_attributes][id]" type="hidden" value="64">
</td>

更改Coffeescript中显示的侦听器:

nameTeam = (target) ->
  send_put(t) for t in $(target)

send_put = (target) ->
  newName = target.value
  node=$(target).closest('td').data('node')
  $.ajax
    type: 'PUT'
    url: $(target).closest('form').attr('action')
    data:
      'team[name]': newName
      'bracket[node]': node

$ ->
  $('input#bracket_teams_attributes_name').on 'change', (e) => nameTeam e.target

忽略性能问题,如果我只是使用应用程序,这将按预期工作 - 无论我如何继续更改文本字段,触发更改事件以及更新数据库。

当我试图学习如何测试Javascript时,我希望能够在我的测试中编写会触发此更改事件的代码。为此,我有以下的Capybara / Javascript / jQuery:

within(NODE_64_CSS) do
    fill_and_click_script =
       %Q(
         $('#{NODE_64_CSS} #{INPUT_TEAM_CSS}').focus().val('#{new_name}');
         $('#{NODE_64_CSS} #{INPUT_TEAM_CSS}').focus().trigger('change');
       )
    page.driver.execute_script(fill_and_click_script)
end

其中常量具有适当的值(它们在测试中的其他位置用于检查最初加载的页面是否正确)。

我花了很多时间搜索StackOverflow和博客试图了解可能阻止我的测试触发更改侦听器的原因,并尝试使用Webkit和其他各种方法更改表单值/触发更改事件,一切都无济于事。如果我使用Webkit和某些版本的send-keys,我在触发send_and_open_page时看不到页面上的更改,但使用Selenium-Webdriver我看到新的输入文字。然而,页面中的更改侦听器未被触发,并且数据库不会更改。

由于我对这个堆栈很陌生,我希望我做了一些明显错误的事情,但我不知道从哪里来看这一点。

我的宝石环境包含:

 cucumber (1.3.11)
     ~/.rvm/gems/ruby-2.0.0-p451/gems/cucumber-1.3.11
 rails (3.2.13)
     ~/.rvm/gems/ruby-2.0.0-p451/gems/rails-3.2.13
 cucumber-rails (1.4.0)
     ~/.rvm/gems/ruby-2.0.0-p451/gems/cucumber-rails-1.4.0
 selenium-webdriver (2.42.0)
     ~/.rvm/gems/ruby-2.0.0-p451/gems/selenium-webdriver-2.42.0
 capybara (2.2.1)
     ~/.rvm/gems/ruby-2.0.0-p451/gems/capybara-2.2.1
 rspec-rails (2.14.1)
     ~/.rvm/gems/ruby-2.0.0-p451/gems/rspec-rails-2.14.1
 capybara-screenshot (0.3.19)
     ~/.rvm/gems/ruby-2.0.0-p451/gems/capybara-screenshot-0.3.19

如果您有其他信息需要解决此问题,我很乐意提供。

更新:

我现在也尝试使用Culerity作为我的Javascript集成测试工具,并且(不出所料,因为它不再维护也不是其基础设施的一部分)我达到了Celerity中存在导致NoMethodError-的错误的程度 - - 对于我的Cabybara:capybara-celerity gem中的服务器实例,未定义'url'。

3 个答案:

答案 0 :(得分:1)

您的代码看起来应该可以正常工作。您可以尝试一件事:在将文本输入字段后,在测试中添加sleep 5调用,以便完成AJAX调用时间。这应该由Capybara处理,但也许那里有问题。

你也可以添加一些console.log左右的语句,以确保问题是没有触发更改处理程序,而不是它是AJAX调用的问题。

答案 1 :(得分:1)

显然,我不清楚这与它有什么关系,我的问题源于使用预编译资产。这很奇怪,因为我的开发和测试环境在功能上是相同的,开发版本就像一个冠军。

在任何情况下,我现在至少可以通过测试来激活更改侦听器。

帮助解决我的问题的SO帖子是:How to avoid precompiled assets being served in development mode?

我到了那里因为这篇帖子在Capybara googlegroup:https://groups.google.com/forum/#!searchin/ruby-capybara/selenium $ 20 $ 20event $ 20%7Csort:date / ruby​​-capybara / u8Tnd6SqD3k / Lou4jBsJuo8J

答案 2 :(得分:0)

我有同样的问题。我很快发现整个js文件没有运行。对我而言,预编译资产似乎也是问题所在。我以前曾手动预编译资产,以便在本地生产中运行Rails。与开发环境不同,测试环境实际上使用了这些预编译的资产。解决方案就是删除资产,因为我不再需要它们。

我在environments/test.rb上添加了一行以防止将来出现这种情况:

  config.assets.prefix = "/assets_test" # don't use production precompiled assets