ensure_websocket.rb 1.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748
  1. module EnsureWebsocket
  2. # Ensures that websocket is connected
  3. #
  4. # @param timeout [Integer] seconds to wait
  5. # @param check_if_pinged [Boolean] checks if was pinged to prevent stale connections
  6. #
  7. # @yield block to execute between disruptive action (e.g. browser refresh) and action that requires websocket
  8. def ensure_websocket(timeout: 2.minutes, check_if_pinged: true)
  9. timestamp = Time.zone.now if check_if_pinged
  10. yield if block_given?
  11. wait(timeout).until do
  12. next if check_if_pinged && !pinged_since?(timestamp)
  13. connection_open?
  14. end
  15. end
  16. private
  17. # Checks if session was active since given time
  18. #
  19. # @param timestamp [Time] when session was (re)activated
  20. # @return [Boolean]
  21. def pinged_since?(timestamp)
  22. unix_time = timestamp.to_i
  23. Sessions
  24. .list
  25. .values
  26. .map { |elem| elem.dig(:meta, :last_ping) }
  27. .any? { |elem| elem >= unix_time }
  28. end
  29. # Checks if websocket connection is active. Javascript function returns string identifier or empty string
  30. #
  31. # @return [Boolean]
  32. def connection_open?
  33. page
  34. .evaluate_script('App.WebSocket.channel()')
  35. .present?
  36. end
  37. end
  38. RSpec.configure do |config|
  39. config.include EnsureWebsocket, type: :system
  40. end