From fa143749e4feed036aba7305dcb9ff2907a45abf Mon Sep 17 00:00:00 2001 From: Mantas Masalskis Date: Fri, 15 May 2020 00:26:15 +0300 Subject: [PATCH] Specs enhancement: reusable websocket status check --- spec/support/capybara/ensure_websocket.rb | 48 +++++++++++++++++++++++ spec/system/login/message_spec.rb | 30 ++------------ 2 files changed, 51 insertions(+), 27 deletions(-) create mode 100644 spec/support/capybara/ensure_websocket.rb diff --git a/spec/support/capybara/ensure_websocket.rb b/spec/support/capybara/ensure_websocket.rb new file mode 100644 index 000000000..512b06b97 --- /dev/null +++ b/spec/support/capybara/ensure_websocket.rb @@ -0,0 +1,48 @@ +module EnsureWebsocket + # Ensures that websocket is connectged + # + # @param timeout [Integer] seconds to wait + # @param check_if_pinged [Boolean] checks if was pinged to prevent stale connections + # + # @yield block to execute between disruptive action (e.g. browser refresh) and action that requires websocket + def ensure_websocket(timeout: 2.minutes, check_if_pinged: true) + timestamp = Time.zone.now if check_if_pinged + + yield if block_given? + + wait(timeout).until do + next if check_if_pinged && !pinged_since?(timestamp) + + connection_open? + end + end + + private + + # Checks if session was active since given time + # + # @param timestamp [Time] when session was (re)activated + # @return [Boolean] + def pinged_since?(timestamp) + unix_time = timestamp.to_i + + Sessions + .list + .values + .map { |elem| elem.dig(:meta, :last_ping) } + .any? { |elem| elem >= unix_time } + end + + # Checks if websocket connection is active. Javascript function returns string identifier or empty string + # + # @return [Boolean] + def connection_open? + page + .evaluate_script('App.WebSocket.channel()') + .present? + end +end + +RSpec.configure do |config| + config.include EnsureWebsocket, type: :system +end diff --git a/spec/system/login/message_spec.rb b/spec/system/login/message_spec.rb index 780a85da7..c200fe7b5 100644 --- a/spec/system/login/message_spec.rb +++ b/spec/system/login/message_spec.rb @@ -21,9 +21,7 @@ RSpec.describe 'Login Message', type: :system, authenticated: false do Setting.set 'maintenance_login', false - wait(10).until_disappears { find '.js-maintenanceLogin', text: message, wait: false } - - expect(page).not_to have_css('.js-maintenanceLogin') + expect(page).to have_no_css('.js-maintenanceLogin', text: message, wait: 10) end it 'changes message text on the go' do @@ -31,9 +29,7 @@ RSpec.describe 'Login Message', type: :system, authenticated: false do Setting.set 'maintenance_login_message', alt_message - wait(10).until_exists { find '.js-maintenanceLogin', text: alt_message, wait: false } - - expect(page).to have_css('.js-maintenanceLogin', text: alt_message) + expect(page).to have_no_css('.js-maintenanceLogin', text: alt_message, wait: 10) end end @@ -59,28 +55,8 @@ RSpec.describe 'Login Message', type: :system, authenticated: false do end def open_login_page - timestamp = Time.zone.now.to_i - visit '/' - wait(8).until do - pinged_since?(timestamp) && connection_open? - end - - true - end - - def pinged_since?(timestamp) - Sessions - .list - .values - .map { |elem| elem.dig(:meta, :last_ping) } - .any? { |elem| elem >= timestamp } - end - - def connection_open? - page - .evaluate_script('App.WebSocket.channel()') - .present? + ensure_websocket end end