From 79ea9fbad7ae5a112038075c0b9b077b179060db Mon Sep 17 00:00:00 2001 From: Iain Beeston Date: Thu, 10 Oct 2024 12:37:05 +0100 Subject: [PATCH] Made TestHelpers include methods from WaitForLoaded Right now many of the test helpers don't work in any other project because they rely on methods from WaitForLoaded and the test helpers crash when they are called. This isn't an issue in the avo project itself because the WaitForLoaded methods are required automatically by the avo test suite. It isn't possible to load WaitForLoaded in projects using the rubygem of avo because files inside the spec directory aren't included (and even if they were it would be a bit weird to load something from `spec/support` in a gem). To fix this I've moved WaitForLoaded alongside the TestHelpers module and included it from there so the helper methods can be used in other projects. --- lib/avo/test_helpers.rb | 2 + lib/avo/wait_for_loaded.rb | 108 ++++++++++++++++++++++++++++++++ spec/rails_helper.rb | 1 - spec/support/wait_for_loaded.rb | 104 ------------------------------ 4 files changed, 110 insertions(+), 105 deletions(-) create mode 100644 lib/avo/wait_for_loaded.rb delete mode 100644 spec/support/wait_for_loaded.rb diff --git a/lib/avo/test_helpers.rb b/lib/avo/test_helpers.rb index acf310f575..9fba97c50b 100644 --- a/lib/avo/test_helpers.rb +++ b/lib/avo/test_helpers.rb @@ -1,5 +1,7 @@ module Avo module TestHelpers + include WaitForLoaded + # Finds the wrapper element on the index view for the given field id and type, and associated with the given record id # Example usage: # index_field_wrapper(id: "name", type: "text", record_id: 2) diff --git a/lib/avo/wait_for_loaded.rb b/lib/avo/wait_for_loaded.rb new file mode 100644 index 0000000000..c37d020cb9 --- /dev/null +++ b/lib/avo/wait_for_loaded.rb @@ -0,0 +1,108 @@ +require "timeout" + +module Avo + module WaitForLoaded + def wait_for_route_loading(time = Capybara.default_max_wait_time) + Timeout.timeout(time) { sleep(0.01) until page.find("body")[:class].include?("route-loading") } + end + + def wait_for_route_loaded(time = Capybara.default_max_wait_time) + Timeout.timeout(time) { sleep(0.01) while page.find("body")[:class].include?("route-loading") } + end + + def wait_for_turbo_loaded(time = Capybara.default_max_wait_time) + wait_for_body_class_missing("turbo-loading", time) + end + + def wait_for_search_loaded(time = Capybara.default_max_wait_time) + wait_for_body_class_missing("search-loading", time) + end + + def wait_for_search_to_dissapear(time = Capybara.default_max_wait_time) + wait_for_element_missing(".aa-DetachedOverlay", time) + end + + def wait_for_turbo_frame_id(frame_id = "", time = Capybara.default_max_wait_time) + wait_for_element_missing("turbo-frame[id='#{frame_id}'][busy]", time) + end + + def wait_for_turbo_frame_src(frame_src = "", time = Capybara.default_max_wait_time) + wait_for_element_missing("turbo-frame[src='#{frame_src}'][busy]", time) + end + + def wait_for_body_class_missing(klass = "turbo-loading", time = Capybara.default_max_wait_time) + Timeout.timeout(time) do + body = page.find(:xpath, "//body") + break if !body[:class].to_s.include?(klass) + + if page.present? && body.present? && body[:class].present? && body[:class].is_a?(String) + sleep(0.1) until page.present? && !body[:class].to_s.include?(klass) + else + sleep 0.1 + end + end + rescue Timeout::Error + puts "\n\nMethod '#{__method__}' raised 'Timeout::Error' after #{time}s" + end + + def wait_for_element_missing(identifier = ".element", time = Capybara.default_max_wait_time) + Timeout.timeout(time) do + if page.present? + break if page.has_no_css?(identifier, wait: time) + else + sleep 0.05 + end + end + end + + def wait_for_element_present(identifier = ".element", time = Capybara.default_max_wait_time) + Timeout.timeout(time) do + if page.present? + break if page.has_css?(identifier, wait: time) + else + sleep 0.05 + end + end + end + + def wait_for_loaded + wait_for_turbo_loaded + end + + def wait_for_action_dialog_to_disappear(time = Capybara.default_max_wait_time) + wait_for_element_missing("[role='dialog']", time) + end + + def wait_for_tag_to_disappear(tag, time = Capybara.default_max_wait_time) + Capybara.using_wait_time(time) do + page.has_no_css?(".tagify__tag", text: tag) + end + end + + def wait_for_tag_to_appear(tag, time = Capybara.default_max_wait_time) + Capybara.using_wait_time(time) do + page.has_css?(".tagify__tag", text: tag) + end + end + + def wait_for_tag_suggestions_to_appear(time = Capybara.default_max_wait_time) + Capybara.using_wait_time(time) do + page.has_css?(".tagify__dropdown") + end + + current_count = prev_count = page.all('.tagify__dropdown__item').count + attempts = 5 + + loop do + sleep(0.05) + current_count = page.all('.tagify__dropdown__item').count + + # Break when suggestions stop appearing + # Or attempts reach 0 + attempts -= 1 + break if (current_count == prev_count) || (attempts == 0) + prev_count = current_count + end + end + end +end diff --git a/spec/rails_helper.rb b/spec/rails_helper.rb index ac22e484f5..c7985c6ed8 100644 --- a/spec/rails_helper.rb +++ b/spec/rails_helper.rb @@ -205,7 +205,6 @@ def headless_download_setup(driver) require "support/helpers" require "support/factory_bot" require "support/database_cleaner" -require "support/wait_for_loaded" require "support/js_error_detector" require "support/devise" require "support/shared_contexts" diff --git a/spec/support/wait_for_loaded.rb b/spec/support/wait_for_loaded.rb deleted file mode 100644 index 562a1e0269..0000000000 --- a/spec/support/wait_for_loaded.rb +++ /dev/null @@ -1,104 +0,0 @@ -require "timeout" - -def wait_for_route_loading(time = Capybara.default_max_wait_time) - Timeout.timeout(time) { sleep(0.01) until page.find("body")[:class].include?("route-loading") } -end - -def wait_for_route_loaded(time = Capybara.default_max_wait_time) - Timeout.timeout(time) { sleep(0.01) while page.find("body")[:class].include?("route-loading") } -end - -def wait_for_turbo_loaded(time = Capybara.default_max_wait_time) - wait_for_body_class_missing("turbo-loading", time) -end - -def wait_for_search_loaded(time = Capybara.default_max_wait_time) - wait_for_body_class_missing("search-loading", time) -end - -def wait_for_search_to_dissapear(time = Capybara.default_max_wait_time) - wait_for_element_missing(".aa-DetachedOverlay", time) -end - -def wait_for_turbo_frame_id(frame_id = "", time = Capybara.default_max_wait_time) - wait_for_element_missing("turbo-frame[id='#{frame_id}'][busy]", time) -end - -def wait_for_turbo_frame_src(frame_src = "", time = Capybara.default_max_wait_time) - wait_for_element_missing("turbo-frame[src='#{frame_src}'][busy]", time) -end - -def wait_for_body_class_missing(klass = "turbo-loading", time = Capybara.default_max_wait_time) - Timeout.timeout(time) do - body = page.find(:xpath, "//body") - break if !body[:class].to_s.include?(klass) - - if page.present? && body.present? && body[:class].present? && body[:class].is_a?(String) - sleep(0.1) until page.present? && !body[:class].to_s.include?(klass) - else - sleep 0.1 - end - end -rescue Timeout::Error - puts "\n\nMethod '#{__method__}' raised 'Timeout::Error' after #{time}s" -end - -def wait_for_element_missing(identifier = ".element", time = Capybara.default_max_wait_time) - Timeout.timeout(time) do - if page.present? - break if page.has_no_css?(identifier, wait: time) - else - sleep 0.05 - end - end -end - -def wait_for_element_present(identifier = ".element", time = Capybara.default_max_wait_time) - Timeout.timeout(time) do - if page.present? - break if page.has_css?(identifier, wait: time) - else - sleep 0.05 - end - end -end - -def wait_for_loaded - wait_for_turbo_loaded -end - -def wait_for_action_dialog_to_disappear(time = Capybara.default_max_wait_time) - wait_for_element_missing("[role='dialog']", time) -end - -def wait_for_tag_to_disappear(tag, time = Capybara.default_max_wait_time) - Capybara.using_wait_time(time) do - page.has_no_css?(".tagify__tag", text: tag) - end -end - -def wait_for_tag_to_appear(tag, time = Capybara.default_max_wait_time) - Capybara.using_wait_time(time) do - page.has_css?(".tagify__tag", text: tag) - end -end - -def wait_for_tag_suggestions_to_appear(time = Capybara.default_max_wait_time) - Capybara.using_wait_time(time) do - page.has_css?(".tagify__dropdown") - end - - current_count = prev_count = page.all('.tagify__dropdown__item').count - attempts = 5 - - loop do - sleep(0.05) - current_count = page.all('.tagify__dropdown__item').count - - # Break when suggestions stop appearing - # Or attempts reach 0 - attempts -= 1 - break if (current_count == prev_count) || (attempts == 0) - prev_count = current_count - end -end