Maintenance: Stabilize tests with general wait_for_ajax_empty approach and some fixed tests.
This commit is contained in:
parent
1242121de7
commit
c44196d7ab
24 changed files with 415 additions and 199 deletions
|
@ -690,6 +690,7 @@ Metrics/ModuleLength:
|
||||||
- 'lib/signature_detection.rb'
|
- 'lib/signature_detection.rb'
|
||||||
- 'lib/static_assets.rb'
|
- 'lib/static_assets.rb'
|
||||||
- 'lib/transaction_dispatcher.rb'
|
- 'lib/transaction_dispatcher.rb'
|
||||||
|
- 'spec/support/capybara/common_actions.rb'
|
||||||
|
|
||||||
Metrics/PerceivedComplexity:
|
Metrics/PerceivedComplexity:
|
||||||
Exclude:
|
Exclude:
|
||||||
|
|
|
@ -1038,12 +1038,13 @@ class App.ControllerTable extends App.Controller
|
||||||
# update store
|
# update store
|
||||||
@preferencesStore('order', 'customOrderBy', @orderBy)
|
@preferencesStore('order', 'customOrderBy', @orderBy)
|
||||||
@preferencesStore('order', 'customOrderDirection', @orderDirection)
|
@preferencesStore('order', 'customOrderDirection', @orderDirection)
|
||||||
render = =>
|
|
||||||
@renderTableFull(false, skipHeadersResize: true)
|
|
||||||
App.QueueManager.add('tableRender', render)
|
|
||||||
|
|
||||||
if @sortRenderCallback
|
if @sortRenderCallback
|
||||||
App.QueueManager.add('tableRender', @sortRenderCallback)
|
App.QueueManager.add('tableRender', @sortRenderCallback)
|
||||||
|
else
|
||||||
|
render = =>
|
||||||
|
@renderTableFull(false, skipHeadersResize: true)
|
||||||
|
App.QueueManager.add('tableRender', render)
|
||||||
|
|
||||||
App.QueueManager.run('tableRender')
|
App.QueueManager.run('tableRender')
|
||||||
|
|
||||||
|
|
|
@ -68,9 +68,11 @@ module BrowserTestHelper
|
||||||
# await_empty_ajax_queue
|
# await_empty_ajax_queue
|
||||||
#
|
#
|
||||||
def await_empty_ajax_queue
|
def await_empty_ajax_queue
|
||||||
wait(5, interval: 0.5).until_constant do
|
wait(5, interval: 0.1).until_constant do
|
||||||
page.evaluate_script('App.Ajax.queue().length').zero?
|
page.evaluate_script('App.Ajax.queue().length').zero?
|
||||||
end
|
end
|
||||||
|
rescue
|
||||||
|
nil
|
||||||
end
|
end
|
||||||
|
|
||||||
# Moves the mouse from its current position by the given offset.
|
# Moves the mouse from its current position by the given offset.
|
||||||
|
@ -112,6 +114,7 @@ module BrowserTestHelper
|
||||||
#
|
#
|
||||||
def release_mouse
|
def release_mouse
|
||||||
page.driver.browser.action.release.perform
|
page.driver.browser.action.release.perform
|
||||||
|
await_empty_ajax_queue
|
||||||
end
|
end
|
||||||
|
|
||||||
class Waiter < SimpleDelegator
|
class Waiter < SimpleDelegator
|
||||||
|
|
|
@ -38,6 +38,8 @@ module CommonActions
|
||||||
wait(4).until_exists do
|
wait(4).until_exists do
|
||||||
current_login
|
current_login
|
||||||
end
|
end
|
||||||
|
|
||||||
|
await_empty_ajax_queue
|
||||||
end
|
end
|
||||||
|
|
||||||
# Checks if the current session is logged in.
|
# Checks if the current session is logged in.
|
||||||
|
@ -120,6 +122,16 @@ module CommonActions
|
||||||
route = "/##{route}"
|
route = "/##{route}"
|
||||||
end
|
end
|
||||||
super(route)
|
super(route)
|
||||||
|
|
||||||
|
# wait for AJAX requets only on WebApp visits
|
||||||
|
return if !route.start_with?('/#')
|
||||||
|
return if route == '/#logout'
|
||||||
|
|
||||||
|
# make sure all AJAX requests are done
|
||||||
|
await_empty_ajax_queue
|
||||||
|
|
||||||
|
# make sure loading is completed (e.g. ticket zoom may take longer)
|
||||||
|
expect(page).to have_no_css('.icon-loading', wait: 30)
|
||||||
end
|
end
|
||||||
|
|
||||||
# Overwrites the global Capybara.always_include_port setting (true)
|
# Overwrites the global Capybara.always_include_port setting (true)
|
||||||
|
|
|
@ -34,3 +34,108 @@ class Capybara::Node::Element
|
||||||
raise "Element still moving after #{checks} checks"
|
raise "Element still moving after #{checks} checks"
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
module ZammadCapybarActionDelegator
|
||||||
|
def select(*)
|
||||||
|
super.tap do
|
||||||
|
await_empty_ajax_queue
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def click(*)
|
||||||
|
super.tap do
|
||||||
|
await_empty_ajax_queue
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def click_on(*)
|
||||||
|
super.tap do
|
||||||
|
await_empty_ajax_queue
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def click_link_or_button(*)
|
||||||
|
super.tap do
|
||||||
|
await_empty_ajax_queue
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def click_button(*)
|
||||||
|
super.tap do
|
||||||
|
await_empty_ajax_queue
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def select_option(*)
|
||||||
|
super.tap do
|
||||||
|
await_empty_ajax_queue
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def send_keys(*)
|
||||||
|
super.tap do
|
||||||
|
await_empty_ajax_queue
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
module ZammadCapybarSelectorDelegator
|
||||||
|
def find_field(*)
|
||||||
|
ZammadCapybaraElementDelegator.new(element: super, context: self)
|
||||||
|
end
|
||||||
|
|
||||||
|
def find_button(*)
|
||||||
|
ZammadCapybaraElementDelegator.new(element: super, context: self)
|
||||||
|
end
|
||||||
|
|
||||||
|
def find_by_id(*)
|
||||||
|
ZammadCapybaraElementDelegator.new(element: super, context: self)
|
||||||
|
end
|
||||||
|
|
||||||
|
def find_link(*)
|
||||||
|
ZammadCapybaraElementDelegator.new(element: super, context: self)
|
||||||
|
end
|
||||||
|
|
||||||
|
def find(*)
|
||||||
|
ZammadCapybaraElementDelegator.new(element: super, context: self)
|
||||||
|
end
|
||||||
|
|
||||||
|
def first(*)
|
||||||
|
ZammadCapybaraElementDelegator.new(element: super, context: self)
|
||||||
|
end
|
||||||
|
|
||||||
|
def all(*)
|
||||||
|
super.map { |element| ZammadCapybaraElementDelegator.new(element: element, context: self) }
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
class ZammadCapybaraSessionDelegator < SimpleDelegator
|
||||||
|
extend Forwardable
|
||||||
|
|
||||||
|
def_delegator :@context, :await_empty_ajax_queue
|
||||||
|
|
||||||
|
include ZammadCapybarSelectorDelegator
|
||||||
|
|
||||||
|
def initialize(context:, element:)
|
||||||
|
@context = context
|
||||||
|
|
||||||
|
super(element)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
class ZammadCapybaraElementDelegator < ZammadCapybaraSessionDelegator
|
||||||
|
include ZammadCapybarActionDelegator
|
||||||
|
end
|
||||||
|
|
||||||
|
module CapybaraCustomExtensions
|
||||||
|
include ZammadCapybarActionDelegator
|
||||||
|
include ZammadCapybarSelectorDelegator
|
||||||
|
|
||||||
|
def page(*)
|
||||||
|
ZammadCapybaraSessionDelegator.new(element: super, context: self)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
RSpec.configure do |config|
|
||||||
|
config.include CapybaraCustomExtensions, type: :system
|
||||||
|
end
|
||||||
|
|
|
@ -15,12 +15,12 @@ RSpec.describe 'Authentication', type: :system do
|
||||||
|
|
||||||
it 'Logout' do
|
it 'Logout' do
|
||||||
logout
|
logout
|
||||||
expect_current_route 'login', wait: 2
|
expect_current_route 'login', wait: 10
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'will unset user attributes after logout' do
|
it 'will unset user attributes after logout' do
|
||||||
logout
|
logout
|
||||||
expect_current_route 'login', wait: 2
|
expect_current_route 'login', wait: 10
|
||||||
|
|
||||||
visit '/#signup'
|
visit '/#signup'
|
||||||
|
|
||||||
|
@ -31,20 +31,20 @@ RSpec.describe 'Authentication', type: :system do
|
||||||
it 'Login and redirect to requested url', authenticated_as: false do
|
it 'Login and redirect to requested url', authenticated_as: false do
|
||||||
visit 'ticket/zoom/1'
|
visit 'ticket/zoom/1'
|
||||||
|
|
||||||
expect_current_route 'login', wait: 2
|
expect_current_route 'login', wait: 10
|
||||||
|
|
||||||
login(
|
login(
|
||||||
username: 'master@example.com',
|
username: 'master@example.com',
|
||||||
password: 'test',
|
password: 'test',
|
||||||
)
|
)
|
||||||
|
|
||||||
expect_current_route 'ticket/zoom/1', wait: 2
|
expect_current_route 'ticket/zoom/1', wait: 10
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'Login and redirect to requested url via external authentication', authenticated_as: false do
|
it 'Login and redirect to requested url via external authentication', authenticated_as: false do
|
||||||
visit 'ticket/zoom/1'
|
visit 'ticket/zoom/1'
|
||||||
|
|
||||||
expect_current_route 'login', wait: 2
|
expect_current_route 'login', wait: 10
|
||||||
|
|
||||||
# simulate jump to external ressource
|
# simulate jump to external ressource
|
||||||
visit 'https://www.zammad.org'
|
visit 'https://www.zammad.org'
|
||||||
|
@ -59,7 +59,7 @@ RSpec.describe 'Authentication', type: :system do
|
||||||
# jump back and check if origin requested url is shown
|
# jump back and check if origin requested url is shown
|
||||||
visit ''
|
visit ''
|
||||||
|
|
||||||
expect_current_route 'ticket/zoom/1', wait: 2
|
expect_current_route 'ticket/zoom/1', wait: 10
|
||||||
|
|
||||||
expect(current_login).to eq('master@example.com')
|
expect(current_login).to eq('master@example.com')
|
||||||
end
|
end
|
||||||
|
|
|
@ -30,7 +30,6 @@ RSpec.describe 'Dashboard', type: :system, authenticated_as: true do
|
||||||
fill_in 'Lastname', with: 'Braun'
|
fill_in 'Lastname', with: 'Braun'
|
||||||
fill_in 'Email', with: 'nick.braun@zammad.org'
|
fill_in 'Email', with: 'nick.braun@zammad.org'
|
||||||
click_on 'Invite'
|
click_on 'Invite'
|
||||||
await_empty_ajax_queue
|
|
||||||
expect(User.find_by(firstname: 'Nick').roles).to eq([Role.find_by(name: 'Public')])
|
expect(User.find_by(firstname: 'Nick').roles).to eq([Role.find_by(name: 'Public')])
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -42,6 +41,7 @@ RSpec.describe 'Dashboard', type: :system, authenticated_as: true do
|
||||||
|
|
||||||
before do
|
before do
|
||||||
ensure_websocket(check_if_pinged: false)
|
ensure_websocket(check_if_pinged: false)
|
||||||
|
sleep 3 # fast relog causes raise conditions in websocket server
|
||||||
end
|
end
|
||||||
|
|
||||||
context 'Logout by frontend plugin - Default', authenticated_as: :authenticate do
|
context 'Logout by frontend plugin - Default', authenticated_as: :authenticate do
|
||||||
|
|
|
@ -1,46 +1,46 @@
|
||||||
# Copyright (C) 2012-2021 Zammad Foundation, http://zammad-foundation.org/
|
# Copyright (C) 2012-2021 Zammad Foundation, http://zammad-foundation.org/
|
||||||
|
|
||||||
RSpec.shared_examples 'pagination' do |model:, klass:, path:, sort_by: :name|
|
RSpec.shared_examples 'pagination' do |model:, klass:, path:, sort_by: :name|
|
||||||
def prepare(model)
|
let(:model) { model }
|
||||||
|
|
||||||
|
def authenticate
|
||||||
create_list(model, 500)
|
create_list(model, 500)
|
||||||
|
true
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'does paginate' do
|
it 'does paginate', authenticated_as: :authenticate do
|
||||||
prepare(model)
|
|
||||||
visit path
|
visit path
|
||||||
refresh # more stability
|
|
||||||
expect(page).to have_css('.js-pager', wait: 10)
|
expect(page).to have_css('.js-pager', wait: 10)
|
||||||
|
|
||||||
class_page1 = klass.order(sort_by => :asc, id: :asc).offset(50).first
|
class_page1 = klass.order(sort_by => :asc, id: :asc).offset(50).first
|
||||||
expect(page).to have_text(class_page1.name, wait: 10)
|
expect(page).to have_text(class_page1.name, wait: 10)
|
||||||
|
expect(page).to have_css('.js-page.is-selected', text: '1')
|
||||||
|
|
||||||
page.first('.js-page', text: '2').click
|
page.first('.js-page', text: '2', wait: 10).click
|
||||||
await_empty_ajax_queue
|
|
||||||
|
|
||||||
class_page2 = klass.order(sort_by => :asc, id: :asc).offset(175).first
|
class_page2 = klass.order(sort_by => :asc, id: :asc).offset(175).first
|
||||||
expect(page).to have_text(class_page2.name, wait: 10)
|
expect(page).to have_text(class_page2.name, wait: 10)
|
||||||
|
expect(page).to have_css('.js-page.is-selected', text: '2')
|
||||||
|
|
||||||
page.first('.js-page', text: '3').click
|
page.first('.js-page', text: '3', wait: 10).click
|
||||||
await_empty_ajax_queue
|
|
||||||
|
|
||||||
class_page3 = klass.order(sort_by => :asc, id: :asc).offset(325).first
|
class_page3 = klass.order(sort_by => :asc, id: :asc).offset(325).first
|
||||||
expect(page).to have_text(class_page3.name, wait: 10)
|
expect(page).to have_text(class_page3.name, wait: 10)
|
||||||
|
expect(page).to have_css('.js-page.is-selected', text: '3')
|
||||||
|
|
||||||
page.first('.js-page', text: '4').click
|
page.first('.js-page', text: '4', wait: 10).click
|
||||||
await_empty_ajax_queue
|
|
||||||
|
|
||||||
class_page4 = klass.order(sort_by => :asc, id: :asc).offset(475).first
|
class_page4 = klass.order(sort_by => :asc, id: :asc).offset(475).first
|
||||||
expect(page).to have_text(class_page4.name, wait: 10)
|
expect(page).to have_text(class_page4.name, wait: 10)
|
||||||
|
expect(page).to have_css('.js-page.is-selected', text: '4')
|
||||||
|
|
||||||
page.first('.js-page', text: '1').click
|
page.first('.js-page', text: '1', wait: 10).click
|
||||||
await_empty_ajax_queue
|
|
||||||
|
|
||||||
page.first('.js-tableHead[data-column-key=name]').click
|
page.first('.js-tableHead[data-column-key=name]').click
|
||||||
await_empty_ajax_queue
|
|
||||||
expect(page).to have_text(class_page1.name, wait: 10)
|
expect(page).to have_text(class_page1.name, wait: 10)
|
||||||
|
expect(page).to have_css('.js-page.is-selected', text: '1')
|
||||||
|
|
||||||
page.first('.js-tableHead[data-column-key=name]').click
|
page.first('.js-tableHead[data-column-key=name]').click
|
||||||
await_empty_ajax_queue
|
|
||||||
class_last = klass.order(sort_by => :desc).first
|
class_last = klass.order(sort_by => :desc).first
|
||||||
expect(page).to have_text(class_last.name, wait: 10)
|
expect(page).to have_text(class_last.name, wait: 10)
|
||||||
end
|
end
|
||||||
|
|
|
@ -42,12 +42,12 @@ RSpec.describe 'Manage > Users', type: :system do
|
||||||
visit 'manage/users'
|
visit 'manage/users'
|
||||||
|
|
||||||
within(:active_content) do
|
within(:active_content) do
|
||||||
row = find("tr[data-id=\"#{user.id}\"]")
|
row = find("tr[data-id=\"#{user.id}\"]", wait: 10)
|
||||||
row.find('.js-action').click
|
row.find('.js-action').click
|
||||||
row.find('.js-switchTo').click
|
row.find('.js-switchTo').click
|
||||||
end
|
end
|
||||||
|
|
||||||
await_empty_ajax_queue
|
expect(page).to have_text("Zammad looks like this for \"#{user.firstname} #{user.lastname}\"", wait: 10)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -63,8 +63,6 @@ RSpec.describe 'Admin Panel > Objects', type: :system, authenticated_as: true do
|
||||||
'nulloption' => true,
|
'nulloption' => true,
|
||||||
'maxlength' => 255 }
|
'maxlength' => 255 }
|
||||||
|
|
||||||
await_empty_ajax_queue
|
|
||||||
|
|
||||||
expect(ObjectManager::Attribute.last.data_option).to eq(expected_data_options)
|
expect(ObjectManager::Attribute.last.data_option).to eq(expected_data_options)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -15,6 +15,6 @@ RSpec.describe 'System > Translations', type: :system do
|
||||||
|
|
||||||
click '.js-syncChanges'
|
click '.js-syncChanges'
|
||||||
|
|
||||||
modal_ready && modal_disappear # make sure test is not terminated while modal is visible
|
modal_disappear # make sure test is not terminated while modal is visible
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -204,8 +204,6 @@ RSpec.describe 'Ticket Create', type: :system do
|
||||||
encrypt_button = find('.js-securityEncrypt', wait: 5)
|
encrypt_button = find('.js-securityEncrypt', wait: 5)
|
||||||
sign_button = find('.js-securitySign', wait: 5)
|
sign_button = find('.js-securitySign', wait: 5)
|
||||||
|
|
||||||
await_empty_ajax_queue
|
|
||||||
|
|
||||||
active_button_class = '.btn--active'
|
active_button_class = '.btn--active'
|
||||||
expect(encrypt_button.matches_css?(active_button_class, wait: 2)).to be(encrypt)
|
expect(encrypt_button.matches_css?(active_button_class, wait: 2)).to be(encrypt)
|
||||||
expect(sign_button.matches_css?(active_button_class, wait: 2)).to be(sign)
|
expect(sign_button.matches_css?(active_button_class, wait: 2)).to be(sign)
|
||||||
|
@ -234,8 +232,6 @@ RSpec.describe 'Ticket Create', type: :system do
|
||||||
within(:active_content) do
|
within(:active_content) do
|
||||||
use_template(template)
|
use_template(template)
|
||||||
|
|
||||||
await_empty_ajax_queue
|
|
||||||
|
|
||||||
select new_group.name, from: 'group_id'
|
select new_group.name, from: 'group_id'
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -378,7 +374,6 @@ RSpec.describe 'Ticket Create', type: :system do
|
||||||
click_on 'Link issue'
|
click_on 'Link issue'
|
||||||
fill_in 'link', with: ENV['GITLAB_ISSUE_LINK']
|
fill_in 'link', with: ENV['GITLAB_ISSUE_LINK']
|
||||||
click_on 'Submit'
|
click_on 'Submit'
|
||||||
await_empty_ajax_queue
|
|
||||||
|
|
||||||
# verify issue
|
# verify issue
|
||||||
content = find('.sidebar-git-issue-content')
|
content = find('.sidebar-git-issue-content')
|
||||||
|
@ -390,7 +385,6 @@ RSpec.describe 'Ticket Create', type: :system do
|
||||||
|
|
||||||
# create Ticket
|
# create Ticket
|
||||||
click '.js-submit'
|
click '.js-submit'
|
||||||
await_empty_ajax_queue
|
|
||||||
|
|
||||||
# check stored data
|
# check stored data
|
||||||
expect(Ticket.last.preferences[:gitlab][:issue_links][0]).to eq(ENV['GITLAB_ISSUE_LINK'])
|
expect(Ticket.last.preferences[:gitlab][:issue_links][0]).to eq(ENV['GITLAB_ISSUE_LINK'])
|
||||||
|
@ -432,7 +426,6 @@ RSpec.describe 'Ticket Create', type: :system do
|
||||||
click_on 'Link issue'
|
click_on 'Link issue'
|
||||||
fill_in 'link', with: ENV['GITHUB_ISSUE_LINK']
|
fill_in 'link', with: ENV['GITHUB_ISSUE_LINK']
|
||||||
click_on 'Submit'
|
click_on 'Submit'
|
||||||
await_empty_ajax_queue
|
|
||||||
|
|
||||||
# verify issue
|
# verify issue
|
||||||
content = find('.sidebar-git-issue-content')
|
content = find('.sidebar-git-issue-content')
|
||||||
|
@ -444,7 +437,6 @@ RSpec.describe 'Ticket Create', type: :system do
|
||||||
|
|
||||||
# create Ticket
|
# create Ticket
|
||||||
click '.js-submit'
|
click '.js-submit'
|
||||||
await_empty_ajax_queue
|
|
||||||
|
|
||||||
# check stored data
|
# check stored data
|
||||||
expect(Ticket.last.preferences[:github][:issue_links][0]).to eq(ENV['GITHUB_ISSUE_LINK'])
|
expect(Ticket.last.preferences[:github][:issue_links][0]).to eq(ENV['GITHUB_ISSUE_LINK'])
|
||||||
|
|
|
@ -35,7 +35,7 @@ RSpec.describe 'Ticket Update', type: :system do
|
||||||
|
|
||||||
select('closed', from: 'state_id')
|
select('closed', from: 'state_id')
|
||||||
click('.js-attributeBar .js-submit')
|
click('.js-attributeBar .js-submit')
|
||||||
expect(page).to have_no_css('.js-submitDropdown .js-submit[disabled]', wait: 2)
|
expect(page).to have_no_css('.js-submitDropdown .js-submit[disabled]', wait: 10)
|
||||||
end
|
end
|
||||||
|
|
||||||
# the update should have failed and thus the ticket is still in the new state
|
# the update should have failed and thus the ticket is still in the new state
|
||||||
|
@ -45,7 +45,7 @@ RSpec.describe 'Ticket Update', type: :system do
|
||||||
# update should work now
|
# update should work now
|
||||||
find(".edit [name=#{attribute.name}]").select('name 2')
|
find(".edit [name=#{attribute.name}]").select('name 2')
|
||||||
click('.js-attributeBar .js-submit')
|
click('.js-attributeBar .js-submit')
|
||||||
expect(page).to have_no_css('.js-submitDropdown .js-submit[disabled]', wait: 2)
|
expect(page).to have_no_css('.js-submitDropdown .js-submit[disabled]', wait: 10)
|
||||||
end
|
end
|
||||||
|
|
||||||
ticket.reload
|
ticket.reload
|
||||||
|
@ -185,7 +185,7 @@ RSpec.describe 'Ticket Update', type: :system do
|
||||||
it 'tickets history of both tickets should show the merge event' do
|
it 'tickets history of both tickets should show the merge event' do
|
||||||
visit "#ticket/zoom/#{origin_ticket.id}"
|
visit "#ticket/zoom/#{origin_ticket.id}"
|
||||||
within(:active_content) do
|
within(:active_content) do
|
||||||
expect(page).to have_css('.js-actions .dropdown-toggle', wait: 3)
|
expect(page).to have_css('.js-actions .dropdown-toggle', wait: 10)
|
||||||
click '.js-actions .dropdown-toggle'
|
click '.js-actions .dropdown-toggle'
|
||||||
click '.js-actions .dropdown-menu [data-type="ticket-history"]'
|
click '.js-actions .dropdown-menu [data-type="ticket-history"]'
|
||||||
|
|
||||||
|
|
|
@ -112,9 +112,9 @@ RSpec.describe 'Ticket views', type: :system do
|
||||||
|
|
||||||
release_mouse
|
release_mouse
|
||||||
|
|
||||||
await_empty_ajax_queue
|
expect do
|
||||||
|
wait(10, interval: 0.1).until { Ticket.first.articles.last.subject == 'macro note' }
|
||||||
expect(Ticket.first.articles.last.subject).to eq('macro note')
|
end.not_to raise_error
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -136,12 +136,9 @@ RSpec.describe 'Ticket views', type: :system do
|
||||||
click '.js-submit'
|
click '.js-submit'
|
||||||
end
|
end
|
||||||
|
|
||||||
await_empty_ajax_queue
|
expect do
|
||||||
|
wait(10, interval: 0.1).until { [ ticket1.articles.last&.body, ticket2.articles.last&.body ] == [note, note] }
|
||||||
expect([
|
end.not_to raise_error
|
||||||
ticket1.articles.last&.body,
|
|
||||||
ticket2.articles.last&.body
|
|
||||||
]).to be_all note
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -184,9 +181,9 @@ RSpec.describe 'Ticket views', type: :system do
|
||||||
|
|
||||||
it 'does basic view test of tickets' do
|
it 'does basic view test of tickets' do
|
||||||
visit 'ticket/view/my_tickets'
|
visit 'ticket/view/my_tickets'
|
||||||
expect(page).to have_text(ticket.title)
|
expect(page).to have_text(ticket.title, wait: 10)
|
||||||
click_on 'My Organization Tickets'
|
click_on 'My Organization Tickets'
|
||||||
expect(page).to have_text(ticket.title)
|
expect(page).to have_text(ticket.title, wait: 10)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -448,7 +448,7 @@ RSpec.describe 'Ticket zoom', type: :system do
|
||||||
end
|
end
|
||||||
|
|
||||||
context 'button is hidden on the go' do
|
context 'button is hidden on the go' do
|
||||||
let(:setting_delete_timeframe) { 5 }
|
let(:setting_delete_timeframe) { 10 }
|
||||||
|
|
||||||
let(:user) { agent }
|
let(:user) { agent }
|
||||||
let(:item) { 'article_note_self' }
|
let(:item) { 'article_note_self' }
|
||||||
|
@ -692,8 +692,6 @@ RSpec.describe 'Ticket zoom', type: :system do
|
||||||
encrypt_button = find('.js-securityEncrypt', wait: 5)
|
encrypt_button = find('.js-securityEncrypt', wait: 5)
|
||||||
sign_button = find('.js-securitySign', wait: 5)
|
sign_button = find('.js-securitySign', wait: 5)
|
||||||
|
|
||||||
await_empty_ajax_queue
|
|
||||||
|
|
||||||
active_button_class = '.btn--active'
|
active_button_class = '.btn--active'
|
||||||
expect(encrypt_button.matches_css?(active_button_class, wait: 2)).to be(encrypt)
|
expect(encrypt_button.matches_css?(active_button_class, wait: 2)).to be(encrypt)
|
||||||
expect(sign_button.matches_css?(active_button_class, wait: 2)).to be(sign)
|
expect(sign_button.matches_css?(active_button_class, wait: 2)).to be(sign)
|
||||||
|
@ -709,8 +707,6 @@ RSpec.describe 'Ticket zoom', type: :system do
|
||||||
within(:active_content) do
|
within(:active_content) do
|
||||||
all('a[data-type=emailReply]').last.click
|
all('a[data-type=emailReply]').last.click
|
||||||
find('.articleNewEdit-body').send_keys('Test')
|
find('.articleNewEdit-body').send_keys('Test')
|
||||||
|
|
||||||
await_empty_ajax_queue
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -726,8 +722,6 @@ RSpec.describe 'Ticket zoom', type: :system do
|
||||||
all('a[data-type=emailReply]').last.click
|
all('a[data-type=emailReply]').last.click
|
||||||
find('.articleNewEdit-body').send_keys('Test')
|
find('.articleNewEdit-body').send_keys('Test')
|
||||||
|
|
||||||
await_empty_ajax_queue
|
|
||||||
|
|
||||||
select new_group.name, from: 'group_id'
|
select new_group.name, from: 'group_id'
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -883,8 +877,6 @@ RSpec.describe 'Ticket zoom', type: :system do
|
||||||
find(:richtext).execute_script "this.innerHTML = \"#{ticket_article_body}\""
|
find(:richtext).execute_script "this.innerHTML = \"#{ticket_article_body}\""
|
||||||
find('.js-submit').click
|
find('.js-submit').click
|
||||||
end
|
end
|
||||||
|
|
||||||
await_empty_ajax_queue
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def forward
|
def forward
|
||||||
|
@ -893,8 +885,6 @@ RSpec.describe 'Ticket zoom', type: :system do
|
||||||
fill_in 'To', with: 'customer@example.com'
|
fill_in 'To', with: 'customer@example.com'
|
||||||
find('.js-submit').click
|
find('.js-submit').click
|
||||||
end
|
end
|
||||||
|
|
||||||
await_empty_ajax_queue
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def images_identical?(image_a, image_b)
|
def images_identical?(image_a, image_b)
|
||||||
|
@ -986,7 +976,7 @@ RSpec.describe 'Ticket zoom', type: :system do
|
||||||
visit "ticket/zoom/#{ticket.id}"
|
visit "ticket/zoom/#{ticket.id}"
|
||||||
refresh # refresh to have assets generated for ticket
|
refresh # refresh to have assets generated for ticket
|
||||||
|
|
||||||
expect(page).to have_select('state_id', options: %w[new open closed])
|
expect(page).to have_select('state_id', options: %w[new open closed], wait: 10)
|
||||||
expect(page).to have_no_select('priority_id')
|
expect(page).to have_no_select('priority_id')
|
||||||
expect(page).to have_no_select('owner_id')
|
expect(page).to have_no_select('owner_id')
|
||||||
expect(page).to have_no_css('div.tabsSidebar-tab[data-tab=customer]')
|
expect(page).to have_no_css('div.tabsSidebar-tab[data-tab=customer]')
|
||||||
|
@ -1119,11 +1109,10 @@ RSpec.describe 'Ticket zoom', type: :system do
|
||||||
|
|
||||||
# make sure ticket is done loading and change will be pushed via WS
|
# make sure ticket is done loading and change will be pushed via WS
|
||||||
find(:active_ticket_article, ticket_article)
|
find(:active_ticket_article, ticket_article)
|
||||||
await_empty_ajax_queue
|
|
||||||
|
|
||||||
ticket_note.update!(internal: false)
|
ticket_note.update!(internal: false)
|
||||||
|
|
||||||
expect(page).to have_selector(:active_ticket_article, ticket_note)
|
expect(page).to have_selector(:active_ticket_article, ticket_note, wait: 10)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -1190,37 +1179,37 @@ RSpec.describe 'Ticket zoom', type: :system do
|
||||||
it 'previous is not clickable for the first item' do
|
it 'previous is not clickable for the first item' do
|
||||||
open_nth_item(0)
|
open_nth_item(0)
|
||||||
|
|
||||||
expect { click '.pagination .previous' }.not_to change { current_url }
|
expect { click '.pagination .previous' }.not_to change { page.find('.content.active')[:id] }
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'next is clickable for the first item' do
|
it 'next is clickable for the first item' do
|
||||||
open_nth_item(0)
|
open_nth_item(0)
|
||||||
|
|
||||||
expect { click '.pagination .next' }.to change { current_url }
|
expect { click '.pagination .next' }.to change { page.find('.content.active')[:id] }
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'previous is clickable for the middle item' do
|
it 'previous is clickable for the middle item' do
|
||||||
open_nth_item(1)
|
open_nth_item(1)
|
||||||
|
|
||||||
expect { click '.pagination .previous' }.to change { current_url }
|
expect { click '.pagination .previous' }.to change { page.find('.content.active')[:id] }
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'next is clickable for the middle item' do
|
it 'next is clickable for the middle item' do
|
||||||
open_nth_item(1)
|
open_nth_item(1)
|
||||||
|
|
||||||
expect { click '.pagination .next' }.to change { current_url }
|
expect { click '.pagination .next' }.to change { page.find('.content.active')[:id] }
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'previous is clickable for the last item' do
|
it 'previous is clickable for the last item' do
|
||||||
open_nth_item(2)
|
open_nth_item(2)
|
||||||
|
|
||||||
expect { click '.pagination .previous' }.to change { current_url }
|
expect { click '.pagination .previous' }.to change { page.find('.content.active')[:id] }
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'next is not clickable for the last item' do
|
it 'next is not clickable for the last item' do
|
||||||
open_nth_item(2)
|
open_nth_item(2)
|
||||||
|
|
||||||
expect { click '.pagination .next' }.not_to change { current_url }
|
expect { click '.pagination .next' }.not_to change { page.find('.content.active')[:id] }
|
||||||
end
|
end
|
||||||
|
|
||||||
def open_nth_item(nth)
|
def open_nth_item(nth)
|
||||||
|
@ -1243,8 +1232,6 @@ RSpec.describe 'Ticket zoom', type: :system do
|
||||||
|
|
||||||
visit "ticket/zoom/#{ticket_a.id}"
|
visit "ticket/zoom/#{ticket_a.id}"
|
||||||
|
|
||||||
await_empty_ajax_queue
|
|
||||||
|
|
||||||
visit 'ticket/view/all_unassigned'
|
visit 'ticket/view/all_unassigned'
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -1252,7 +1239,7 @@ RSpec.describe 'Ticket zoom', type: :system do
|
||||||
within :active_content do
|
within :active_content do
|
||||||
click_on ticket_a.title
|
click_on ticket_a.title
|
||||||
|
|
||||||
expect(page).to have_css('.pagination-counter')
|
expect(page).to have_css('.pagination-counter', wait: 10)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -1262,7 +1249,7 @@ RSpec.describe 'Ticket zoom', type: :system do
|
||||||
visit 'dashboard'
|
visit 'dashboard'
|
||||||
visit "ticket/zoom/#{ticket_a.id}"
|
visit "ticket/zoom/#{ticket_a.id}"
|
||||||
|
|
||||||
expect(page).to have_css('.pagination-counter')
|
expect(page).to have_css('.pagination-counter', wait: 10)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -1293,7 +1280,6 @@ RSpec.describe 'Ticket zoom', type: :system do
|
||||||
|
|
||||||
# wait for article to be added to the page
|
# wait for article to be added to the page
|
||||||
expect(page).to have_css('.ticket-article-item', count: 1)
|
expect(page).to have_css('.ticket-article-item', count: 1)
|
||||||
await_empty_ajax_queue
|
|
||||||
|
|
||||||
# create a on-the-fly article with attachment that will get pushed to open browser
|
# create a on-the-fly article with attachment that will get pushed to open browser
|
||||||
article1 = create(:ticket_article, ticket: ticket)
|
article1 = create(:ticket_article, ticket: ticket)
|
||||||
|
@ -1310,7 +1296,6 @@ RSpec.describe 'Ticket zoom', type: :system do
|
||||||
|
|
||||||
# wait for article to be added to the page
|
# wait for article to be added to the page
|
||||||
expect(page).to have_css('.ticket-article-item', count: 2, wait: 10)
|
expect(page).to have_css('.ticket-article-item', count: 2, wait: 10)
|
||||||
await_empty_ajax_queue
|
|
||||||
|
|
||||||
# click on forward of created article
|
# click on forward of created article
|
||||||
within :active_ticket_article, article1 do
|
within :active_ticket_article, article1 do
|
||||||
|
@ -1327,7 +1312,6 @@ RSpec.describe 'Ticket zoom', type: :system do
|
||||||
click '.js-submit'
|
click '.js-submit'
|
||||||
|
|
||||||
# wait for article to be added to the page
|
# wait for article to be added to the page
|
||||||
await_empty_ajax_queue
|
|
||||||
expect(page).to have_css('.ticket-article-item', count: 3)
|
expect(page).to have_css('.ticket-article-item', count: 3)
|
||||||
|
|
||||||
# check if attachment was forwarded successfully
|
# check if attachment was forwarded successfully
|
||||||
|
@ -1376,7 +1360,6 @@ RSpec.describe 'Ticket zoom', type: :system do
|
||||||
|
|
||||||
it 'not shown to customer' do
|
it 'not shown to customer' do
|
||||||
visit "ticket/zoom/#{ticket.id}"
|
visit "ticket/zoom/#{ticket.id}"
|
||||||
await_empty_ajax_queue
|
|
||||||
|
|
||||||
within :active_content do
|
within :active_content do
|
||||||
expect(page).to have_no_css('.controls[data-name=pending_time]')
|
expect(page).to have_no_css('.controls[data-name=pending_time]')
|
||||||
|
@ -1389,7 +1372,6 @@ RSpec.describe 'Ticket zoom', type: :system do
|
||||||
ticket.update(pending_time: 1.day.from_now, state: Ticket::State.lookup(name: 'pending reminder'))
|
ticket.update(pending_time: 1.day.from_now, state: Ticket::State.lookup(name: 'pending reminder'))
|
||||||
|
|
||||||
visit "ticket/zoom/#{ticket.id}"
|
visit "ticket/zoom/#{ticket.id}"
|
||||||
await_empty_ajax_queue
|
|
||||||
end
|
end
|
||||||
|
|
||||||
let(:ticket) { Ticket.first }
|
let(:ticket) { Ticket.first }
|
||||||
|
@ -1436,7 +1418,6 @@ RSpec.describe 'Ticket zoom', type: :system do
|
||||||
|
|
||||||
ensure_websocket do
|
ensure_websocket do
|
||||||
visit "ticket/zoom/#{ticket.id}"
|
visit "ticket/zoom/#{ticket.id}"
|
||||||
await_empty_ajax_queue
|
|
||||||
|
|
||||||
within :active_ticket_article, article do
|
within :active_ticket_article, article do
|
||||||
expect(page).to have_css(%(a[href="#{url}"]))
|
expect(page).to have_css(%(a[href="#{url}"]))
|
||||||
|
@ -1457,44 +1438,33 @@ RSpec.describe 'Ticket zoom', type: :system do
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def check_obscured(top: true, middle: true, bottom: true, scroll_y: 0)
|
||||||
|
expect(page).to have_text(ticket.title, wait: 10)
|
||||||
|
wait(5, interval: 0.2).until do
|
||||||
|
scroll_y != find('.ticketZoom').native.location.y
|
||||||
|
end
|
||||||
|
expect(page).to have_css("div#article-content-#{article_at_the_top.id}", obscured: top, wait: 10)
|
||||||
|
expect(page).to have_css("div#article-content-#{article_in_the_middle.id}", obscured: middle, wait: 10)
|
||||||
|
expect(page).to have_css("div#article-content-#{article_at_the_bottom.id}", obscured: bottom, wait: 10)
|
||||||
|
find('.ticketZoom').native.location.y
|
||||||
|
end
|
||||||
|
|
||||||
it 'scrolls to given Article ID' do
|
it 'scrolls to given Article ID' do
|
||||||
ensure_websocket do
|
ensure_websocket do
|
||||||
visit "ticket/zoom/#{ticket.id}/#{article_in_the_middle.id}"
|
visit "ticket/zoom/#{ticket.id}"
|
||||||
await_empty_ajax_queue
|
y = check_obscured(bottom: false)
|
||||||
# workaround because browser scrolls in test initially to the bottom
|
|
||||||
# maybe because the articles are not present?!
|
|
||||||
refresh
|
|
||||||
|
|
||||||
# scroll to article in the middle of the page
|
# scroll to article in the middle of the page
|
||||||
within :active_content do
|
visit "ticket/zoom/#{ticket.id}/#{article_in_the_middle.id}"
|
||||||
find("div#article-content-#{article_in_the_middle.id}").in_fixed_position(wait: 0.5)
|
y = check_obscured(middle: false, scroll_y: y)
|
||||||
|
|
||||||
expect(find("div#article-content-#{article_at_the_top.id}")).to be_obscured
|
|
||||||
expect(find("div#article-content-#{article_in_the_middle.id}")).not_to be_obscured
|
|
||||||
expect(find("div#article-content-#{article_at_the_bottom.id}")).to be_obscured
|
|
||||||
end
|
|
||||||
|
|
||||||
# scroll to article at the top of the page
|
# scroll to article at the top of the page
|
||||||
visit "ticket/zoom/#{ticket.id}/#{article_at_the_top.id}"
|
visit "ticket/zoom/#{ticket.id}/#{article_at_the_top.id}"
|
||||||
await_empty_ajax_queue
|
y = check_obscured(top: false, scroll_y: y)
|
||||||
within :active_content do
|
|
||||||
find("div#article-content-#{article_in_the_middle.id}").in_fixed_position(wait: 0.5)
|
|
||||||
|
|
||||||
expect(find("div#article-content-#{article_at_the_top.id}")).not_to be_obscured
|
|
||||||
expect(find("div#article-content-#{article_in_the_middle.id}")).to be_obscured
|
|
||||||
expect(find("div#article-content-#{article_at_the_bottom.id}")).to be_obscured
|
|
||||||
end
|
|
||||||
|
|
||||||
# scroll to article at the bottom of the page
|
# scroll to article at the bottom of the page
|
||||||
visit "ticket/zoom/#{ticket.id}/#{article_at_the_bottom.id}"
|
visit "ticket/zoom/#{ticket.id}/#{article_at_the_bottom.id}"
|
||||||
await_empty_ajax_queue
|
check_obscured(bottom: false, scroll_y: y)
|
||||||
within :active_content do
|
|
||||||
find("div#article-content-#{article_in_the_middle.id}").in_fixed_position(wait: 0.5)
|
|
||||||
|
|
||||||
expect(find("div#article-content-#{article_at_the_top.id}")).to be_obscured
|
|
||||||
expect(find("div#article-content-#{article_in_the_middle.id}")).to be_obscured
|
|
||||||
expect(find("div#article-content-#{article_at_the_bottom.id}")).not_to be_obscured
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -1503,12 +1473,11 @@ RSpec.describe 'Ticket zoom', type: :system do
|
||||||
it 'will properly show the "See more" link if you switch between the ticket and the dashboard on new articles' do
|
it 'will properly show the "See more" link if you switch between the ticket and the dashboard on new articles' do
|
||||||
ensure_websocket do
|
ensure_websocket do
|
||||||
visit "ticket/zoom/#{ticket.id}"
|
visit "ticket/zoom/#{ticket.id}"
|
||||||
await_empty_ajax_queue
|
|
||||||
|
|
||||||
visit 'dashboard'
|
visit 'dashboard'
|
||||||
expect(page).to have_css("a.js-dashboardMenuItem[data-key='Dashboard'].is-active", wait: 10)
|
expect(page).to have_css("a.js-dashboardMenuItem[data-key='Dashboard'].is-active", wait: 10)
|
||||||
article_id = create(:'ticket/article', ticket: ticket, body: "#{SecureRandom.uuid} #{"lorem ipsum\n" * 200}")
|
article_id = create(:'ticket/article', ticket: ticket, body: "#{SecureRandom.uuid} #{"lorem ipsum\n" * 200}")
|
||||||
expect(page).to have_css('div.tasks a.is-modified', wait: 10)
|
expect(page).to have_css('div.tasks a.is-modified', wait: 30)
|
||||||
|
|
||||||
visit "ticket/zoom/#{ticket.id}"
|
visit "ticket/zoom/#{ticket.id}"
|
||||||
within :active_content do
|
within :active_content do
|
||||||
|
@ -1533,7 +1502,6 @@ RSpec.describe 'Ticket zoom', type: :system do
|
||||||
visit "ticket/zoom/#{ticket.id}"
|
visit "ticket/zoom/#{ticket.id}"
|
||||||
find('.js-openDropdownMacro').click
|
find('.js-openDropdownMacro').click
|
||||||
find(:macro, macro.id).click
|
find(:macro, macro.id).click
|
||||||
await_empty_ajax_queue
|
|
||||||
|
|
||||||
expect(ticket.reload.articles.last.body).to eq(macro_body)
|
expect(ticket.reload.articles.last.body).to eq(macro_body)
|
||||||
expect(ticket.reload.articles.last.content_type).to eq('text/html')
|
expect(ticket.reload.articles.last.content_type).to eq('text/html')
|
||||||
|
@ -1598,7 +1566,6 @@ RSpec.describe 'Ticket zoom', type: :system do
|
||||||
click_on 'Link issue'
|
click_on 'Link issue'
|
||||||
fill_in 'link', with: ENV['GITLAB_ISSUE_LINK']
|
fill_in 'link', with: ENV['GITLAB_ISSUE_LINK']
|
||||||
click_on 'Submit'
|
click_on 'Submit'
|
||||||
await_empty_ajax_queue
|
|
||||||
|
|
||||||
# verify issue
|
# verify issue
|
||||||
content = find('.sidebar-git-issue-content')
|
content = find('.sidebar-git-issue-content')
|
||||||
|
@ -1615,7 +1582,6 @@ RSpec.describe 'Ticket zoom', type: :system do
|
||||||
|
|
||||||
# delete issue
|
# delete issue
|
||||||
click(".sidebar-git-issue-delete span[data-issue-id='#{ENV['GITLAB_ISSUE_LINK']}']")
|
click(".sidebar-git-issue-delete span[data-issue-id='#{ENV['GITLAB_ISSUE_LINK']}']")
|
||||||
await_empty_ajax_queue
|
|
||||||
|
|
||||||
content = find('.sidebar[data-tab=gitlab] .sidebar-content')
|
content = find('.sidebar[data-tab=gitlab] .sidebar-content')
|
||||||
expect(content).to have_text('No linked issues')
|
expect(content).to have_text('No linked issues')
|
||||||
|
@ -1658,7 +1624,6 @@ RSpec.describe 'Ticket zoom', type: :system do
|
||||||
click_on 'Link issue'
|
click_on 'Link issue'
|
||||||
fill_in 'link', with: ENV['GITHUB_ISSUE_LINK']
|
fill_in 'link', with: ENV['GITHUB_ISSUE_LINK']
|
||||||
click_on 'Submit'
|
click_on 'Submit'
|
||||||
await_empty_ajax_queue
|
|
||||||
|
|
||||||
# verify issue
|
# verify issue
|
||||||
content = find('.sidebar-git-issue-content')
|
content = find('.sidebar-git-issue-content')
|
||||||
|
@ -1675,7 +1640,6 @@ RSpec.describe 'Ticket zoom', type: :system do
|
||||||
|
|
||||||
# delete issue
|
# delete issue
|
||||||
click(".sidebar-git-issue-delete span[data-issue-id='#{ENV['GITHUB_ISSUE_LINK']}']")
|
click(".sidebar-git-issue-delete span[data-issue-id='#{ENV['GITHUB_ISSUE_LINK']}']")
|
||||||
await_empty_ajax_queue
|
|
||||||
|
|
||||||
content = find('.sidebar[data-tab=github] .sidebar-content')
|
content = find('.sidebar[data-tab=github] .sidebar-content')
|
||||||
expect(content).to have_text('No linked issues')
|
expect(content).to have_text('No linked issues')
|
||||||
|
@ -1707,7 +1671,6 @@ RSpec.describe 'Ticket zoom', type: :system do
|
||||||
expect(page).to have_text(ticket_open.title, wait: 20)
|
expect(page).to have_text(ticket_open.title, wait: 20)
|
||||||
|
|
||||||
visit "#ticket/zoom/#{ticket_open.id}"
|
visit "#ticket/zoom/#{ticket_open.id}"
|
||||||
click '.tabsSidebar-tab[data-tab=customer]'
|
|
||||||
click '.user-tickets[data-type=closed]'
|
click '.user-tickets[data-type=closed]'
|
||||||
expect(page).to have_text(ticket_closed.title, wait: 20)
|
expect(page).to have_text(ticket_closed.title, wait: 20)
|
||||||
end
|
end
|
||||||
|
|
|
@ -159,7 +159,7 @@ class AgentTicketActionLevel0Test < TestCase
|
||||||
css: '.newTicket',
|
css: '.newTicket',
|
||||||
value: 'New Ticket',
|
value: 'New Ticket',
|
||||||
)
|
)
|
||||||
exists_not(css: '.newTicket select[name="group_id"]')
|
exists(css: '.newTicket .form-group.hide select[name="group_id"]')
|
||||||
|
|
||||||
set(
|
set(
|
||||||
css: '.newTicket input[name="title"]',
|
css: '.newTicket input[name="title"]',
|
||||||
|
|
|
@ -30,14 +30,7 @@ class AgentTicketAttachmentTest < TestCase
|
||||||
sleep 1
|
sleep 1
|
||||||
|
|
||||||
# submit form
|
# submit form
|
||||||
click(css: '.content.active .js-submit')
|
click(css: '.content.active .js-submit', expect_alert: true)
|
||||||
sleep 2
|
|
||||||
|
|
||||||
# check warning
|
|
||||||
alert = @browser.switch_to.alert
|
|
||||||
alert.dismiss()
|
|
||||||
#alert.accept()
|
|
||||||
#alert = alert.text
|
|
||||||
|
|
||||||
# since selenium webdriver with firefox is not able to upload files, skipp here
|
# since selenium webdriver with firefox is not able to upload files, skipp here
|
||||||
# https://github.com/w3c/webdriver/issues/1230
|
# https://github.com/w3c/webdriver/issues/1230
|
||||||
|
@ -90,12 +83,7 @@ class AgentTicketAttachmentTest < TestCase
|
||||||
)
|
)
|
||||||
|
|
||||||
# submit form
|
# submit form
|
||||||
click(css: '.content.active .js-submit')
|
click(css: '.content.active .js-submit', expect_alert: true)
|
||||||
sleep 2
|
|
||||||
|
|
||||||
# check warning
|
|
||||||
alert = @browser.switch_to.alert
|
|
||||||
alert.dismiss()
|
|
||||||
|
|
||||||
# add attachment, attachment check should quiet
|
# add attachment, attachment check should quiet
|
||||||
file_upload(
|
file_upload(
|
||||||
|
@ -111,12 +99,6 @@ class AgentTicketAttachmentTest < TestCase
|
||||||
|
|
||||||
# submit form
|
# submit form
|
||||||
click(css: '.content.active .js-submit')
|
click(css: '.content.active .js-submit')
|
||||||
sleep 2
|
|
||||||
|
|
||||||
# no warning
|
|
||||||
#alert = @browser.switch_to.alert
|
|
||||||
|
|
||||||
# check if article exists
|
|
||||||
|
|
||||||
# discard changes should gone away
|
# discard changes should gone away
|
||||||
watch_for_disappear(
|
watch_for_disappear(
|
||||||
|
|
|
@ -160,7 +160,12 @@ class AgentTicketMacroTest < TestCase
|
||||||
# when we re-enter the Zoom view for a ticket via the overview
|
# when we re-enter the Zoom view for a ticket via the overview
|
||||||
tasks_close_all()
|
tasks_close_all()
|
||||||
|
|
||||||
sleep 8 # to update overview list to open correct/next ticket in overview
|
overview_open(
|
||||||
|
link: '#ticket/view/all_unassigned',
|
||||||
|
)
|
||||||
|
|
||||||
|
await_text(text: ticket1[:title])
|
||||||
|
await_text(text: ticket2[:title])
|
||||||
|
|
||||||
ticket_open_by_overview(
|
ticket_open_by_overview(
|
||||||
title: ticket1[:title],
|
title: ticket1[:title],
|
||||||
|
|
|
@ -67,6 +67,9 @@ class AgentTicketOverviewLevel0Test < TestCase
|
||||||
css: %(.content.active table tr td input[value="#{ticket2[:id]}"][type="checkbox"]:checked),
|
css: %(.content.active table tr td input[value="#{ticket2[:id]}"][type="checkbox"]:checked),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
# remember current overview count
|
||||||
|
overview_counter_before = overview_counter()
|
||||||
|
|
||||||
# select close state & submit
|
# select close state & submit
|
||||||
select(
|
select(
|
||||||
css: '.content.active .bulkAction [name="state_id"]',
|
css: '.content.active .bulkAction [name="state_id"]',
|
||||||
|
@ -92,6 +95,7 @@ class AgentTicketOverviewLevel0Test < TestCase
|
||||||
)
|
)
|
||||||
|
|
||||||
# remember current overview count
|
# remember current overview count
|
||||||
|
await_overview_counter(view: '#ticket/view/all_unassigned', count: overview_counter_before['#ticket/view/all_unassigned'] - 2)
|
||||||
overview_counter_before = overview_counter()
|
overview_counter_before = overview_counter()
|
||||||
|
|
||||||
# click options and enable number and article count
|
# click options and enable number and article count
|
||||||
|
@ -188,11 +192,9 @@ class AgentTicketOverviewLevel0Test < TestCase
|
||||||
body: 'overview count test #3',
|
body: 'overview count test #3',
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
sleep 6
|
|
||||||
|
|
||||||
# get new overview count
|
# get new overview count
|
||||||
overview_counter_new = overview_counter()
|
await_overview_counter(view: '#ticket/view/all_unassigned', count: overview_counter_before['#ticket/view/all_unassigned'] + 1)
|
||||||
assert_equal(overview_counter_before['#ticket/view/all_unassigned'] + 1, overview_counter_new['#ticket/view/all_unassigned'])
|
|
||||||
|
|
||||||
# open ticket by search
|
# open ticket by search
|
||||||
ticket_open_by_search(
|
ticket_open_by_search(
|
||||||
|
@ -206,11 +208,9 @@ class AgentTicketOverviewLevel0Test < TestCase
|
||||||
state: 'closed',
|
state: 'closed',
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
sleep 6
|
|
||||||
|
|
||||||
# get current overview count
|
# get current overview count
|
||||||
overview_counter_after = overview_counter()
|
await_overview_counter(view: '#ticket/view/all_unassigned', count: overview_counter_before['#ticket/view/all_unassigned'])
|
||||||
assert_equal(overview_counter_before['#ticket/view/all_unassigned'], overview_counter_after['#ticket/view/all_unassigned'])
|
|
||||||
|
|
||||||
# cleanup
|
# cleanup
|
||||||
tasks_close_all()
|
tasks_close_all()
|
||||||
|
@ -334,8 +334,7 @@ class AgentTicketOverviewLevel0Test < TestCase
|
||||||
)
|
)
|
||||||
|
|
||||||
# get new overview count
|
# get new overview count
|
||||||
overview_counter_new = overview_counter()
|
await_overview_counter(view: '#ticket/view/all_unassigned', count: overview_counter_before['#ticket/view/all_unassigned'] - 2)
|
||||||
assert_equal(overview_counter_before['#ticket/view/all_unassigned'] - 2, overview_counter_new['#ticket/view/all_unassigned'])
|
|
||||||
|
|
||||||
# open ticket by search
|
# open ticket by search
|
||||||
ticket_open_by_search(
|
ticket_open_by_search(
|
||||||
|
@ -463,8 +462,7 @@ class AgentTicketOverviewLevel0Test < TestCase
|
||||||
)
|
)
|
||||||
|
|
||||||
# get new overview count
|
# get new overview count
|
||||||
overview_counter_new = overview_counter()
|
await_overview_counter(view: '#ticket/view/all_unassigned', count: overview_counter_before['#ticket/view/all_unassigned'] - 2)
|
||||||
assert_equal(overview_counter_before['#ticket/view/all_unassigned'] - 2, overview_counter_new['#ticket/view/all_unassigned'])
|
|
||||||
|
|
||||||
# cleanup
|
# cleanup
|
||||||
tasks_close_all()
|
tasks_close_all()
|
||||||
|
|
|
@ -3,6 +3,20 @@
|
||||||
require 'browser_test_helper'
|
require 'browser_test_helper'
|
||||||
|
|
||||||
class AgentTicketOverviewTabTest < TestCase
|
class AgentTicketOverviewTabTest < TestCase
|
||||||
|
def task_count_equals(count)
|
||||||
|
|
||||||
|
retries ||= 0
|
||||||
|
assert_equal(count, @browser.find_elements(css: '.tasks .task').count)
|
||||||
|
rescue
|
||||||
|
retries += 1
|
||||||
|
if retries < 5
|
||||||
|
sleep 1
|
||||||
|
retry
|
||||||
|
end
|
||||||
|
raise e
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
def test_i
|
def test_i
|
||||||
@browser = browser_instance
|
@browser = browser_instance
|
||||||
login(
|
login(
|
||||||
|
@ -54,7 +68,7 @@ class AgentTicketOverviewTabTest < TestCase
|
||||||
link: '#ticket/view/all_unassigned',
|
link: '#ticket/view/all_unassigned',
|
||||||
)
|
)
|
||||||
|
|
||||||
assert_equal(1, @browser.find_elements(css: '.tasks .task').count)
|
task_count_equals(1)
|
||||||
|
|
||||||
ticket_update(
|
ticket_update(
|
||||||
data: {
|
data: {
|
||||||
|
@ -70,7 +84,7 @@ class AgentTicketOverviewTabTest < TestCase
|
||||||
timeout: 8,
|
timeout: 8,
|
||||||
)
|
)
|
||||||
|
|
||||||
assert_equal(1, @browser.find_elements(css: '.tasks .task').count)
|
task_count_equals(1)
|
||||||
|
|
||||||
ticket_update(
|
ticket_update(
|
||||||
data: {
|
data: {
|
||||||
|
@ -80,7 +94,7 @@ class AgentTicketOverviewTabTest < TestCase
|
||||||
task_type: 'closeTab', # default: stayOnTab / possible: closeTab, closeNextInOverview, stayOnTab
|
task_type: 'closeTab', # default: stayOnTab / possible: closeTab, closeNextInOverview, stayOnTab
|
||||||
)
|
)
|
||||||
|
|
||||||
assert_equal(0, @browser.find_elements(css: '.tasks .task').count)
|
task_count_equals(0)
|
||||||
|
|
||||||
# cleanup
|
# cleanup
|
||||||
tasks_close_all()
|
tasks_close_all()
|
||||||
|
|
|
@ -4,8 +4,9 @@ require 'browser_test_helper'
|
||||||
|
|
||||||
class AgentUserManageTest < TestCase
|
class AgentUserManageTest < TestCase
|
||||||
def test_agent_customer_ticket_create
|
def test_agent_customer_ticket_create
|
||||||
customer_user_email = "customer-test-#{rand(999_999)}@example.com"
|
random_number = rand(999_999)
|
||||||
firstname = 'Customer Firstname'
|
customer_user_email = "customer-test-#{random_number}@example.com"
|
||||||
|
firstname = "Customer Firstname #{random_number}"
|
||||||
lastname = 'Customer Lastname'
|
lastname = 'Customer Lastname'
|
||||||
fullname = "#{firstname} #{lastname} <#{customer_user_email}>"
|
fullname = "#{firstname} #{lastname} <#{customer_user_email}>"
|
||||||
|
|
||||||
|
@ -21,10 +22,10 @@ class AgentUserManageTest < TestCase
|
||||||
click(css: 'a[href="#new"]', only_if_exists: true)
|
click(css: 'a[href="#new"]', only_if_exists: true)
|
||||||
click(css: 'a[href="#ticket/create"]')
|
click(css: 'a[href="#ticket/create"]')
|
||||||
|
|
||||||
watch_for(
|
await_text(text: 'New Ticket')
|
||||||
css: '.content.active .newTicket',
|
|
||||||
timeout: 1,
|
# Rumors say there is a modal reaper which will kill your modals if you dont sleep before a new ticket create
|
||||||
)
|
sleep 3
|
||||||
|
|
||||||
click(css: '.content.active .newTicket [name="customer_id_completion"]')
|
click(css: '.content.active .newTicket [name="customer_id_completion"]')
|
||||||
|
|
||||||
|
@ -77,11 +78,13 @@ class AgentUserManageTest < TestCase
|
||||||
css: '.content.active .newTicket input[name="customer_id_completion"]',
|
css: '.content.active .newTicket input[name="customer_id_completion"]',
|
||||||
value: fullname,
|
value: fullname,
|
||||||
)
|
)
|
||||||
sleep 4
|
|
||||||
|
|
||||||
# call new ticket screen again
|
# call new ticket screen again
|
||||||
tasks_close_all()
|
tasks_close_all()
|
||||||
|
|
||||||
|
# wait for user get indexed in elastic search
|
||||||
|
await_global_search(query: random_number)
|
||||||
|
|
||||||
click(css: 'a[href="#new"]', only_if_exists: true)
|
click(css: 'a[href="#new"]', only_if_exists: true)
|
||||||
click(css: 'a[href="#ticket/create"]')
|
click(css: 'a[href="#ticket/create"]')
|
||||||
|
|
||||||
|
|
|
@ -160,13 +160,11 @@ class FormTest < TestCase
|
||||||
value: "some text\nnew line",
|
value: "some text\nnew line",
|
||||||
)
|
)
|
||||||
click(
|
click(
|
||||||
browser: customer,
|
browser: customer,
|
||||||
css: 'body div.zammad-form-modal button[type="submit"]',
|
css: 'body div.zammad-form-modal button[type="submit"]',
|
||||||
|
expect_alert: true,
|
||||||
)
|
)
|
||||||
|
|
||||||
# check warning
|
|
||||||
alert = customer.switch_to.alert
|
|
||||||
alert.dismiss()
|
|
||||||
sleep 10
|
sleep 10
|
||||||
|
|
||||||
# fill form invalid data - within correct time
|
# fill form invalid data - within correct time
|
||||||
|
|
|
@ -28,7 +28,8 @@ class SwitchToUserTest < TestCase
|
||||||
css: '.content.active .dropdown--actions',
|
css: '.content.active .dropdown--actions',
|
||||||
)
|
)
|
||||||
click(
|
click(
|
||||||
css: '.content.active .icon-switchView',
|
css: '.content.active .icon-switchView',
|
||||||
|
ajax: false
|
||||||
)
|
)
|
||||||
sleep 3
|
sleep 3
|
||||||
|
|
||||||
|
@ -42,7 +43,7 @@ class SwitchToUserTest < TestCase
|
||||||
)
|
)
|
||||||
login = @browser.find_elements({ css: '.user-menu .user a' })[0].attribute('title')
|
login = @browser.find_elements({ css: '.user-menu .user a' })[0].attribute('title')
|
||||||
assert_equal(login, 'nicole.braun@zammad.org')
|
assert_equal(login, 'nicole.braun@zammad.org')
|
||||||
click(css: '.switchBackToUser .js-close')
|
click(css: '.switchBackToUser .js-close', ajax: false)
|
||||||
|
|
||||||
sleep 5
|
sleep 5
|
||||||
login = @browser.find_elements({ css: '.user-menu .user a' })[0].attribute('title')
|
login = @browser.find_elements({ css: '.user-menu .user a' })[0].attribute('title')
|
||||||
|
|
|
@ -542,6 +542,12 @@ class TestCase < ActiveSupport::TestCase
|
||||||
|
|
||||||
sleep 0.2 if !params[:fast]
|
sleep 0.2 if !params[:fast]
|
||||||
sleep params[:wait] if params[:wait]
|
sleep params[:wait] if params[:wait]
|
||||||
|
|
||||||
|
if params[:expect_alert]
|
||||||
|
check_alert(params)
|
||||||
|
else
|
||||||
|
await_empty_ajax_queue(params)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
=begin
|
=begin
|
||||||
|
@ -825,6 +831,7 @@ class TestCase < ActiveSupport::TestCase
|
||||||
end
|
end
|
||||||
|
|
||||||
sleep 0.2
|
sleep 0.2
|
||||||
|
await_empty_ajax_queue(params)
|
||||||
end
|
end
|
||||||
|
|
||||||
=begin
|
=begin
|
||||||
|
@ -880,6 +887,8 @@ class TestCase < ActiveSupport::TestCase
|
||||||
dropdown.select_by(:text, params[:value])
|
dropdown.select_by(:text, params[:value])
|
||||||
#puts "select2 - #{params.inspect}"
|
#puts "select2 - #{params.inspect}"
|
||||||
end
|
end
|
||||||
|
|
||||||
|
await_empty_ajax_queue(params)
|
||||||
end
|
end
|
||||||
|
|
||||||
=begin
|
=begin
|
||||||
|
@ -1265,16 +1274,17 @@ set type of task (closeTab, closeNextInOverview, stayOnTab)
|
||||||
|
|
||||||
=end
|
=end
|
||||||
|
|
||||||
def verify_task(params = {}, fallback = false)
|
def verify_task(params = {})
|
||||||
switch_window_focus(params)
|
switch_window_focus(params)
|
||||||
log('verify_task', params)
|
log('verify_task', params)
|
||||||
|
|
||||||
instance = params[:browser] || @browser
|
instance = params[:browser] || @browser
|
||||||
data = params[:data]
|
data = params[:data]
|
||||||
|
|
||||||
sleep 1
|
|
||||||
|
|
||||||
begin
|
begin
|
||||||
|
retries ||= 0
|
||||||
|
sleep 1
|
||||||
|
|
||||||
# verify title
|
# verify title
|
||||||
if data[:title]
|
if data[:title]
|
||||||
title = instance.find_elements(css: '.tasks .is-active')[0].text.strip
|
title = instance.find_elements(css: '.tasks .is-active')[0].text.strip
|
||||||
|
@ -1318,10 +1328,8 @@ set type of task (closeTab, closeNextInOverview, stayOnTab)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
rescue => e
|
rescue => e
|
||||||
# just try again
|
retries += 1
|
||||||
if !fallback
|
retry if retries < 5
|
||||||
verify_task(params, true)
|
|
||||||
end
|
|
||||||
raise "ERROR: #{e.inspect}"
|
raise "ERROR: #{e.inspect}"
|
||||||
end
|
end
|
||||||
true
|
true
|
||||||
|
@ -1572,6 +1580,7 @@ wait untill text in selector disabppears
|
||||||
.key_up(:control)
|
.key_up(:control)
|
||||||
.perform
|
.perform
|
||||||
screenshot(browser: instance, comment: 'shortcut_after')
|
screenshot(browser: instance, comment: 'shortcut_after')
|
||||||
|
await_empty_ajax_queue(params)
|
||||||
end
|
end
|
||||||
|
|
||||||
=begin
|
=begin
|
||||||
|
@ -1588,6 +1597,7 @@ wait untill text in selector disabppears
|
||||||
log('window_keys', params)
|
log('window_keys', params)
|
||||||
instance = params[:browser] || @browser
|
instance = params[:browser] || @browser
|
||||||
instance.action.send_keys(params[:value]).perform
|
instance.action.send_keys(params[:value]).perform
|
||||||
|
await_empty_ajax_queue(params)
|
||||||
end
|
end
|
||||||
|
|
||||||
=begin
|
=begin
|
||||||
|
@ -2122,19 +2132,14 @@ wait untill text in selector disabppears
|
||||||
mute_log: true,
|
mute_log: true,
|
||||||
)
|
)
|
||||||
|
|
||||||
found = false
|
watch_for(
|
||||||
7.times do
|
browser: instance,
|
||||||
element = instance.find_elements(css: '.content.active .newTicket')[0]
|
css: '.content.active .newTicket',
|
||||||
if element
|
timeout: 30,
|
||||||
found = true
|
)
|
||||||
break
|
|
||||||
end
|
# Rumors say there is a modal reaper which will kill your modals if you dont sleep before a new ticket create
|
||||||
sleep 1
|
sleep 3
|
||||||
end
|
|
||||||
if !found
|
|
||||||
screenshot(browser: instance, comment: 'ticket_create_failed')
|
|
||||||
raise 'no ticket create screen found!'
|
|
||||||
end
|
|
||||||
|
|
||||||
if data[:group]
|
if data[:group]
|
||||||
if data[:group] == '-NONE-'
|
if data[:group] == '-NONE-'
|
||||||
|
@ -2570,6 +2575,7 @@ wait untill text in selector disabppears
|
||||||
end
|
end
|
||||||
|
|
||||||
instance.find_elements(css: '.content.active .js-submit')[0].click
|
instance.find_elements(css: '.content.active .js-submit')[0].click
|
||||||
|
await_empty_ajax_queue(params)
|
||||||
|
|
||||||
# do not stay on tab
|
# do not stay on tab
|
||||||
if params[:task_type] == 'closeTab' || params[:task_type] == 'closeNextInOverview'
|
if params[:task_type] == 'closeTab' || params[:task_type] == 'closeNextInOverview'
|
||||||
|
@ -2867,7 +2873,7 @@ wait untill text in selector disabppears
|
||||||
instance = params[:browser] || @browser
|
instance = params[:browser] || @browser
|
||||||
|
|
||||||
instance.find_elements(css: '.js-overviewsMenuItem')[0].click
|
instance.find_elements(css: '.js-overviewsMenuItem')[0].click
|
||||||
sleep 2
|
await_empty_ajax_queue(params)
|
||||||
|
|
||||||
execute(
|
execute(
|
||||||
browser: instance,
|
browser: instance,
|
||||||
|
@ -2878,18 +2884,28 @@ wait untill text in selector disabppears
|
||||||
# js: '$(".content.active .overview-header").css("display", "none")',
|
# js: '$(".content.active .overview-header").css("display", "none")',
|
||||||
#)
|
#)
|
||||||
|
|
||||||
overviews = {}
|
begin
|
||||||
instance.find_elements(css: '.content.active .sidebar a[href]').each do |element|
|
overviews = {}
|
||||||
url = element.attribute('href')
|
instance.find_elements(css: '.content.active .sidebar a[href]').each do |element|
|
||||||
url.gsub!(%r{(http|https)://.+?/(.+?)$}, '\\2')
|
url = element.attribute('href')
|
||||||
overviews[url] = 0
|
url.gsub!(%r{(http|https)://.+?/(.+?)$}, '\\2')
|
||||||
#puts url.inspect
|
overviews[url] = 0
|
||||||
#puts element.inspect
|
#puts url.inspect
|
||||||
end
|
#puts element.inspect
|
||||||
overviews.each_key do |url|
|
end
|
||||||
count = instance.find_elements(css: ".content.active .sidebar a[href=\"#{url}\"] .badge")[0].text
|
|
||||||
overviews[url] = count.to_i
|
overviews.each_key do |url|
|
||||||
|
count = instance.find_elements(css: ".content.active .sidebar a[href=\"#{url}\"] .badge")[0].text
|
||||||
|
overviews[url] = count.to_i
|
||||||
|
end
|
||||||
|
rescue => e
|
||||||
|
retries ||= 0
|
||||||
|
retries += 1
|
||||||
|
sleep 0.5
|
||||||
|
retry if retries < 5
|
||||||
|
raise e
|
||||||
end
|
end
|
||||||
|
|
||||||
log('overview_counter', overviews)
|
log('overview_counter', overviews)
|
||||||
overviews
|
overviews
|
||||||
end
|
end
|
||||||
|
@ -3340,6 +3356,7 @@ wait untill text in selector disabppears
|
||||||
element.send_keys(data[:name])
|
element.send_keys(data[:name])
|
||||||
|
|
||||||
instance.find_elements(css: '.modal button.js-submit')[0].click
|
instance.find_elements(css: '.modal button.js-submit')[0].click
|
||||||
|
await_empty_ajax_queue(params)
|
||||||
modal_disappear(
|
modal_disappear(
|
||||||
browser: instance,
|
browser: instance,
|
||||||
timeout: 5,
|
timeout: 5,
|
||||||
|
@ -3458,6 +3475,7 @@ wait untill text in selector disabppears
|
||||||
element.clear
|
element.clear
|
||||||
element.send_keys(data[:first_response_time_in_text])
|
element.send_keys(data[:first_response_time_in_text])
|
||||||
instance.find_elements(css: '.modal button.js-submit')[0].click
|
instance.find_elements(css: '.modal button.js-submit')[0].click
|
||||||
|
await_empty_ajax_queue(params)
|
||||||
modal_disappear(browser: instance)
|
modal_disappear(browser: instance)
|
||||||
7.times do
|
7.times do
|
||||||
element = instance.find_elements(css: 'body')[0]
|
element = instance.find_elements(css: 'body')[0]
|
||||||
|
@ -3661,6 +3679,7 @@ wait untill text in selector disabppears
|
||||||
dropdown.select_by(:text, data[:signature])
|
dropdown.select_by(:text, data[:signature])
|
||||||
end
|
end
|
||||||
instance.find_elements(css: '.modal button.js-submit')[0].click
|
instance.find_elements(css: '.modal button.js-submit')[0].click
|
||||||
|
await_empty_ajax_queue(params)
|
||||||
modal_disappear(browser: instance)
|
modal_disappear(browser: instance)
|
||||||
|
|
||||||
element = instance.find_elements(css: 'body')[0]
|
element = instance.find_elements(css: 'body')[0]
|
||||||
|
@ -3673,6 +3692,7 @@ wait untill text in selector disabppears
|
||||||
data[:member]&.each do |member|
|
data[:member]&.each do |member|
|
||||||
instance.find_elements(css: 'a[href="#manage"]')[0].click
|
instance.find_elements(css: 'a[href="#manage"]')[0].click
|
||||||
sleep 1
|
sleep 1
|
||||||
|
scroll_to(params.merge(css: '.content.active a[href="#manage/users"]'))
|
||||||
instance.find_elements(css: '.content.active a[href="#manage/users"]')[0].click
|
instance.find_elements(css: '.content.active a[href="#manage/users"]')[0].click
|
||||||
sleep 3
|
sleep 3
|
||||||
element = instance.find_elements(css: '.content.active [name="search"]')[0]
|
element = instance.find_elements(css: '.content.active [name="search"]')[0]
|
||||||
|
@ -3685,6 +3705,7 @@ wait untill text in selector disabppears
|
||||||
#instance.find_elements(:css => 'label:contains(" ' + action[:name] + '")')[0].click
|
#instance.find_elements(:css => 'label:contains(" ' + action[:name] + '")')[0].click
|
||||||
instance.execute_script(%($(".js-groupList tr:contains(\\"#{data[:name]}\\") .js-groupListItem[value=#{member[:access]}]").prop("checked", true)))
|
instance.execute_script(%($(".js-groupList tr:contains(\\"#{data[:name]}\\") .js-groupListItem[value=#{member[:access]}]").prop("checked", true)))
|
||||||
instance.find_elements(css: '.modal button.js-submit')[0].click
|
instance.find_elements(css: '.modal button.js-submit')[0].click
|
||||||
|
await_empty_ajax_queue(params)
|
||||||
modal_disappear(browser: instance)
|
modal_disappear(browser: instance)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -3933,6 +3954,8 @@ wait untill text in selector disabppears
|
||||||
css: '.content.active a[href="#manage/roles"]',
|
css: '.content.active a[href="#manage/roles"]',
|
||||||
mute_log: true,
|
mute_log: true,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
await_text(container: '.content.active table tr td', text: data[:name])
|
||||||
instance.execute_script(%($('.content.active table tr td:contains(" #{data[:name]}")').first().click()))
|
instance.execute_script(%($('.content.active table tr td:contains(" #{data[:name]}")').first().click()))
|
||||||
|
|
||||||
modal_ready(browser: instance)
|
modal_ready(browser: instance)
|
||||||
|
@ -4830,4 +4853,124 @@ wait untill text in selector disabppears
|
||||||
screenshot(browser: instance, comment: "object_manager_attribute_#{action}_failed")
|
screenshot(browser: instance, comment: "object_manager_attribute_#{action}_failed")
|
||||||
raise "object_manager_attribute_#{action}_failed"
|
raise "object_manager_attribute_#{action}_failed"
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def check_alert(params = {})
|
||||||
|
instance = params[:browser] || @browser
|
||||||
|
|
||||||
|
tries = 5
|
||||||
|
begin
|
||||||
|
alert = instance.switch_to.alert
|
||||||
|
alert.dismiss()
|
||||||
|
rescue e
|
||||||
|
tries -= 1
|
||||||
|
sleep 0.5
|
||||||
|
retry if tries.positive?
|
||||||
|
raise e
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
=begin
|
||||||
|
|
||||||
|
This function waits for ajax requests and object form flow to be done
|
||||||
|
|
||||||
|
await_empty_ajax_queue
|
||||||
|
|
||||||
|
=end
|
||||||
|
|
||||||
|
def await_empty_ajax_queue(params = {})
|
||||||
|
return if params[:ajax] == false
|
||||||
|
|
||||||
|
instance = params[:browser] || @browser
|
||||||
|
|
||||||
|
10.times do
|
||||||
|
sleep 0.5
|
||||||
|
|
||||||
|
break if instance.execute_script('return typeof(App) === "undefined"')
|
||||||
|
break if instance.execute_script('return App.Ajax.queue().length').zero?
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
=begin
|
||||||
|
|
||||||
|
This function waits for a text to be ready in the dom. By default it searches in the active content.
|
||||||
|
|
||||||
|
await_text(text: 'New Ticket')
|
||||||
|
|
||||||
|
await_text(text: 'New Ticket', container: 'body')
|
||||||
|
|
||||||
|
=end
|
||||||
|
|
||||||
|
def await_text(params)
|
||||||
|
return if params[:ajax] == false
|
||||||
|
|
||||||
|
instance = params[:browser] || @browser
|
||||||
|
|
||||||
|
container = '.content.active'
|
||||||
|
if params[:container]
|
||||||
|
container = params[:container]
|
||||||
|
end
|
||||||
|
|
||||||
|
20.times do
|
||||||
|
log('await_text', params)
|
||||||
|
|
||||||
|
break if instance.execute_script("return $(\"#{container}:contains('#{params[:text]}')\").length").positive?
|
||||||
|
|
||||||
|
sleep 0.5
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
=begin
|
||||||
|
|
||||||
|
This function waits for the overview_counter to return a specific result.
|
||||||
|
|
||||||
|
await_overview_counter(view: '#ticket/view/all_unassigned', count: overview_counter_before['#ticket/view/all_unassigned'] - 2)
|
||||||
|
|
||||||
|
=end
|
||||||
|
|
||||||
|
def await_overview_counter(params)
|
||||||
|
result = nil
|
||||||
|
40.times do
|
||||||
|
result = overview_counter
|
||||||
|
|
||||||
|
if result[ params[:view] ] != params[:count]
|
||||||
|
sleep 0.5
|
||||||
|
next
|
||||||
|
end
|
||||||
|
|
||||||
|
break
|
||||||
|
end
|
||||||
|
|
||||||
|
assert_equal(params[:count], result[ params[:view] ])
|
||||||
|
end
|
||||||
|
|
||||||
|
=begin
|
||||||
|
|
||||||
|
This function waits for a search result to be available in the global search.
|
||||||
|
It can help to verify if a user is indexed in elastic search.
|
||||||
|
|
||||||
|
await_global_search(query: 'customer 1 firstname')
|
||||||
|
|
||||||
|
=end
|
||||||
|
|
||||||
|
def await_global_search(params)
|
||||||
|
instance = params[:browser] || @browser
|
||||||
|
|
||||||
|
30.times do
|
||||||
|
log('await_global_search', params)
|
||||||
|
|
||||||
|
set(
|
||||||
|
css: 'input#global-search',
|
||||||
|
value: params[:query],
|
||||||
|
)
|
||||||
|
|
||||||
|
break if instance.execute_script("return $(\"ul.global-search-result:visible:contains('#{params[:query]}')\").length") == 1
|
||||||
|
|
||||||
|
sleep 0.5
|
||||||
|
end
|
||||||
|
|
||||||
|
set(
|
||||||
|
css: 'input#global-search',
|
||||||
|
value: '',
|
||||||
|
)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
Loading…
Reference in a new issue