Question

I've a problem with my jasmine suite and my usage of jQuery's new event registration method .on().

Here's a simplified version of my fixuture:

<div id='rent_payment_schedule_container'>
  <select class="select optional" id="frequency_select" name="payment_schedule[frequency]">
    <option value="0">Monthly</option>
    <option value="1">Weekly</option>
    <option value="2">Bi-Weekly</option>
  </select>

  <div class="control-group select optional start-day-select" id="monthly_select"></div>

  <div class="control-group select optional start-day-select" id="weekly_select" style="display: none;"></div>
</div>

Here's the coffeescript (which works just fine on the actual page that its being used on):

$ ->
  $('#rent_payment_schedule_container').on 'change', '#frequency_select', (event) ->
    $('.start-day-select').hide()

    switch $(event.target).val()
      when '0'
        $('#monthly_select').show()
      when '1'
        $('#weekly_select').show()
      when '2'
        $('#weekly_select').show()

And here is the spec:

describe 'The UI components on the payment schedule creation page', ->
  beforeEach ->
    loadFixtures 'payment_schedule'

  describe 'The toggling of the monthly and weekly day select options', ->

    it 'shows the weekly select div and hides the monthly select div when the weekly option is selected from the #frequency_select select box', ->
      $('#frequency_select option[value=1]').attr('selected', 'selected')
      $('#frequency_select').change()
      expect($("#weekly_select")).toBeVisible()

    it 'shows the weekly select div and hides the monthly select div when the bi-weekly option is selected from the #frequency_select select box', ->
      $('#frequency_select option[value=2]').attr('selected', 'selected')
      $('#frequency_select').change()
      expect($("#weekly_select")).toBeVisible()

    it 'shows the monthly select div and hides the weekly select div when the monthly option is selected from the #frequency_select select box', ->
      $('#frequency_select option[value=1]').attr('selected', 'selected')
      $('#frequency_select').change()
      $('#frequency_select option[value=0]').attr('selected', 'selected')
      $('#frequency_select').change()
      expect($("#monthly_select")).toBeVisible()

And this fails miserably, each and every time.

However, if instead of using $('#rent_payment_schedule_container') as the receiver for .on(), I use $(document), the whole thing works just great.

$ ->
  $(document).on 'change', '#frequency_select', (event) ->
    $('.start-day-select').hide()

    switch $(event.target).val()
      when '0'
        $('#monthly_select').show()
      when '1'
        $('#weekly_select').show()
      when '2'
        $('#weekly_select').show()

So, my best guess is that this has something to do with the order or the speed of the way that jasmine loads the fixture and then runs the tests, but I can't be sure. Can anybody point me in the right direction as to why this happens and how I can fix it?

Was it helpful?

Solution

My guess is that you load your script together with the spec runner. Your script executes on when your DOM is ready. The fixture is yet loaded at that point though. As a result, $('#rent_payment_schedule_container') will select no elements, which you can probably verify yourself.

In any case you should be able to go around that by wrapping your script in a function that you can call in your tests.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top