2

I have a page with many similar text-boxes, upon all of which I have installed a change listener in Javascript (though I wrote Coffeescript).

Example 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>

Change listener as it appears in 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

Ignoring performance concerns, this works as intended if I'm just using the app-- regardless of how I proceed from changing a text field, the change event is fired, and the database is updated.

As I'm trying to learn how to test Javascript, I wanted to be able to write code in my test that would trigger this change event. To that end, I have the following bit of 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

where the constants have appropriate values (they're used elsewhere in the test to check that the page as originally loaded is correct).

I have spent many hours scouring StackOverflow and blogs trying to understand what might be preventing my test from triggering the change listener, and have tried this with Webkit and a variety of other methods to change the form values/trigger the change event, all to no avail. If I use Webkit and some version of send-keys, I do not see the changes on the page when I fire send_and_open_page, but using Selenium-Webdriver I do see that the new text is entered. Nevertheless, the change listener in the page isn't fired, and the database doesn't change.

As I'm pretty new to this stack, I expect I've done something obviously wrong, but I've got no idea where to look at this point.

My gem environment contains:

 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

If there's additional information you feel you need to solve this problem, I'll gladly provide it.

UPDATE:

I have now also tried to use Culerity as my Javascript integration test tool, and (unsurprisingly, as it's no longer maintained nor are parts of its infrastructure) I reach a point where there's a bug in Celerity that results in a NoMethodError-- 'url' is undefined for my Cabybara:Server instance inside the capybara-celerity gem.

Derrell Durrett
  • 544
  • 10
  • 26

3 Answers3

2

Apparently, and it is quite unclear to me exactly what this had to do with it, my problem stemmed from using the precompiled assets. This is odd, since my development and test environments were functionally identical, and the development version was working like a champ.

In any case, I can now at least get the test to fire the change listener.

The SO post that helped resolve my issue was :How to avoid precompiled assets being served in development mode?

I got there because of this post on the Capybara googlegroup: https://groups.google.com/forum/#!searchin/ruby-capybara/selenium$20$20event$20%7Csort:date/ruby-capybara/u8Tnd6SqD3k/Lou4jBsJuo8J

Community
  • 1
  • 1
Derrell Durrett
  • 544
  • 10
  • 26
1

Your code looks like it should work. Just one thing you could try: Add a sleep 5 call in your test after you enter the text into the field to give the AJAX call time to complete. This should be handled by Capybara but maybe there's something wrong there.

Also can you add some console.log or so statements to make sure the problem is that the change handler is not fired, and not that it's a problem with the AJAX call.

Alex Lang
  • 1,298
  • 11
  • 14
  • Thanks for your interest in my problem, Alex. – Derrell Durrett Jul 21 '14 at 17:17
  • Sorry it's taken me so long to get back to you. I've been trying as many things as I can find, and I broke things along the way. I'm now back to where I was, and I can confirm that there's no output from the browser's side, indicating the change listener isn't fired. – Derrell Durrett Jul 28 '14 at 17:34
0

I has the same problem. I quickly figured out the entire js file was not being run. For me the precompiled assets also seemed to be the problem. I has previously precompiled assets manually, to run rails in production locally. Unlike the development env the test env actually uses these precompiled assets. The solution was simply deleting the assets as I didn't need them anymore.

I added a line to the environments/test.rb to prevent this in the future:

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