chat_spec.rb 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445
  1. # Copyright (C) 2012-2022 Zammad Foundation, https://zammad-foundation.org/
  2. require 'rails_helper'
  3. RSpec.describe 'Chat Handling', type: :system do
  4. let(:agent_chat_switch_selector) { '#navigation .js-chatMenuItem .js-switch' }
  5. let(:chat_url) { "/assets/chat/#{chat_url_type}.html?port=#{ENV['WS_PORT']}" }
  6. let(:chat_url_type) { 'znuny' }
  7. def authenticate
  8. Setting.set('chat', true)
  9. true
  10. end
  11. def check_content(selector, value, should_match: true, wait: nil)
  12. if should_match
  13. expect(page).to have_css(selector, wait: wait, text: value)
  14. else
  15. expect(page).to have_no_css(selector, wait: wait, text: value)
  16. end
  17. end
  18. def enable_agent_chat
  19. click agent_chat_switch_selector
  20. click 'a[href="#customer_chat"]'
  21. end
  22. def open_chat_dialog
  23. expect(page).to have_css('.zammad-chat')
  24. click '.zammad-chat .js-chat-open'
  25. expect(page).to have_css('.zammad-chat-is-shown')
  26. end
  27. def send_customer_message(message)
  28. find('.zammad-chat .zammad-chat-input').send_keys(message)
  29. click '.zammad-chat .zammad-chat-send'
  30. end
  31. def send_agent_message(message)
  32. find('.active .chat-window .js-customerChatInput').send_keys(message)
  33. click '.active .chat-window .js-send'
  34. end
  35. shared_examples 'chat button is hidden after idle timeout' do
  36. it 'check that button is hidden after idle timeout', authenticated_as: :authenticate do
  37. click agent_chat_switch_selector
  38. open_window_and_switch
  39. visit chat_url
  40. expect(page).to have_css('.zammad-chat', visible: :all)
  41. expect(page).to have_css('.zammad-chat-is-hidden', visible: :all)
  42. expect(page).to have_no_css('.open-zammad-chat:not([style*="display: none"]', visible: :all)
  43. end
  44. end
  45. shared_examples 'chat messages' do
  46. it 'messages in each direction, starting on agent side', authenticated_as: :authenticate do
  47. enable_agent_chat
  48. open_window_and_switch
  49. visit chat_url
  50. open_chat_dialog
  51. switch_to_window_index(1)
  52. click '.active .js-acceptChat'
  53. expect(page).to have_no_css('.active .chat-window .chat-status.is-modified')
  54. check_content('.active .chat-window .js-body', chat_url)
  55. send_agent_message('my name is me')
  56. switch_to_window_index(2)
  57. check_content('.zammad-chat .zammad-chat-agent-status', 'Online')
  58. check_content('.zammad-chat', 'my name is me')
  59. send_customer_message('my name is customer')
  60. switch_to_window_index(1)
  61. check_content('.active .chat-window', 'my name is customer')
  62. expect(page).to have_css('.active .chat-window .chat-status.is-modified')
  63. click '.active .chat-window .js-customerChatInput'
  64. expect(page).to have_no_css('.active .chat-window .chat-status.is-modified')
  65. switch_to_window_index(2)
  66. click '.js-chat-toggle .zammad-chat-header-icon'
  67. switch_to_window_index(1)
  68. check_content('.active .chat-window', 'closed the conversation')
  69. end
  70. it 'messages in each direction, starting on customer side', authenticated_as: :authenticate do
  71. enable_agent_chat
  72. open_window_and_switch
  73. visit chat_url
  74. open_chat_dialog
  75. switch_to_window_index(1)
  76. click '.active .js-acceptChat'
  77. expect(page).to have_no_css('.active .chat-window .chat-status.is-modified')
  78. # Keep focus outside of chat window to check .chat-status.is-modified later.
  79. click '#global-search'
  80. switch_to_window_index(2)
  81. check_content('.zammad-chat .zammad-chat-agent-status', 'Online')
  82. send_customer_message('my name is customer')
  83. switch_to_window_index(1)
  84. expect(page).to have_css('.active .chat-window .chat-status.is-modified')
  85. check_content('.active .chat-window', 'my name is customer')
  86. send_agent_message('my name is me')
  87. expect(page).to have_no_css('.active .chat-window .chat-status.is-modified')
  88. switch_to_window_index(2)
  89. check_content('.zammad-chat', 'my name is me')
  90. switch_to_window_index(1)
  91. click '.active .chat-window .js-disconnect:not(.is-hidden)'
  92. click '.active .chat-window .js-close'
  93. switch_to_window_index(2)
  94. check_content('.zammad-chat .zammad-chat-agent-status', 'Offline')
  95. check_content('.zammad-chat', %r{(Chat closed by|Chat beendet von)})
  96. click '.zammad-chat .js-chat-toggle .zammad-chat-header-icon'
  97. expect(page).to have_no_css('.zammad-chat-is-open')
  98. open_chat_dialog
  99. switch_to_window_index(1)
  100. click '.active .js-acceptChat'
  101. expect(page).to have_css('.active .chat-window .chat-status')
  102. end
  103. end
  104. shared_examples 'open chat with button' do
  105. it 'open the chat', authenticated_as: :authenticate do
  106. enable_agent_chat
  107. open_window_and_switch
  108. visit chat_url
  109. expect(page).to have_css('.zammad-chat', visible: :all)
  110. expect(page).to have_css('.zammad-chat-is-hidden', visible: :all)
  111. expect(page).to have_no_css('.zammad-chat-is-shown', visible: :all)
  112. expect(page).to have_no_css('.zammad-chat-is-open', visible: :all)
  113. click '.open-zammad-chat'
  114. expect(page).to have_css('.zammad-chat-is-shown', visible: :all)
  115. expect(page).to have_css('.zammad-chat-is-open', visible: :all)
  116. check_content('.zammad-chat-modal-text', %r{(waiting|Warte)})
  117. click '.zammad-chat-header-icon-close'
  118. expect(page).to have_no_css('.zammad-chat-is-shown', visible: :all)
  119. expect(page).to have_no_css('.zammad-chat-is-open', visible: :all)
  120. end
  121. end
  122. shared_examples 'timeouts' do
  123. it 'check different timeouts', authenticated_as: :authenticate do
  124. enable_agent_chat
  125. open_window_and_switch
  126. visit chat_url
  127. # No customer action, hide the widget.
  128. expect(page).to have_css('.zammad-chat')
  129. expect(page).to have_no_css('.zammad-chat')
  130. refresh
  131. # No agent action, show sorry screen.
  132. open_chat_dialog
  133. check_content('.zammad-chat-modal-text', %r{(waiting|Warte)})
  134. check_content('.zammad-chat-modal-text', %r{(takes longer|dauert länger)})
  135. refresh
  136. # No customer action, show sorry screen.
  137. open_chat_dialog
  138. switch_to_window_index(1)
  139. click '.active .js-acceptChat'
  140. send_agent_message('agent is asking')
  141. switch_to_window_index(2)
  142. check_content('.zammad-chat', 'agent is asking')
  143. check_content('.zammad-chat-modal-text', %r{(Since you didn't respond|Da Sie in den letzten)}, wait: 30)
  144. # Test the restart of inactive chat.
  145. switch_to_window_index(1)
  146. click '.active .chat-window .js-close'
  147. switch_to_window_index(2)
  148. click '.js-restart'
  149. open_chat_dialog
  150. switch_to_window_index(1)
  151. click '.active .js-acceptChat'
  152. send_agent_message('my name is me')
  153. switch_to_window_index(2)
  154. check_content('.zammad-chat', 'my name is me')
  155. end
  156. end
  157. context 'when chat is activated or disabled' do
  158. it 'switch the chat setting', authenticated_as: :authenticate do
  159. visit '/#channels/chat'
  160. click '.content.active .js-chatSetting'
  161. expect(page).to have_no_css(agent_chat_switch_selector)
  162. open_window_and_switch
  163. visit chat_url
  164. check_content('.settings', '{"state":"chat_disabled"}')
  165. switch_to_window_index(1)
  166. click '.content.active .js-chatSetting'
  167. expect(page).to have_css(agent_chat_switch_selector)
  168. switch_to_window_index(2)
  169. refresh
  170. expect(page).to have_no_css('.zammad-chat')
  171. check_content('.settings', '{"state":"chat_disabled"}', should_match: false)
  172. check_content('.settings', '{"event":"chat_status_customer","data":{"state":"offline"}}')
  173. switch_to_window_index(1)
  174. click agent_chat_switch_selector
  175. click 'a[href="#customer_chat"]'
  176. switch_to_window_index(2)
  177. refresh
  178. expect(page).to have_css('.zammad-chat')
  179. check_content('.settings', '{"event":"chat_status_customer","data":{"state":"offline"}}', should_match: false)
  180. check_content('.settings', '{"state":"online"}')
  181. click '.zammad-chat .js-chat-open'
  182. expect(page).to have_css('.zammad-chat-is-shown')
  183. check_content('.zammad-chat-modal-text', %r{(waiting|Warte)})
  184. switch_to_window_index(1)
  185. check_content('.js-chatMenuItem .counter', '1')
  186. switch_to_window_index(2)
  187. click '.zammad-chat .js-chat-toggle .zammad-chat-header-icon'
  188. check_content('.zammad-chat-modal-text', %r{(waiting|Warte)}, should_match: false)
  189. switch_to_window_index(1)
  190. expect(page).to have_no_css('.js-chatMenuItem .counter')
  191. end
  192. end
  193. context 'when changing chat preferences for current agent' do
  194. it 'use chat phrase preference', authenticated_as: :authenticate do
  195. enable_agent_chat
  196. click '.active .js-settings'
  197. modal_ready
  198. find('.modal [name="chat::phrase::1"]').send_keys('Hi Stranger!;My Greeting')
  199. click '.modal .js-submit'
  200. modal_disappear
  201. open_window_and_switch
  202. visit chat_url
  203. open_chat_dialog
  204. switch_to_window_index(1)
  205. click '.active .js-acceptChat'
  206. expect(page).to have_css('.active .chat-window .chat-status')
  207. switch_to_window_index(2)
  208. check_content('.zammad-chat', %r{(Hi Stranger|My Greeting)})
  209. switch_to_window_index(1)
  210. send_agent_message('my name is me')
  211. switch_to_window_index(2)
  212. check_content('.zammad-chat', 'my name is me')
  213. refresh
  214. expect(page).to have_css('.zammad-chat')
  215. check_content('.zammad-chat', %r{(Hi Stranger|My Greeting)})
  216. check_content('.zammad-chat', 'my name is me')
  217. visit "#{chat_url}#new_hash"
  218. switch_to_window_index(1)
  219. check_content('.active .chat-window .js-body', "#{chat_url}#new_hash")
  220. end
  221. end
  222. context 'when jquery variant is used' do
  223. context 'when normal mode is used' do
  224. include_examples 'chat messages'
  225. include_examples 'timeouts'
  226. end
  227. context 'when button mode is active' do
  228. let(:chat_url_type) { 'znuny_open_by_button' }
  229. include_examples 'open chat with button'
  230. include_examples 'chat button is hidden after idle timeout'
  231. end
  232. end
  233. context 'when none jquery variant is used' do
  234. let(:chat_url_type) { 'znuny-no-jquery' }
  235. context 'when normal mode is used' do
  236. include_examples 'chat messages'
  237. include_examples 'timeouts'
  238. end
  239. context 'when button mode is active' do
  240. let(:chat_url_type) { 'znuny-no-jquery-open_by_button' }
  241. include_examples 'open chat with button'
  242. include_examples 'chat button is hidden after idle timeout'
  243. end
  244. end
  245. describe "Chat can't be closed after timeout #2471", authenticated_as: :authenticate do
  246. shared_examples 'test issue #2471' do
  247. it 'is able to close to the dialog after a idleTimeout happened' do
  248. click agent_chat_switch_selector
  249. open_window_and_switch
  250. visit chat_url
  251. click '.zammad-chat .js-chat-open'
  252. expect(page).to have_selector('.js-restart', wait: 60)
  253. click '.js-chat-toggle .zammad-chat-header-icon'
  254. expect(page).to have_no_selector('zammad-chat-is-open', wait: 60)
  255. end
  256. end
  257. context 'with jquery' do
  258. include_examples 'test issue #2471'
  259. end
  260. context 'wihtout jquery' do
  261. let(:chat_url_type) { 'znuny-no-jquery' }
  262. include_examples 'test issue #2471'
  263. end
  264. end
  265. context 'when image is present in chat message', authenticated_as: :authenticate do
  266. let(:chat) { create(:chat) }
  267. let(:chat_user) { create(:agent) }
  268. let(:chat_session) { create(:'chat/session', user: chat_user, chat: chat) }
  269. before do
  270. file = File.binread(Rails.root.join('spec/fixtures/image/squares.png'))
  271. base64 = Base64.encode64(file).delete("\n")
  272. create(
  273. :'chat/message',
  274. chat_session: chat_session,
  275. content: "With inline image: <img src='data:image/png;base64,#{base64}' style='width: 100%; max-width: 460px;'>"
  276. )
  277. end
  278. context 'when image preview is used' do
  279. it 'use image preview' do
  280. visit "#customer_chat/session/#{chat_session.id}"
  281. click '.chat-body .chat-message img'
  282. modal_ready
  283. expect(page).to have_css('.js-submit', text: 'Download')
  284. end
  285. end
  286. end
  287. end