Brian NortonMay 22
Ember meet Capybara
It was a cordial hello. Capybara agreed to work nicely and Ember basically ignoring small talk and getting right down to business.
Shortly thereafter, when the real testing began, Capybara decided that it had enough and walked away. I was left standing there awkwardly with Ember trying to think of something to say. I managed “just get give us a moment” to which Ember did nothing. I can only assume it deferred processing until the next run loop tick.
I joined Capybara at the bar.
I was only one beer in when I solved the real problem. I didn’t need Capybara and Ember to be friends; I needed to have Capybara check the DOM / page after Ember did everything it needed to…
<!-- application.html.erb -->
<%= javascript_include_tag 'test' if Rails.env.test? %>
<!-- ... -->
// test.js
test = {
ajaxRequests: {}};
$(document).on('ajaxSend', function(e, xhr, options) {test.ajaxRequests[options.url] = true;
}).on('ajaxComplete', function(e, xhr, options) {delete test.ajaxRequests[options.url];
});
# helpers/spec_helper.rb
RSpec.configure do |config|
config.include RequestHelper, :type => :feature
end
# ...
# helpers/request_helper.rb
module RequestHelper
def self.included(base)
base.send(:include, InstanceMethods)
end
module InstanceMethods
##
# Wait up to 3 seconds for asynchronous action processing to complete
def wait_for_async
start_time = Time.now
loop do
break if page.evaluate_script('Object.keys(test.ajaxRequests).length == 0 && !Ember.run.hasScheduledTimers() && !Ember.run.currentRunLoop') raise "Waited too long for ajax requests to finish #{page.evaluate_script('JSON.stringify(test.ajaxRequests)')} - #{page.evaluate_script('!Ember.run.hasScheduledTimers()')} - #{page.evaluate_script('!Ember.run.currentRunLoop')}" if (Time.now - start_time) > 3sleep 0.1
end
end
end
end