diff options
Diffstat (limited to 'spec/support/helpers/wait_for_requests.rb')
-rw-r--r-- | spec/support/helpers/wait_for_requests.rb | 78 |
1 files changed, 78 insertions, 0 deletions
diff --git a/spec/support/helpers/wait_for_requests.rb b/spec/support/helpers/wait_for_requests.rb new file mode 100644 index 00000000000..fda0e29f983 --- /dev/null +++ b/spec/support/helpers/wait_for_requests.rb @@ -0,0 +1,78 @@ +module WaitForRequests + extend self + + # This is inspired by http://www.salsify.com/blog/engineering/tearing-capybara-ajax-tests + def block_and_wait_for_requests_complete + block_requests { wait_for_all_requests } + end + + # Block all requests inside block with 503 response + def block_requests + Gitlab::Testing::RequestBlockerMiddleware.block_requests! + yield + ensure + Gitlab::Testing::RequestBlockerMiddleware.allow_requests! + end + + # Slow down requests inside block by injecting `sleep 0.2` before each response + def slow_requests + Gitlab::Testing::RequestBlockerMiddleware.slow_requests! + yield + ensure + Gitlab::Testing::RequestBlockerMiddleware.allow_requests! + end + + # Wait for client-side AJAX requests + def wait_for_requests + wait_for('JS requests complete') { finished_all_js_requests? } + end + + # Wait for active Rack requests and client-side AJAX requests + def wait_for_all_requests + wait_for('pending requests complete') do + finished_all_rack_reqiests? && + finished_all_js_requests? + end + end + + private + + def finished_all_rack_reqiests? + Gitlab::Testing::RequestBlockerMiddleware.num_active_requests.zero? + end + + def finished_all_js_requests? + return true unless javascript_test? + + finished_all_ajax_requests? && + finished_all_vue_resource_requests? + end + + # Waits until the passed block returns true + def wait_for(condition_name, max_wait_time: Capybara.default_max_wait_time, polling_interval: 0.01) + wait_until = Time.now + max_wait_time.seconds + loop do + break if yield + + if Time.now > wait_until + raise "Condition not met: #{condition_name}" + else + sleep(polling_interval) + end + end + end + + def finished_all_vue_resource_requests? + Capybara.page.evaluate_script('window.activeVueResources || 0').zero? + end + + def finished_all_ajax_requests? + return true if Capybara.page.evaluate_script('typeof jQuery === "undefined"') + + Capybara.page.evaluate_script('jQuery.active').zero? + end + + def javascript_test? + Capybara.current_driver == Capybara.javascript_driver + end +end |