Last active
January 21, 2016 23:40
-
-
Save robhurring/bc9978844680587197a4 to your computer and use it in GitHub Desktop.
Capybara + Angular.js wait_for_ajax
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
require 'selenium-webdriver' | |
module FeatureHelpers | |
DEFAULT_WAIT_TIME = 30 | |
Capybara.register_driver :poltergeist_debug do |app| | |
Capybara::Poltergeist::Driver.new(app, | |
inspector: true, | |
js_errors: true, | |
timeout: DEFAULT_WAIT_TIME | |
) | |
end | |
Capybara.default_wait_time = DEFAULT_WAIT_TIME | |
Capybara.javascript_driver = :poltergeist_debug | |
# Public: Block until our page says there are no requests currently | |
# in progress, or we timeout. | |
# | |
# max_wait - The amount of time you're willing to wait for AJAX to complete. | |
# check_pause - The amount of time between checks | |
# notify_after_ticks - After this many ticks output a message about whats going on. | |
# | |
# Returns nothing. | |
def wait_for_ajax(max_wait = Capybara.default_wait_time, check_pause = 0.1, notify_after_ticks = 10) | |
ticks = 0 | |
new_line = false | |
Timeout.timeout(max_wait) do | |
until finished_all_ajax_requests? | |
ticks += 1 | |
if (ticks % notify_after_ticks).zero? | |
wait_time = (ticks * check_pause.to_f).round(1) | |
debug_inplace("[waiting <time: #{wait_time}s/#{max_wait}s>] #{last_ajax_request}\r#{eol}") | |
new_line = true | |
end | |
sleep check_pause | |
end | |
end | |
puts if new_line # flush line | |
end | |
private | |
def debug_inplace(message) | |
$stderr.write("%s\r" % message) | |
$stderr.flush | |
end | |
# Private: The URL of the last active AJAX request. | |
# Returns the URL if present, blank string otherwise. | |
def last_ajax_request | |
page.evaluate_script('window.__lastActiveRequest__').to_s | |
end | |
# Private: The number of AJAX requests currently in progress on the page. | |
# Returns the number of active requests. | |
def current_active_requests | |
page.evaluate_script('window.__activeRequests__') | |
end | |
# Private: Check if we have no AJAX request in progress. | |
# Returns false if there are active requests, true otherwise. | |
def finished_all_ajax_requests? | |
current_active_requests.zero? | |
end | |
end | |
RSpec.configure do |config| | |
config.include FeatureHelpers, type: :feature | |
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
(function(module) { | |
'use strict'; | |
// Track HTTP requests so we can fix capybara specs without resorting | |
// to random sleeps. | |
// See: spec/support/feature_helpers.rb for how its used | |
module.config(['$httpProvider', | |
function($httpProvider) { | |
var key = '__activeRequests__'; | |
var lastUrl = '__lastActiveRequest__'; | |
$httpProvider.interceptors.push(['$window', '$q', | |
function($window, $q) { | |
$window[key] = 0; | |
var startRequest = function(config) { | |
$window[key] += 1; | |
$window[lastUrl] = config.method + ' ' + config.url; | |
}; | |
var finishRequest = function() { | |
$window[key] -= 1; | |
if($window[key] < 0) { | |
$window[key] = 0; | |
} | |
}; | |
return { | |
request: function(config) { | |
startRequest(config); | |
return config; | |
}, | |
requestError: function(rejection) { | |
finishRequest(); | |
return $q.reject(rejection); | |
}, | |
response: function(response) { | |
finishRequest(); | |
return response; | |
}, | |
responseError: function(rejection) { | |
finishRequest(); | |
return $q.reject(rejection); | |
} | |
}; | |
} | |
]); | |
} | |
]); | |
})(angular.module('MyModule')); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment