Maintenance: Switch to headless Selenium in CI.
This commit is contained in:
parent
25c971ed00
commit
f84ac43cdd
8 changed files with 163 additions and 194 deletions
|
@ -22,6 +22,7 @@
|
|||
variables:
|
||||
REMOTE_URL: "http://selenium-firefox:4444/wd/hub"
|
||||
BROWSER: "firefox"
|
||||
START_XVFB: "false" # not needed for headless mode
|
||||
SE_NODE_MAX_SESSIONS: "5"
|
||||
SE_NODE_OVERRIDE_MAX_SESSIONS: "true"
|
||||
|
||||
|
@ -29,6 +30,7 @@
|
|||
variables:
|
||||
REMOTE_URL: "http://selenium-chrome:4444/wd/hub"
|
||||
BROWSER: chrome
|
||||
START_XVFB: "false" # not needed for headless mode
|
||||
SE_NODE_MAX_SESSIONS: "5"
|
||||
SE_NODE_OVERRIDE_MAX_SESSIONS: "true"
|
||||
|
||||
|
|
|
@ -152,16 +152,6 @@ module CapybaraCustomExtensions
|
|||
def page(...)
|
||||
ZammadCapybaraSessionDelegator.new(element: super, context: self)
|
||||
end
|
||||
|
||||
# Work around an issue with failures in Capybara if different specs of the same rspec run
|
||||
# use using_session with the same name, e.g. :second_browser. Solve by prepending the test name.
|
||||
def using_session(name_or_session, &block)
|
||||
if !(name_or_session.is_a? Capybara::Session)
|
||||
# self.class.name refers to the RSpec test case.
|
||||
name_or_session = (self.class.name + "::#{name_or_session}").to_sym
|
||||
end
|
||||
Capybara.using_session(name_or_session, &block)
|
||||
end
|
||||
end
|
||||
|
||||
RSpec.configure do |config|
|
||||
|
|
|
@ -35,10 +35,19 @@ RSpec.configure do |config|
|
|||
browser_height = 1000
|
||||
end
|
||||
|
||||
# Firefox and Chrome effective screen sizes are slightly different
|
||||
# accomodate that by reducing declared screen size on Firefox
|
||||
browser_height -= 44 if browser_name == 'firefox'
|
||||
|
||||
page.driver.browser.manage.window.resize_to(browser_width, browser_height)
|
||||
end
|
||||
|
||||
config.after(:each, type: :system) do
|
||||
# Make sure additional sessions (from using_sessions) are always ended
|
||||
# after every test and not kept alive. Selenium will automatically close
|
||||
# idle sessions which can cause 404 errors later.
|
||||
# (see https://github.com/teamcapybara/capybara/issues/2237)
|
||||
Capybara.send(:session_pool).reverse_each do |_mode, session|
|
||||
if !session.eql?(Capybara.current_session)
|
||||
session.quit
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
|
|
@ -15,6 +15,8 @@ Capybara.register_driver(:zammad_chrome) do |app|
|
|||
'intl.accept_languages' => 'en-US',
|
||||
'profile.default_content_setting_values.notifications' => 1, # ALLOW notifications
|
||||
},
|
||||
# Disable the "Chrome is controlled by automation software" info bar.
|
||||
excludeSwitches: ['enable-automation'],
|
||||
)
|
||||
|
||||
options = {
|
||||
|
@ -25,6 +27,7 @@ Capybara.register_driver(:zammad_chrome) do |app|
|
|||
if ENV['REMOTE_URL'].present?
|
||||
options[:browser] = :remote
|
||||
options[:url] = ENV['REMOTE_URL']
|
||||
options[:options].headless!
|
||||
end
|
||||
|
||||
ENV['FAKE_SELENIUM_LOGIN_USER_ID'] = nil
|
||||
|
@ -51,6 +54,7 @@ Capybara.register_driver(:zammad_firefox) do |app|
|
|||
if ENV['REMOTE_URL'].present?
|
||||
options[:browser] = :remote
|
||||
options[:url] = ENV['REMOTE_URL']
|
||||
options[:options].headless!
|
||||
end
|
||||
|
||||
ENV['FAKE_SELENIUM_LOGIN_USER_ID'] = nil
|
||||
|
@ -60,16 +64,3 @@ Capybara.register_driver(:zammad_firefox) do |app|
|
|||
driver.browser.file_detector = nil if ENV['REMOTE_URL'].present?
|
||||
end
|
||||
end
|
||||
|
||||
class Capybara::Selenium::Driver
|
||||
alias original_quit quit
|
||||
|
||||
def quit
|
||||
original_quit
|
||||
rescue Selenium::WebDriver::Error::ServerError
|
||||
# Work around a possible capybara/Selenium bug. driver.quit() fails because there is already no session any more;
|
||||
# not sure why that happens.
|
||||
ensure
|
||||
@browser = nil
|
||||
end
|
||||
end
|
||||
|
|
|
@ -37,7 +37,12 @@ RSpec.describe 'Chat Handling', type: :system do
|
|||
end
|
||||
|
||||
def send_agent_message(message)
|
||||
find('.active .chat-window .js-customerChatInput').send_keys(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
|
||||
|
||||
|
@ -45,8 +50,7 @@ RSpec.describe 'Chat Handling', type: :system do
|
|||
it 'check that button is hidden after idle timeout', authenticated_as: :authenticate do
|
||||
click agent_chat_switch_selector
|
||||
|
||||
open_window_and_switch
|
||||
|
||||
using_session :customer do
|
||||
visit chat_url
|
||||
|
||||
expect(page).to have_css('.zammad-chat', visible: :all)
|
||||
|
@ -54,18 +58,16 @@ RSpec.describe 'Chat Handling', type: :system do
|
|||
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
|
||||
|
||||
open_window_and_switch
|
||||
|
||||
using_session :customer do
|
||||
visit chat_url
|
||||
|
||||
open_chat_dialog
|
||||
|
||||
switch_to_window_index(1)
|
||||
end
|
||||
|
||||
click '.active .js-acceptChat'
|
||||
|
||||
|
@ -74,14 +76,11 @@ RSpec.describe 'Chat Handling', type: :system do
|
|||
|
||||
send_agent_message('my name is me')
|
||||
|
||||
switch_to_window_index(2)
|
||||
|
||||
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')
|
||||
|
||||
switch_to_window_index(1)
|
||||
end
|
||||
|
||||
check_content('.active .chat-window', 'my name is customer')
|
||||
expect(page).to have_css('.active .chat-window .chat-status.is-modified')
|
||||
|
@ -90,11 +89,9 @@ RSpec.describe 'Chat Handling', type: :system do
|
|||
|
||||
expect(page).to have_no_css('.active .chat-window .chat-status.is-modified')
|
||||
|
||||
switch_to_window_index(2)
|
||||
|
||||
using_session :customer do
|
||||
click '.js-chat-toggle .zammad-chat-header-icon'
|
||||
|
||||
switch_to_window_index(1)
|
||||
end
|
||||
|
||||
check_content('.active .chat-window', 'closed the conversation')
|
||||
end
|
||||
|
@ -102,13 +99,12 @@ RSpec.describe 'Chat Handling', type: :system do
|
|||
it 'messages in each direction, starting on customer side', authenticated_as: :authenticate do
|
||||
enable_agent_chat
|
||||
|
||||
open_window_and_switch
|
||||
using_session :customer do
|
||||
|
||||
visit chat_url
|
||||
|
||||
open_chat_dialog
|
||||
|
||||
switch_to_window_index(1)
|
||||
end
|
||||
|
||||
click '.active .js-acceptChat'
|
||||
|
||||
|
@ -117,13 +113,10 @@ RSpec.describe 'Chat Handling', type: :system do
|
|||
# Keep focus outside of chat window to check .chat-status.is-modified later.
|
||||
click '#global-search'
|
||||
|
||||
switch_to_window_index(2)
|
||||
|
||||
using_session :customer do
|
||||
check_content('.zammad-chat .zammad-chat-agent-status', 'Online')
|
||||
|
||||
send_customer_message('my name is customer')
|
||||
|
||||
switch_to_window_index(1)
|
||||
end
|
||||
|
||||
expect(page).to have_css('.active .chat-window .chat-status.is-modified')
|
||||
check_content('.active .chat-window', 'my name is customer')
|
||||
|
@ -131,16 +124,14 @@ RSpec.describe 'Chat Handling', type: :system do
|
|||
send_agent_message('my name is me')
|
||||
expect(page).to have_no_css('.active .chat-window .chat-status.is-modified')
|
||||
|
||||
switch_to_window_index(2)
|
||||
|
||||
using_session :customer do
|
||||
check_content('.zammad-chat', 'my name is me')
|
||||
|
||||
switch_to_window_index(1)
|
||||
end
|
||||
|
||||
click '.active .chat-window .js-disconnect:not(.is-hidden)'
|
||||
click '.active .chat-window .js-close'
|
||||
|
||||
switch_to_window_index(2)
|
||||
using_session :customer do
|
||||
|
||||
check_content('.zammad-chat .zammad-chat-agent-status', 'Offline')
|
||||
check_content('.zammad-chat', %r{(Chat closed by|Chat beendet von)})
|
||||
|
@ -150,8 +141,7 @@ RSpec.describe 'Chat Handling', type: :system do
|
|||
expect(page).to have_no_css('.zammad-chat-is-open')
|
||||
|
||||
open_chat_dialog
|
||||
|
||||
switch_to_window_index(1)
|
||||
end
|
||||
|
||||
click '.active .js-acceptChat'
|
||||
|
||||
|
@ -163,8 +153,7 @@ RSpec.describe 'Chat Handling', type: :system do
|
|||
it 'open the chat', authenticated_as: :authenticate do
|
||||
enable_agent_chat
|
||||
|
||||
open_window_and_switch
|
||||
|
||||
using_session :customer do
|
||||
visit chat_url
|
||||
|
||||
expect(page).to have_css('.zammad-chat', visible: :all)
|
||||
|
@ -184,12 +173,13 @@ RSpec.describe 'Chat Handling', type: :system do
|
|||
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
|
||||
|
||||
open_window_and_switch
|
||||
using_session :customer do
|
||||
|
||||
visit chat_url
|
||||
|
||||
|
@ -210,41 +200,37 @@ RSpec.describe 'Chat Handling', type: :system do
|
|||
|
||||
# No customer action, show sorry screen.
|
||||
open_chat_dialog
|
||||
|
||||
switch_to_window_index(1)
|
||||
end
|
||||
|
||||
click '.active .js-acceptChat'
|
||||
|
||||
send_agent_message('agent is asking')
|
||||
|
||||
switch_to_window_index(2)
|
||||
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 in den letzten)}, wait: 30)
|
||||
end
|
||||
|
||||
# Test the restart of inactive chat.
|
||||
switch_to_window_index(1)
|
||||
|
||||
click '.active .chat-window .js-close'
|
||||
|
||||
switch_to_window_index(2)
|
||||
using_session :customer do
|
||||
|
||||
click '.js-restart'
|
||||
|
||||
open_chat_dialog
|
||||
|
||||
switch_to_window_index(1)
|
||||
end
|
||||
|
||||
click '.active .js-acceptChat'
|
||||
|
||||
send_agent_message('my name is me')
|
||||
|
||||
switch_to_window_index(2)
|
||||
|
||||
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
|
||||
|
@ -254,32 +240,30 @@ RSpec.describe 'Chat Handling', type: :system do
|
|||
|
||||
expect(page).to have_no_css(agent_chat_switch_selector)
|
||||
|
||||
open_window_and_switch
|
||||
using_session :customer do
|
||||
|
||||
visit chat_url
|
||||
|
||||
check_content('.settings', '{"state":"chat_disabled"}')
|
||||
|
||||
switch_to_window_index(1)
|
||||
end
|
||||
|
||||
click '.content.active .js-chatSetting'
|
||||
|
||||
expect(page).to have_css(agent_chat_switch_selector)
|
||||
|
||||
switch_to_window_index(2)
|
||||
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"}}')
|
||||
|
||||
switch_to_window_index(1)
|
||||
end
|
||||
|
||||
click agent_chat_switch_selector
|
||||
click 'a[href="#customer_chat"]'
|
||||
|
||||
switch_to_window_index(2)
|
||||
using_session :customer do
|
||||
|
||||
refresh
|
||||
|
||||
|
@ -291,18 +275,16 @@ RSpec.describe 'Chat Handling', type: :system do
|
|||
|
||||
expect(page).to have_css('.zammad-chat-is-shown')
|
||||
check_content('.zammad-chat-modal-text', %r{(waiting|Warte)})
|
||||
|
||||
switch_to_window_index(1)
|
||||
end
|
||||
|
||||
check_content('.js-chatMenuItem .counter', '1')
|
||||
|
||||
switch_to_window_index(2)
|
||||
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)
|
||||
|
||||
switch_to_window_index(1)
|
||||
end
|
||||
|
||||
expect(page).to have_no_css('.js-chatMenuItem .counter')
|
||||
end
|
||||
|
@ -321,27 +303,24 @@ RSpec.describe 'Chat Handling', type: :system do
|
|||
|
||||
modal_disappear
|
||||
|
||||
open_window_and_switch
|
||||
using_session :customer do
|
||||
|
||||
visit chat_url
|
||||
|
||||
open_chat_dialog
|
||||
|
||||
switch_to_window_index(1)
|
||||
end
|
||||
|
||||
click '.active .js-acceptChat'
|
||||
|
||||
expect(page).to have_css('.active .chat-window .chat-status')
|
||||
|
||||
switch_to_window_index(2)
|
||||
|
||||
using_session :customer do
|
||||
check_content('.zammad-chat', %r{(Hi Stranger|My Greeting)})
|
||||
|
||||
switch_to_window_index(1)
|
||||
end
|
||||
|
||||
send_agent_message('my name is me')
|
||||
|
||||
switch_to_window_index(2)
|
||||
using_session :customer do
|
||||
|
||||
check_content('.zammad-chat', 'my name is me')
|
||||
|
||||
|
@ -352,8 +331,7 @@ RSpec.describe 'Chat Handling', type: :system do
|
|||
check_content('.zammad-chat', 'my name is me')
|
||||
|
||||
visit "#{chat_url}#new_hash"
|
||||
|
||||
switch_to_window_index(1)
|
||||
end
|
||||
|
||||
check_content('.active .chat-window .js-body', "#{chat_url}#new_hash")
|
||||
end
|
||||
|
@ -373,7 +351,7 @@ RSpec.describe 'Chat Handling', type: :system do
|
|||
end
|
||||
end
|
||||
|
||||
context 'when none jquery variant is used' do
|
||||
context 'when no-jquery variant is used' do
|
||||
let(:chat_url_type) { 'znuny-no-jquery' }
|
||||
|
||||
context 'when normal mode is used' do
|
||||
|
@ -393,7 +371,7 @@ RSpec.describe 'Chat Handling', type: :system 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
|
||||
open_window_and_switch
|
||||
using_session :customer do
|
||||
|
||||
visit chat_url
|
||||
click '.zammad-chat .js-chat-open'
|
||||
|
@ -402,12 +380,13 @@ RSpec.describe 'Chat Handling', type: :system do
|
|||
expect(page).to have_no_selector('zammad-chat-is-open', wait: 60)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context 'with jquery' do
|
||||
include_examples 'test issue #2471'
|
||||
end
|
||||
|
||||
context 'wihtout jquery' do
|
||||
context 'without jquery' do
|
||||
let(:chat_url_type) { 'znuny-no-jquery' }
|
||||
|
||||
include_examples 'test issue #2471'
|
||||
|
|
|
@ -146,9 +146,7 @@ class AgentOrganizationProfileTest < TestCase
|
|||
css: '.active .profile [data-name="note"]',
|
||||
slow: true,
|
||||
value: message,
|
||||
)
|
||||
empty_search(
|
||||
browser: browser1,
|
||||
blur: true
|
||||
)
|
||||
|
||||
# verify
|
||||
|
|
|
@ -139,9 +139,7 @@ class AgentUserProfileTest < TestCase
|
|||
browser: browser1,
|
||||
css: '.active [data-name="note"]',
|
||||
value: message,
|
||||
)
|
||||
empty_search(
|
||||
browser: browser1,
|
||||
blur: true,
|
||||
)
|
||||
|
||||
watch_for(
|
||||
|
|
|
@ -91,16 +91,6 @@ class TestCase < ActiveSupport::TestCase
|
|||
params = {
|
||||
profile: profile,
|
||||
}
|
||||
if ENV['BROWSER_HEADLESS'].present?
|
||||
case browser
|
||||
when 'firefox'
|
||||
params[:options] = Selenium::WebDriver::Firefox::Options.new
|
||||
params[:options].add_argument('-headless')
|
||||
when 'chrome'
|
||||
params[:options] = Selenium::WebDriver::Chrome::Options.new
|
||||
params[:options].add_argument('-headless')
|
||||
end
|
||||
end
|
||||
local_browser = Selenium::WebDriver.for(browser.to_sym, params)
|
||||
@browsers[local_browser.hash] = local_browser
|
||||
browser_instance_preferences(local_browser)
|
||||
|
@ -135,12 +125,24 @@ class TestCase < ActiveSupport::TestCase
|
|||
open_timeout: 120,
|
||||
read_timeout: 120
|
||||
)
|
||||
case browser
|
||||
when 'firefox'
|
||||
options = Selenium::WebDriver::Firefox::Options.new
|
||||
options.headless!
|
||||
when 'chrome'
|
||||
options = Selenium::WebDriver::Chrome::Options.new(
|
||||
# Disable the "Chrome is controlled by automation software" info bar.
|
||||
excludeSwitches: ['enable-automation'],
|
||||
)
|
||||
options.headless!
|
||||
end
|
||||
|
||||
local_browser = Selenium::WebDriver.for(
|
||||
:remote,
|
||||
url: ENV['REMOTE_URL'],
|
||||
desired_capabilities: caps,
|
||||
http_client: http_client,
|
||||
options: options,
|
||||
)
|
||||
@browsers[local_browser.hash] = local_browser
|
||||
browser_instance_preferences(local_browser)
|
||||
|
|
Loading…
Reference in a new issue