chat_spec.rb 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439
  1. # Copyright (C) 2012-2024 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. input = find('.active .chat-window .js-customerChatInput')
  33. input.send_keys(message)
  34. # Work around an obsure bug of send_keys sometimes not working on Firefox headless.
  35. if input.text != message
  36. input.execute_script("this.textContent = '#{message}'")
  37. end
  38. click '.active .chat-window .js-send'
  39. end
  40. shared_examples 'chat button is hidden after idle timeout' do
  41. it 'check that button is hidden after idle timeout', authenticated_as: :authenticate do
  42. click agent_chat_switch_selector
  43. using_session :customer do
  44. visit chat_url
  45. expect(page).to have_css('.zammad-chat', visible: :all)
  46. expect(page).to have_css('.zammad-chat-is-hidden', visible: :all)
  47. expect(page).to have_no_css('.open-zammad-chat:not([style*="display: none"]', visible: :all)
  48. end
  49. end
  50. end
  51. shared_examples 'chat messages' do
  52. it 'messages in each direction, starting on agent side', authenticated_as: :authenticate do
  53. enable_agent_chat
  54. using_session :customer do
  55. visit chat_url
  56. open_chat_dialog
  57. end
  58. click '.active .js-acceptChat'
  59. expect(page).to have_no_css('.active .chat-window .chat-status.is-modified')
  60. check_content('.active .chat-window .js-body', chat_url)
  61. send_agent_message('my name is me')
  62. using_session :customer do
  63. check_content('.zammad-chat .zammad-chat-agent-status', 'Online')
  64. check_content('.zammad-chat', 'my name is me')
  65. send_customer_message('my name is customer')
  66. end
  67. check_content('.active .chat-window', 'my name is customer')
  68. expect(page).to have_css('.active .chat-window .chat-status.is-modified')
  69. click '.active .chat-window .js-customerChatInput'
  70. expect(page).to have_no_css('.active .chat-window .chat-status.is-modified')
  71. using_session :customer do
  72. click '.js-chat-toggle .zammad-chat-header-icon'
  73. end
  74. check_content('.active .chat-window', 'closed the conversation')
  75. end
  76. it 'messages in each direction, starting on customer side', authenticated_as: :authenticate do
  77. enable_agent_chat
  78. using_session :customer do
  79. visit chat_url
  80. open_chat_dialog
  81. end
  82. click '.active .js-acceptChat'
  83. expect(page).to have_no_css('.active .chat-window .chat-status.is-modified')
  84. # Keep focus outside of chat window to check .chat-status.is-modified later.
  85. click_on 'Dashboard'
  86. using_session :customer do
  87. check_content('.zammad-chat .zammad-chat-agent-status', 'Online')
  88. send_customer_message('my name is customer')
  89. end
  90. click 'a[href="#customer_chat"]'
  91. expect(page).to have_css('.active .chat-window .chat-status.is-modified')
  92. check_content('.active .chat-window', 'my name is customer')
  93. send_agent_message('my name is me')
  94. expect(page).to have_no_css('.active .chat-window .chat-status.is-modified')
  95. using_session :customer do
  96. check_content('.zammad-chat', 'my name is me')
  97. end
  98. click '.active .chat-window .js-disconnect:not(.is-hidden)'
  99. click '.active .chat-window .js-close'
  100. using_session :customer do
  101. check_content('.zammad-chat .zammad-chat-agent-status', 'Offline')
  102. check_content('.zammad-chat', %r{(Chat closed by|Chat.*geschlossen)})
  103. click '.zammad-chat .js-chat-toggle .zammad-chat-header-icon'
  104. expect(page).to have_no_css('.zammad-chat-is-open')
  105. open_chat_dialog
  106. end
  107. click '.active .js-acceptChat'
  108. expect(page).to have_css('.active .chat-window .chat-status')
  109. end
  110. end
  111. shared_examples 'open chat with button' do
  112. it 'open the chat', authenticated_as: :authenticate do
  113. enable_agent_chat
  114. using_session :customer do
  115. visit chat_url
  116. expect(page).to have_css('.zammad-chat', visible: :all)
  117. expect(page).to have_css('.zammad-chat-is-hidden', visible: :all)
  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. click '.open-zammad-chat'
  121. expect(page).to have_css('.zammad-chat-is-shown', visible: :all)
  122. expect(page).to have_css('.zammad-chat-is-open', visible: :all)
  123. check_content('.zammad-chat-modal-text', %r{(waiting|Warte)})
  124. click '.zammad-chat-header-icon-close'
  125. expect(page).to have_no_css('.zammad-chat-is-shown', visible: :all)
  126. expect(page).to have_no_css('.zammad-chat-is-open', visible: :all)
  127. end
  128. end
  129. end
  130. shared_examples 'timeouts' do
  131. it 'check different timeouts', authenticated_as: :authenticate do
  132. enable_agent_chat
  133. using_session :customer do
  134. visit chat_url
  135. # No customer action, hide the widget.
  136. expect(page).to have_css('.zammad-chat')
  137. expect(page).to have_no_css('.zammad-chat')
  138. refresh
  139. # No agent action, show sorry screen.
  140. open_chat_dialog
  141. check_content('.zammad-chat-modal-text', %r{(waiting|Warte)})
  142. check_content('.zammad-chat-modal-text', %r{(taking longer|dauert länger)})
  143. refresh
  144. # No customer action, show sorry screen.
  145. open_chat_dialog
  146. end
  147. click '.active .js-acceptChat'
  148. send_agent_message('agent is asking')
  149. using_session :customer do
  150. check_content('.zammad-chat', 'agent is asking')
  151. check_content('.zammad-chat-modal-text', %r{(Since you didn't respond|Da Sie innerhalb der letzten)}, wait: 30)
  152. end
  153. # Test the restart of inactive chat.
  154. click '.active .chat-window .js-close'
  155. using_session :customer do
  156. click '.js-restart'
  157. open_chat_dialog
  158. end
  159. click '.active .js-acceptChat'
  160. send_agent_message('my name is me')
  161. using_session :customer do
  162. check_content('.zammad-chat', 'my name is me')
  163. end
  164. end
  165. end
  166. context 'when chat is activated or disabled' do
  167. it 'switch the chat setting', authenticated_as: :authenticate do
  168. visit '/#channels/chat'
  169. click '.content.active .js-chatSetting'
  170. expect(page).to have_no_css(agent_chat_switch_selector)
  171. using_session :customer do
  172. visit chat_url
  173. check_content('.settings', '{"state":"chat_disabled"}')
  174. end
  175. click '.content.active .js-chatSetting'
  176. expect(page).to have_css(agent_chat_switch_selector)
  177. using_session :customer do
  178. refresh
  179. expect(page).to have_no_css('.zammad-chat')
  180. check_content('.settings', '{"state":"chat_disabled"}', should_match: false)
  181. check_content('.settings', '{"event":"chat_status_customer","data":{"state":"offline"}}')
  182. end
  183. click agent_chat_switch_selector
  184. click 'a[href="#customer_chat"]'
  185. using_session :customer do
  186. refresh
  187. expect(page).to have_css('.zammad-chat')
  188. check_content('.settings', '{"event":"chat_status_customer","data":{"state":"offline"}}', should_match: false)
  189. check_content('.settings', '{"state":"online"}')
  190. click '.zammad-chat .js-chat-open'
  191. expect(page).to have_css('.zammad-chat-is-shown')
  192. check_content('.zammad-chat-modal-text', %r{(waiting|Warte)})
  193. end
  194. check_content('.js-chatMenuItem .counter', '1')
  195. using_session :customer do
  196. click '.zammad-chat .js-chat-toggle .zammad-chat-header-icon'
  197. check_content('.zammad-chat-modal-text', %r{(waiting|Warte)}, should_match: false)
  198. end
  199. expect(page).to have_no_css('.js-chatMenuItem .counter')
  200. end
  201. end
  202. context 'when changing chat preferences for current agent' do
  203. it 'use chat phrase preference', authenticated_as: :authenticate do
  204. visit '/'
  205. enable_agent_chat
  206. click '.active .js-settings'
  207. in_modal do
  208. find('[name="chat::phrase::1"]').send_keys('Hi Stranger!;My Greeting')
  209. click '.js-submit'
  210. end
  211. using_session :customer do
  212. visit chat_url
  213. open_chat_dialog
  214. end
  215. click '.active .js-acceptChat'
  216. expect(page).to have_css('.active .chat-window .chat-status')
  217. using_session :customer do
  218. check_content('.zammad-chat', %r{(Hi Stranger|My Greeting)})
  219. end
  220. send_agent_message('my name is me')
  221. using_session :customer do
  222. check_content('.zammad-chat', 'my name is me')
  223. refresh
  224. expect(page).to have_css('.zammad-chat')
  225. check_content('.zammad-chat', %r{(Hi Stranger|My Greeting)})
  226. check_content('.zammad-chat', 'my name is me')
  227. visit "#{chat_url}#new_hash"
  228. end
  229. check_content('.active .chat-window .js-body', "#{chat_url}#new_hash")
  230. end
  231. end
  232. context 'when jquery variant is used' do
  233. before do
  234. visit '/'
  235. end
  236. context 'when normal mode is used' do
  237. include_examples 'chat messages'
  238. include_examples 'timeouts'
  239. end
  240. context 'when button mode is active' do
  241. let(:chat_url_type) { 'znuny_open_by_button' }
  242. include_examples 'open chat with button'
  243. include_examples 'chat button is hidden after idle timeout'
  244. end
  245. end
  246. context 'when no-jquery variant is used' do
  247. let(:chat_url_type) { 'znuny-no-jquery' }
  248. before do
  249. visit '/'
  250. end
  251. context 'when normal mode is used' do
  252. include_examples 'chat messages'
  253. include_examples 'timeouts'
  254. end
  255. context 'when button mode is active' do
  256. let(:chat_url_type) { 'znuny-no-jquery-open_by_button' }
  257. include_examples 'open chat with button'
  258. include_examples 'chat button is hidden after idle timeout'
  259. end
  260. end
  261. describe "Chat can't be closed after timeout #2471", authenticated_as: :authenticate do
  262. shared_examples 'test issue #2471' do
  263. it 'is able to close to the dialog after a idleTimeout happened' do
  264. click agent_chat_switch_selector
  265. using_session :customer do
  266. visit chat_url
  267. click '.zammad-chat .js-chat-open'
  268. expect(page).to have_css('.js-restart', wait: 60)
  269. click '.js-chat-toggle .zammad-chat-header-icon'
  270. expect(page).to have_no_selector('zammad-chat-is-open', wait: 60)
  271. end
  272. end
  273. end
  274. before do
  275. visit '/'
  276. end
  277. context 'with jquery' do
  278. include_examples 'test issue #2471'
  279. end
  280. context 'without jquery' do
  281. let(:chat_url_type) { 'znuny-no-jquery' }
  282. include_examples 'test issue #2471'
  283. end
  284. end
  285. context 'when image is present in chat message', authenticated_as: :authenticate do
  286. let(:chat) { create(:chat) }
  287. let(:chat_user) { create(:agent) }
  288. let(:chat_session) { create(:'chat/session', user: chat_user, chat: chat) }
  289. before do
  290. file = Rails.root.join('spec/fixtures/files/image/squares.png').binread
  291. base64 = Base64.encode64(file).delete("\n")
  292. create(
  293. :'chat/message',
  294. chat_session: chat_session,
  295. content: "With inline image: <img src='data:image/png;base64,#{base64}' style='width: 100%; max-width: 460px;'>"
  296. )
  297. end
  298. context 'when image preview is used' do
  299. it 'use image preview' do
  300. visit "#customer_chat/session/#{chat_session.id}"
  301. find('.chat-body .chat-message img') { |elem| ActiveModel::Type::Boolean.new.cast elem[:complete] }
  302. .click
  303. in_modal do
  304. expect(page).to have_css('.js-submit', text: 'Download')
  305. end
  306. end
  307. end
  308. end
  309. end