Question

We are writing an Ember.js app, and on one page have an Ember.Select whose selections are models from the Rails database. The value on the select is bound to an observer on the controller that changes the view based on the selection. This works properly when using the browser; however, when running integration tests in Capybara (using both webkit and selenium drivers), the observer on the controller registers a change action on this select when no selection had been made. This triggers the transition and causes the test to fail.

Code for a simplified version is below:

The Ember.Select

<div class="select-dropdown">
  {{view Prm.PropertySelect
  contentBinding='properties'
  optionLabelPath='content.name'
  optionValuePath='content.id'
  selectionBinding='selectedProperty'
  id='property-selector'
  classNames='property-selector'}}
</div>

The Ember.Controller action

Prm.PropertyController = Ember.ObjectController.extend
  selectedLead: null
  selectedProperty: null

  selectedPropertyChanged: (->
    @transitionToRoute('property.index', @get('selectedProperty'))
  ).observes('selectedProperty')

The Capybara Spec

require 'spec_helper'

feature 'ember allows direct access to a lead via url', js: true do
  scenario 'linking directly to lead' do
    user = create_signed_in_user
    lead = create_lead_for_user(user)

    visit ember_lead_path(lead) # defined in a helper. Returns url as string.
    assert_at_lead_detail(lead)
  end

  def assert_at_lead_detail(lead)
    expect(page).to have_link 'All leads'
    expect(page).to have_text lead.booking_request.name.upcase
  end
end

If I remove the observer, the test passes. If I do not remove the observer, the test goes to the appropriate url, and then redirects to root, and the test fails.

I need a way to rewrite the test or the select so that we can write integration tests that address what's on the page after navigating directly to a url in Ember.

Was it helpful?

Solution

I spent some time in IRC this morning, and was turned on to the right path when it was suggested that I tell the controller not to redirect if the selection from the Ember.Select was null. This solved the redirect problem, but broke the selector - the first attempt to select a value resulted in no change; after that it worked properly.

I moved the select into a custom view extending Ember.Select and put the change action there. Then I populated the initial value of the property on the controller using the router, and everything seems to work.

So - lesson:

1) Put change events on custom views; don't have the controller observe directly.

2) When a controller is watching a change of a property, make sure that there is an initial value. This may be uniquely true for values which are supplied by the database.

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