123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439 |
- # Copyright (C) 2012-2024 Zammad Foundation, https://zammad-foundation.org/
- require 'rails_helper'
- RSpec.describe 'Chat Handling', type: :system do
- let(:agent_chat_switch_selector) { '#navigation .js-chatMenuItem .js-switch' }
- let(:chat_url) { "/assets/chat/#{chat_url_type}.html?port=#{ENV['WS_PORT']}" }
- let(:chat_url_type) { 'znuny' }
- def authenticate
- Setting.set('chat', true)
- true
- end
- def check_content(selector, value, should_match: true, wait: nil)
- if should_match
- expect(page).to have_css(selector, wait: wait, text: value)
- else
- expect(page).to have_no_css(selector, wait: wait, text: value)
- end
- end
- def enable_agent_chat
- click agent_chat_switch_selector
- click 'a[href="#customer_chat"]'
- end
- def open_chat_dialog
- expect(page).to have_css('.zammad-chat')
- click '.zammad-chat .js-chat-open'
- expect(page).to have_css('.zammad-chat-is-shown')
- end
- def send_customer_message(message)
- find('.zammad-chat .zammad-chat-input').send_keys(message)
- click '.zammad-chat .zammad-chat-send'
- end
- def send_agent_message(message)
- input = find('.active .chat-window .js-customerChatInput')
- input.send_keys(message)
- # Work around an obsure bug of send_keys sometimes not working on Firefox headless.
- if input.text != message
- input.execute_script("this.textContent = '#{message}'")
- end
- click '.active .chat-window .js-send'
- end
- shared_examples 'chat button is hidden after idle timeout' do
- it 'check that button is hidden after idle timeout', authenticated_as: :authenticate do
- click agent_chat_switch_selector
- using_session :customer do
- visit chat_url
- expect(page).to have_css('.zammad-chat', visible: :all)
- expect(page).to have_css('.zammad-chat-is-hidden', visible: :all)
- expect(page).to have_no_css('.open-zammad-chat:not([style*="display: none"]', visible: :all)
- end
- end
- end
- shared_examples 'chat messages' do
- it 'messages in each direction, starting on agent side', authenticated_as: :authenticate do
- enable_agent_chat
- using_session :customer do
- visit chat_url
- open_chat_dialog
- end
- click '.active .js-acceptChat'
- expect(page).to have_no_css('.active .chat-window .chat-status.is-modified')
- check_content('.active .chat-window .js-body', chat_url)
- send_agent_message('my name is me')
- using_session :customer do
- check_content('.zammad-chat .zammad-chat-agent-status', 'Online')
- check_content('.zammad-chat', 'my name is me')
- send_customer_message('my name is customer')
- end
- check_content('.active .chat-window', 'my name is customer')
- expect(page).to have_css('.active .chat-window .chat-status.is-modified')
- click '.active .chat-window .js-customerChatInput'
- expect(page).to have_no_css('.active .chat-window .chat-status.is-modified')
- using_session :customer do
- click '.js-chat-toggle .zammad-chat-header-icon'
- end
- check_content('.active .chat-window', 'closed the conversation')
- end
- it 'messages in each direction, starting on customer side', authenticated_as: :authenticate do
- enable_agent_chat
- using_session :customer do
- visit chat_url
- open_chat_dialog
- end
- click '.active .js-acceptChat'
- expect(page).to have_no_css('.active .chat-window .chat-status.is-modified')
- # Keep focus outside of chat window to check .chat-status.is-modified later.
- click_on 'Dashboard'
- using_session :customer do
- check_content('.zammad-chat .zammad-chat-agent-status', 'Online')
- send_customer_message('my name is customer')
- end
- click 'a[href="#customer_chat"]'
- expect(page).to have_css('.active .chat-window .chat-status.is-modified')
- check_content('.active .chat-window', 'my name is customer')
- send_agent_message('my name is me')
- expect(page).to have_no_css('.active .chat-window .chat-status.is-modified')
- using_session :customer do
- check_content('.zammad-chat', 'my name is me')
- end
- click '.active .chat-window .js-disconnect:not(.is-hidden)'
- click '.active .chat-window .js-close'
- using_session :customer do
- check_content('.zammad-chat .zammad-chat-agent-status', 'Offline')
- check_content('.zammad-chat', %r{(Chat closed by|Chat.*geschlossen)})
- click '.zammad-chat .js-chat-toggle .zammad-chat-header-icon'
- expect(page).to have_no_css('.zammad-chat-is-open')
- open_chat_dialog
- end
- click '.active .js-acceptChat'
- expect(page).to have_css('.active .chat-window .chat-status')
- end
- end
- shared_examples 'open chat with button' do
- it 'open the chat', authenticated_as: :authenticate do
- enable_agent_chat
- using_session :customer do
- visit chat_url
- expect(page).to have_css('.zammad-chat', visible: :all)
- expect(page).to have_css('.zammad-chat-is-hidden', visible: :all)
- expect(page).to have_no_css('.zammad-chat-is-shown', visible: :all)
- expect(page).to have_no_css('.zammad-chat-is-open', visible: :all)
- click '.open-zammad-chat'
- expect(page).to have_css('.zammad-chat-is-shown', visible: :all)
- expect(page).to have_css('.zammad-chat-is-open', visible: :all)
- check_content('.zammad-chat-modal-text', %r{(waiting|Warte)})
- click '.zammad-chat-header-icon-close'
- expect(page).to have_no_css('.zammad-chat-is-shown', visible: :all)
- expect(page).to have_no_css('.zammad-chat-is-open', visible: :all)
- end
- end
- end
- shared_examples 'timeouts' do
- it 'check different timeouts', authenticated_as: :authenticate do
- enable_agent_chat
- using_session :customer do
- visit chat_url
- # No customer action, hide the widget.
- expect(page).to have_css('.zammad-chat')
- expect(page).to have_no_css('.zammad-chat')
- refresh
- # No agent action, show sorry screen.
- open_chat_dialog
- check_content('.zammad-chat-modal-text', %r{(waiting|Warte)})
- check_content('.zammad-chat-modal-text', %r{(taking longer|dauert länger)})
- refresh
- # No customer action, show sorry screen.
- open_chat_dialog
- end
- click '.active .js-acceptChat'
- send_agent_message('agent is asking')
- using_session :customer do
- check_content('.zammad-chat', 'agent is asking')
- check_content('.zammad-chat-modal-text', %r{(Since you didn't respond|Da Sie innerhalb der letzten)}, wait: 30)
- end
- # Test the restart of inactive chat.
- click '.active .chat-window .js-close'
- using_session :customer do
- click '.js-restart'
- open_chat_dialog
- end
- click '.active .js-acceptChat'
- send_agent_message('my name is me')
- using_session :customer do
- check_content('.zammad-chat', 'my name is me')
- end
- end
- end
- context 'when chat is activated or disabled' do
- it 'switch the chat setting', authenticated_as: :authenticate do
- visit '/#channels/chat'
- click '.content.active .js-chatSetting'
- expect(page).to have_no_css(agent_chat_switch_selector)
- using_session :customer do
- visit chat_url
- check_content('.settings', '{"state":"chat_disabled"}')
- end
- click '.content.active .js-chatSetting'
- expect(page).to have_css(agent_chat_switch_selector)
- using_session :customer do
- refresh
- expect(page).to have_no_css('.zammad-chat')
- check_content('.settings', '{"state":"chat_disabled"}', should_match: false)
- check_content('.settings', '{"event":"chat_status_customer","data":{"state":"offline"}}')
- end
- click agent_chat_switch_selector
- click 'a[href="#customer_chat"]'
- using_session :customer do
- refresh
- expect(page).to have_css('.zammad-chat')
- check_content('.settings', '{"event":"chat_status_customer","data":{"state":"offline"}}', should_match: false)
- check_content('.settings', '{"state":"online"}')
- click '.zammad-chat .js-chat-open'
- expect(page).to have_css('.zammad-chat-is-shown')
- check_content('.zammad-chat-modal-text', %r{(waiting|Warte)})
- end
- check_content('.js-chatMenuItem .counter', '1')
- using_session :customer do
- click '.zammad-chat .js-chat-toggle .zammad-chat-header-icon'
- check_content('.zammad-chat-modal-text', %r{(waiting|Warte)}, should_match: false)
- end
- expect(page).to have_no_css('.js-chatMenuItem .counter')
- end
- end
- context 'when changing chat preferences for current agent' do
- it 'use chat phrase preference', authenticated_as: :authenticate do
- visit '/'
- enable_agent_chat
- click '.active .js-settings'
- in_modal do
- find('[name="chat::phrase::1"]').send_keys('Hi Stranger!;My Greeting')
- click '.js-submit'
- end
- using_session :customer do
- visit chat_url
- open_chat_dialog
- end
- click '.active .js-acceptChat'
- expect(page).to have_css('.active .chat-window .chat-status')
- using_session :customer do
- check_content('.zammad-chat', %r{(Hi Stranger|My Greeting)})
- end
- send_agent_message('my name is me')
- using_session :customer do
- check_content('.zammad-chat', 'my name is me')
- refresh
- expect(page).to have_css('.zammad-chat')
- check_content('.zammad-chat', %r{(Hi Stranger|My Greeting)})
- check_content('.zammad-chat', 'my name is me')
- visit "#{chat_url}#new_hash"
- end
- check_content('.active .chat-window .js-body', "#{chat_url}#new_hash")
- end
- end
- context 'when jquery variant is used' do
- before do
- visit '/'
- end
- context 'when normal mode is used' do
- include_examples 'chat messages'
- include_examples 'timeouts'
- end
- context 'when button mode is active' do
- let(:chat_url_type) { 'znuny_open_by_button' }
- include_examples 'open chat with button'
- include_examples 'chat button is hidden after idle timeout'
- end
- end
- context 'when no-jquery variant is used' do
- let(:chat_url_type) { 'znuny-no-jquery' }
- before do
- visit '/'
- end
- context 'when normal mode is used' do
- include_examples 'chat messages'
- include_examples 'timeouts'
- end
- context 'when button mode is active' do
- let(:chat_url_type) { 'znuny-no-jquery-open_by_button' }
- include_examples 'open chat with button'
- include_examples 'chat button is hidden after idle timeout'
- end
- end
- describe "Chat can't be closed after timeout #2471", authenticated_as: :authenticate do
- shared_examples 'test issue #2471' do
- it 'is able to close to the dialog after a idleTimeout happened' do
- click agent_chat_switch_selector
- using_session :customer do
- visit chat_url
- click '.zammad-chat .js-chat-open'
- expect(page).to have_css('.js-restart', wait: 60)
- click '.js-chat-toggle .zammad-chat-header-icon'
- expect(page).to have_no_selector('zammad-chat-is-open', wait: 60)
- end
- end
- end
- before do
- visit '/'
- end
- context 'with jquery' do
- include_examples 'test issue #2471'
- end
- context 'without jquery' do
- let(:chat_url_type) { 'znuny-no-jquery' }
- include_examples 'test issue #2471'
- end
- end
- context 'when image is present in chat message', authenticated_as: :authenticate do
- let(:chat) { create(:chat) }
- let(:chat_user) { create(:agent) }
- let(:chat_session) { create(:'chat/session', user: chat_user, chat: chat) }
- before do
- file = Rails.root.join('spec/fixtures/files/image/squares.png').binread
- base64 = Base64.encode64(file).delete("\n")
- create(
- :'chat/message',
- chat_session: chat_session,
- content: "With inline image: <img src='data:image/png;base64,#{base64}' style='width: 100%; max-width: 460px;'>"
- )
- end
- context 'when image preview is used' do
- it 'use image preview' do
- visit "#customer_chat/session/#{chat_session.id}"
- find('.chat-body .chat-message img') { |elem| ActiveModel::Type::Boolean.new.cast elem[:complete] }
- .click
- in_modal do
- expect(page).to have_css('.js-submit', text: 'Download')
- end
- end
- end
- end
- end
|