ensure_websocket.rb 1.3 KB

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