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/static_assets.rb'
|
||||
- 'lib/transaction_dispatcher.rb'
|
||||
- 'spec/support/capybara/common_actions.rb'
|
||||
|
||||
Metrics/PerceivedComplexity:
|
||||
Exclude:
|
||||
|
|
|
@ -1038,12 +1038,13 @@ class App.ControllerTable extends App.Controller
|
|||
# update store
|
||||
@preferencesStore('order', 'customOrderBy', @orderBy)
|
||||
@preferencesStore('order', 'customOrderDirection', @orderDirection)
|
||||
render = =>
|
||||
@renderTableFull(false, skipHeadersResize: true)
|
||||
App.QueueManager.add('tableRender', render)
|
||||
|
||||
if @sortRenderCallback
|
||||
App.QueueManager.add('tableRender', @sortRenderCallback)
|
||||
else
|
||||
render = =>
|
||||
@renderTableFull(false, skipHeadersResize: true)
|
||||
App.QueueManager.add('tableRender', render)
|
||||
|
||||
App.QueueManager.run('tableRender')
|
||||
|
||||
|
|
|
@ -68,9 +68,11 @@ module BrowserTestHelper
|
|||
# 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?
|
||||
end
|
||||
rescue
|
||||
nil
|
||||
end
|
||||
|
||||
# Moves the mouse from its current position by the given offset.
|
||||
|
@ -112,6 +114,7 @@ module BrowserTestHelper
|
|||
#
|
||||
def release_mouse
|
||||
page.driver.browser.action.release.perform
|
||||
await_empty_ajax_queue
|
||||
end
|
||||
|
||||
class Waiter < SimpleDelegator
|
||||
|
|
|
@ -38,6 +38,8 @@ module CommonActions
|
|||
wait(4).until_exists do
|
||||
current_login
|
||||
end
|
||||
|
||||
await_empty_ajax_queue
|
||||
end
|
||||
|
||||
# Checks if the current session is logged in.
|
||||
|
@ -120,6 +122,16 @@ module CommonActions
|
|||
route = "/##{route}"
|
||||
end
|
||||
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
|
||||
|
||||
# Overwrites the global Capybara.always_include_port setting (true)
|
||||
|
|
|
@ -34,3 +34,108 @@ class Capybara::Node::Element
|
|||
raise "Element still moving after #{checks} checks"
|
||||
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
|
||||
logout
|
||||
expect_current_route 'login', wait: 2
|
||||
expect_current_route 'login', wait: 10
|
||||
end
|
||||
|
||||
it 'will unset user attributes after logout' do
|
||||
logout
|
||||
expect_current_route 'login', wait: 2
|
||||
expect_current_route 'login', wait: 10
|
||||
|
||||
visit '/#signup'
|
||||
|
||||
|
@ -31,20 +31,20 @@ RSpec.describe 'Authentication', type: :system do
|
|||
it 'Login and redirect to requested url', authenticated_as: false do
|
||||
visit 'ticket/zoom/1'
|
||||
|
||||
expect_current_route 'login', wait: 2
|
||||
expect_current_route 'login', wait: 10
|
||||
|
||||
login(
|
||||
username: 'master@example.com',
|
||||
password: 'test',
|
||||
)
|
||||
|
||||
expect_current_route 'ticket/zoom/1', wait: 2
|
||||
expect_current_route 'ticket/zoom/1', wait: 10
|
||||
end
|
||||
|
||||
it 'Login and redirect to requested url via external authentication', authenticated_as: false do
|
||||
visit 'ticket/zoom/1'
|
||||
|
||||
expect_current_route 'login', wait: 2
|
||||
expect_current_route 'login', wait: 10
|
||||
|
||||
# simulate jump to external ressource
|
||||
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
|
||||
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')
|
||||
end
|
||||
|
|
|
@ -30,7 +30,6 @@ RSpec.describe 'Dashboard', type: :system, authenticated_as: true do
|
|||
fill_in 'Lastname', with: 'Braun'
|
||||
fill_in 'Email', with: 'nick.braun@zammad.org'
|
||||
click_on 'Invite'
|
||||
await_empty_ajax_queue
|
||||
expect(User.find_by(firstname: 'Nick').roles).to eq([Role.find_by(name: 'Public')])
|
||||
end
|
||||
end
|
||||
|
@ -42,6 +41,7 @@ RSpec.describe 'Dashboard', type: :system, authenticated_as: true do
|
|||
|
||||
before do
|
||||
ensure_websocket(check_if_pinged: false)
|
||||
sleep 3 # fast relog causes raise conditions in websocket server
|
||||
end
|
||||
|
||||
context 'Logout by frontend plugin - Default', authenticated_as: :authenticate do
|
||||
|
|
|
@ -1,46 +1,46 @@
|
|||
# Copyright (C) 2012-2021 Zammad Foundation, http://zammad-foundation.org/
|
||||
|
||||
RSpec.shared_examples 'pagination' do |model:, klass:, path:, sort_by: :name|
|
||||
def prepare(model)
|
||||
let(:model) { model }
|
||||
|
||||
def authenticate
|
||||
create_list(model, 500)
|
||||
true
|
||||
end
|
||||
|
||||
it 'does paginate' do
|
||||
prepare(model)
|
||||
it 'does paginate', authenticated_as: :authenticate do
|
||||
visit path
|
||||
refresh # more stability
|
||||
expect(page).to have_css('.js-pager', wait: 10)
|
||||
|
||||
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_css('.js-page.is-selected', text: '1')
|
||||
|
||||
page.first('.js-page', text: '2').click
|
||||
await_empty_ajax_queue
|
||||
page.first('.js-page', text: '2', wait: 10).click
|
||||
|
||||
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_css('.js-page.is-selected', text: '2')
|
||||
|
||||
page.first('.js-page', text: '3').click
|
||||
await_empty_ajax_queue
|
||||
page.first('.js-page', text: '3', wait: 10).click
|
||||
|
||||
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_css('.js-page.is-selected', text: '3')
|
||||
|
||||
page.first('.js-page', text: '4').click
|
||||
await_empty_ajax_queue
|
||||
page.first('.js-page', text: '4', wait: 10).click
|
||||
|
||||
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_css('.js-page.is-selected', text: '4')
|
||||
|
||||
page.first('.js-page', text: '1').click
|
||||
await_empty_ajax_queue
|
||||
page.first('.js-page', text: '1', wait: 10).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_css('.js-page.is-selected', text: '1')
|
||||
|
||||
page.first('.js-tableHead[data-column-key=name]').click
|
||||
await_empty_ajax_queue
|
||||
class_last = klass.order(sort_by => :desc).first
|
||||
expect(page).to have_text(class_last.name, wait: 10)
|
||||
end
|
||||
|
|
|
@ -42,12 +42,12 @@ RSpec.describe 'Manage > Users', type: :system do
|
|||
visit 'manage/users'
|
||||
|
||||
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-switchTo').click
|
||||
end
|
||||
|
||||
await_empty_ajax_queue
|
||||
expect(page).to have_text("Zammad looks like this for \"#{user.firstname} #{user.lastname}\"", wait: 10)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -63,8 +63,6 @@ RSpec.describe 'Admin Panel > Objects', type: :system, authenticated_as: true do
|
|||
'nulloption' => true,
|
||||
'maxlength' => 255 }
|
||||
|
||||
await_empty_ajax_queue
|
||||
|
||||
expect(ObjectManager::Attribute.last.data_option).to eq(expected_data_options)
|
||||
end
|
||||
end
|
||||
|
|
|
@ -15,6 +15,6 @@ RSpec.describe 'System > Translations', type: :system do
|
|||
|
||||
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
|
||||
|
|
|
@ -204,8 +204,6 @@ RSpec.describe 'Ticket Create', type: :system do
|
|||
encrypt_button = find('.js-securityEncrypt', wait: 5)
|
||||
sign_button = find('.js-securitySign', wait: 5)
|
||||
|
||||
await_empty_ajax_queue
|
||||
|
||||
active_button_class = '.btn--active'
|
||||
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)
|
||||
|
@ -234,8 +232,6 @@ RSpec.describe 'Ticket Create', type: :system do
|
|||
within(:active_content) do
|
||||
use_template(template)
|
||||
|
||||
await_empty_ajax_queue
|
||||
|
||||
select new_group.name, from: 'group_id'
|
||||
end
|
||||
end
|
||||
|
@ -378,7 +374,6 @@ RSpec.describe 'Ticket Create', type: :system do
|
|||
click_on 'Link issue'
|
||||
fill_in 'link', with: ENV['GITLAB_ISSUE_LINK']
|
||||
click_on 'Submit'
|
||||
await_empty_ajax_queue
|
||||
|
||||
# verify issue
|
||||
content = find('.sidebar-git-issue-content')
|
||||
|
@ -390,7 +385,6 @@ RSpec.describe 'Ticket Create', type: :system do
|
|||
|
||||
# create Ticket
|
||||
click '.js-submit'
|
||||
await_empty_ajax_queue
|
||||
|
||||
# check stored data
|
||||
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'
|
||||
fill_in 'link', with: ENV['GITHUB_ISSUE_LINK']
|
||||
click_on 'Submit'
|
||||
await_empty_ajax_queue
|
||||
|
||||
# verify issue
|
||||
content = find('.sidebar-git-issue-content')
|
||||
|
@ -444,7 +437,6 @@ RSpec.describe 'Ticket Create', type: :system do
|
|||
|
||||
# create Ticket
|
||||
click '.js-submit'
|
||||
await_empty_ajax_queue
|
||||
|
||||
# check stored data
|
||||
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')
|
||||
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
|
||||
|
||||
# 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
|
||||
find(".edit [name=#{attribute.name}]").select('name 2')
|
||||
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
|
||||
|
||||
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
|
||||
visit "#ticket/zoom/#{origin_ticket.id}"
|
||||
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-menu [data-type="ticket-history"]'
|
||||
|
||||
|
|
|
@ -112,9 +112,9 @@ RSpec.describe 'Ticket views', type: :system do
|
|||
|
||||
release_mouse
|
||||
|
||||
await_empty_ajax_queue
|
||||
|
||||
expect(Ticket.first.articles.last.subject).to eq('macro note')
|
||||
expect do
|
||||
wait(10, interval: 0.1).until { Ticket.first.articles.last.subject == 'macro note' }
|
||||
end.not_to raise_error
|
||||
end
|
||||
end
|
||||
end
|
||||
|
@ -136,12 +136,9 @@ RSpec.describe 'Ticket views', type: :system do
|
|||
click '.js-submit'
|
||||
end
|
||||
|
||||
await_empty_ajax_queue
|
||||
|
||||
expect([
|
||||
ticket1.articles.last&.body,
|
||||
ticket2.articles.last&.body
|
||||
]).to be_all note
|
||||
expect do
|
||||
wait(10, interval: 0.1).until { [ ticket1.articles.last&.body, ticket2.articles.last&.body ] == [note, note] }
|
||||
end.not_to raise_error
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -184,9 +181,9 @@ RSpec.describe 'Ticket views', type: :system do
|
|||
|
||||
it 'does basic view test of tickets' do
|
||||
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'
|
||||
expect(page).to have_text(ticket.title)
|
||||
expect(page).to have_text(ticket.title, wait: 10)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -448,7 +448,7 @@ RSpec.describe 'Ticket zoom', type: :system do
|
|||
end
|
||||
|
||||
context 'button is hidden on the go' do
|
||||
let(:setting_delete_timeframe) { 5 }
|
||||
let(:setting_delete_timeframe) { 10 }
|
||||
|
||||
let(:user) { agent }
|
||||
let(:item) { 'article_note_self' }
|
||||
|
@ -692,8 +692,6 @@ RSpec.describe 'Ticket zoom', type: :system do
|
|||
encrypt_button = find('.js-securityEncrypt', wait: 5)
|
||||
sign_button = find('.js-securitySign', wait: 5)
|
||||
|
||||
await_empty_ajax_queue
|
||||
|
||||
active_button_class = '.btn--active'
|
||||
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)
|
||||
|
@ -709,8 +707,6 @@ RSpec.describe 'Ticket zoom', type: :system do
|
|||
within(:active_content) do
|
||||
all('a[data-type=emailReply]').last.click
|
||||
find('.articleNewEdit-body').send_keys('Test')
|
||||
|
||||
await_empty_ajax_queue
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -726,8 +722,6 @@ RSpec.describe 'Ticket zoom', type: :system do
|
|||
all('a[data-type=emailReply]').last.click
|
||||
find('.articleNewEdit-body').send_keys('Test')
|
||||
|
||||
await_empty_ajax_queue
|
||||
|
||||
select new_group.name, from: 'group_id'
|
||||
end
|
||||
end
|
||||
|
@ -883,8 +877,6 @@ RSpec.describe 'Ticket zoom', type: :system do
|
|||
find(:richtext).execute_script "this.innerHTML = \"#{ticket_article_body}\""
|
||||
find('.js-submit').click
|
||||
end
|
||||
|
||||
await_empty_ajax_queue
|
||||
end
|
||||
|
||||
def forward
|
||||
|
@ -893,8 +885,6 @@ RSpec.describe 'Ticket zoom', type: :system do
|
|||
fill_in 'To', with: 'customer@example.com'
|
||||
find('.js-submit').click
|
||||
end
|
||||
|
||||
await_empty_ajax_queue
|
||||
end
|
||||
|
||||
def images_identical?(image_a, image_b)
|
||||
|
@ -986,7 +976,7 @@ RSpec.describe 'Ticket zoom', type: :system do
|
|||
visit "ticket/zoom/#{ticket.id}"
|
||||
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('owner_id')
|
||||
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
|
||||
find(:active_ticket_article, ticket_article)
|
||||
await_empty_ajax_queue
|
||||
|
||||
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
|
||||
|
@ -1190,37 +1179,37 @@ RSpec.describe 'Ticket zoom', type: :system do
|
|||
it 'previous is not clickable for the first item' do
|
||||
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
|
||||
|
||||
it 'next is clickable for the first item' do
|
||||
open_nth_item(0)
|
||||
|
||||
expect { click '.pagination .next' }.to change { current_url }
|
||||
expect { click '.pagination .next' }.to change { page.find('.content.active')[:id] }
|
||||
end
|
||||
|
||||
it 'previous is clickable for the middle item' do
|
||||
open_nth_item(1)
|
||||
|
||||
expect { click '.pagination .previous' }.to change { current_url }
|
||||
expect { click '.pagination .previous' }.to change { page.find('.content.active')[:id] }
|
||||
end
|
||||
|
||||
it 'next is clickable for the middle item' do
|
||||
open_nth_item(1)
|
||||
|
||||
expect { click '.pagination .next' }.to change { current_url }
|
||||
expect { click '.pagination .next' }.to change { page.find('.content.active')[:id] }
|
||||
end
|
||||
|
||||
it 'previous is clickable for the last item' do
|
||||
open_nth_item(2)
|
||||
|
||||
expect { click '.pagination .previous' }.to change { current_url }
|
||||
expect { click '.pagination .previous' }.to change { page.find('.content.active')[:id] }
|
||||
end
|
||||
|
||||
it 'next is not clickable for the last item' do
|
||||
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
|
||||
|
||||
def open_nth_item(nth)
|
||||
|
@ -1243,8 +1232,6 @@ RSpec.describe 'Ticket zoom', type: :system do
|
|||
|
||||
visit "ticket/zoom/#{ticket_a.id}"
|
||||
|
||||
await_empty_ajax_queue
|
||||
|
||||
visit 'ticket/view/all_unassigned'
|
||||
end
|
||||
|
||||
|
@ -1252,7 +1239,7 @@ RSpec.describe 'Ticket zoom', type: :system do
|
|||
within :active_content do
|
||||
click_on ticket_a.title
|
||||
|
||||
expect(page).to have_css('.pagination-counter')
|
||||
expect(page).to have_css('.pagination-counter', wait: 10)
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -1262,7 +1249,7 @@ RSpec.describe 'Ticket zoom', type: :system do
|
|||
visit 'dashboard'
|
||||
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
|
||||
|
@ -1293,7 +1280,6 @@ RSpec.describe 'Ticket zoom', type: :system do
|
|||
|
||||
# wait for article to be added to the page
|
||||
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
|
||||
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
|
||||
expect(page).to have_css('.ticket-article-item', count: 2, wait: 10)
|
||||
await_empty_ajax_queue
|
||||
|
||||
# click on forward of created article
|
||||
within :active_ticket_article, article1 do
|
||||
|
@ -1327,7 +1312,6 @@ RSpec.describe 'Ticket zoom', type: :system do
|
|||
click '.js-submit'
|
||||
|
||||
# wait for article to be added to the page
|
||||
await_empty_ajax_queue
|
||||
expect(page).to have_css('.ticket-article-item', count: 3)
|
||||
|
||||
# check if attachment was forwarded successfully
|
||||
|
@ -1376,7 +1360,6 @@ RSpec.describe 'Ticket zoom', type: :system do
|
|||
|
||||
it 'not shown to customer' do
|
||||
visit "ticket/zoom/#{ticket.id}"
|
||||
await_empty_ajax_queue
|
||||
|
||||
within :active_content do
|
||||
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'))
|
||||
|
||||
visit "ticket/zoom/#{ticket.id}"
|
||||
await_empty_ajax_queue
|
||||
end
|
||||
|
||||
let(:ticket) { Ticket.first }
|
||||
|
@ -1436,7 +1418,6 @@ RSpec.describe 'Ticket zoom', type: :system do
|
|||
|
||||
ensure_websocket do
|
||||
visit "ticket/zoom/#{ticket.id}"
|
||||
await_empty_ajax_queue
|
||||
|
||||
within :active_ticket_article, article do
|
||||
expect(page).to have_css(%(a[href="#{url}"]))
|
||||
|
@ -1457,44 +1438,33 @@ RSpec.describe 'Ticket zoom', type: :system do
|
|||
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
|
||||
ensure_websocket do
|
||||
visit "ticket/zoom/#{ticket.id}/#{article_in_the_middle.id}"
|
||||
await_empty_ajax_queue
|
||||
# workaround because browser scrolls in test initially to the bottom
|
||||
# maybe because the articles are not present?!
|
||||
refresh
|
||||
visit "ticket/zoom/#{ticket.id}"
|
||||
y = check_obscured(bottom: false)
|
||||
|
||||
# scroll to article in the middle of the page
|
||||
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}")).not_to be_obscured
|
||||
expect(find("div#article-content-#{article_at_the_bottom.id}")).to be_obscured
|
||||
end
|
||||
visit "ticket/zoom/#{ticket.id}/#{article_in_the_middle.id}"
|
||||
y = check_obscured(middle: false, scroll_y: y)
|
||||
|
||||
# scroll to article at the top of the page
|
||||
visit "ticket/zoom/#{ticket.id}/#{article_at_the_top.id}"
|
||||
await_empty_ajax_queue
|
||||
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
|
||||
y = check_obscured(top: false, scroll_y: y)
|
||||
|
||||
# scroll to article at the bottom of the page
|
||||
visit "ticket/zoom/#{ticket.id}/#{article_at_the_bottom.id}"
|
||||
await_empty_ajax_queue
|
||||
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
|
||||
check_obscured(bottom: false, scroll_y: y)
|
||||
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
|
||||
ensure_websocket do
|
||||
visit "ticket/zoom/#{ticket.id}"
|
||||
await_empty_ajax_queue
|
||||
|
||||
visit 'dashboard'
|
||||
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}")
|
||||
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}"
|
||||
within :active_content do
|
||||
|
@ -1533,7 +1502,6 @@ RSpec.describe 'Ticket zoom', type: :system do
|
|||
visit "ticket/zoom/#{ticket.id}"
|
||||
find('.js-openDropdownMacro').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.content_type).to eq('text/html')
|
||||
|
@ -1598,7 +1566,6 @@ RSpec.describe 'Ticket zoom', type: :system do
|
|||
click_on 'Link issue'
|
||||
fill_in 'link', with: ENV['GITLAB_ISSUE_LINK']
|
||||
click_on 'Submit'
|
||||
await_empty_ajax_queue
|
||||
|
||||
# verify issue
|
||||
content = find('.sidebar-git-issue-content')
|
||||
|
@ -1615,7 +1582,6 @@ RSpec.describe 'Ticket zoom', type: :system do
|
|||
|
||||
# delete issue
|
||||
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')
|
||||
expect(content).to have_text('No linked issues')
|
||||
|
@ -1658,7 +1624,6 @@ RSpec.describe 'Ticket zoom', type: :system do
|
|||
click_on 'Link issue'
|
||||
fill_in 'link', with: ENV['GITHUB_ISSUE_LINK']
|
||||
click_on 'Submit'
|
||||
await_empty_ajax_queue
|
||||
|
||||
# verify issue
|
||||
content = find('.sidebar-git-issue-content')
|
||||
|
@ -1675,7 +1640,6 @@ RSpec.describe 'Ticket zoom', type: :system do
|
|||
|
||||
# delete issue
|
||||
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')
|
||||
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)
|
||||
|
||||
visit "#ticket/zoom/#{ticket_open.id}"
|
||||
click '.tabsSidebar-tab[data-tab=customer]'
|
||||
click '.user-tickets[data-type=closed]'
|
||||
expect(page).to have_text(ticket_closed.title, wait: 20)
|
||||
end
|
||||
|
|
|
@ -159,7 +159,7 @@ class AgentTicketActionLevel0Test < TestCase
|
|||
css: '.newTicket',
|
||||
value: 'New Ticket',
|
||||
)
|
||||
exists_not(css: '.newTicket select[name="group_id"]')
|
||||
exists(css: '.newTicket .form-group.hide select[name="group_id"]')
|
||||
|
||||
set(
|
||||
css: '.newTicket input[name="title"]',
|
||||
|
|
|
@ -30,14 +30,7 @@ class AgentTicketAttachmentTest < TestCase
|
|||
sleep 1
|
||||
|
||||
# submit form
|
||||
click(css: '.content.active .js-submit')
|
||||
sleep 2
|
||||
|
||||
# check warning
|
||||
alert = @browser.switch_to.alert
|
||||
alert.dismiss()
|
||||
#alert.accept()
|
||||
#alert = alert.text
|
||||
click(css: '.content.active .js-submit', expect_alert: true)
|
||||
|
||||
# since selenium webdriver with firefox is not able to upload files, skipp here
|
||||
# https://github.com/w3c/webdriver/issues/1230
|
||||
|
@ -90,12 +83,7 @@ class AgentTicketAttachmentTest < TestCase
|
|||
)
|
||||
|
||||
# submit form
|
||||
click(css: '.content.active .js-submit')
|
||||
sleep 2
|
||||
|
||||
# check warning
|
||||
alert = @browser.switch_to.alert
|
||||
alert.dismiss()
|
||||
click(css: '.content.active .js-submit', expect_alert: true)
|
||||
|
||||
# add attachment, attachment check should quiet
|
||||
file_upload(
|
||||
|
@ -111,12 +99,6 @@ class AgentTicketAttachmentTest < TestCase
|
|||
|
||||
# submit form
|
||||
click(css: '.content.active .js-submit')
|
||||
sleep 2
|
||||
|
||||
# no warning
|
||||
#alert = @browser.switch_to.alert
|
||||
|
||||
# check if article exists
|
||||
|
||||
# discard changes should gone away
|
||||
watch_for_disappear(
|
||||
|
|
|
@ -160,7 +160,12 @@ class AgentTicketMacroTest < TestCase
|
|||
# when we re-enter the Zoom view for a ticket via the overview
|
||||
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(
|
||||
title: ticket1[:title],
|
||||
|
|
|
@ -67,6 +67,9 @@ class AgentTicketOverviewLevel0Test < TestCase
|
|||
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(
|
||||
css: '.content.active .bulkAction [name="state_id"]',
|
||||
|
@ -92,6 +95,7 @@ class AgentTicketOverviewLevel0Test < TestCase
|
|||
)
|
||||
|
||||
# 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()
|
||||
|
||||
# click options and enable number and article count
|
||||
|
@ -188,11 +192,9 @@ class AgentTicketOverviewLevel0Test < TestCase
|
|||
body: 'overview count test #3',
|
||||
}
|
||||
)
|
||||
sleep 6
|
||||
|
||||
# get new overview count
|
||||
overview_counter_new = overview_counter()
|
||||
assert_equal(overview_counter_before['#ticket/view/all_unassigned'] + 1, overview_counter_new['#ticket/view/all_unassigned'])
|
||||
await_overview_counter(view: '#ticket/view/all_unassigned', count: overview_counter_before['#ticket/view/all_unassigned'] + 1)
|
||||
|
||||
# open ticket by search
|
||||
ticket_open_by_search(
|
||||
|
@ -206,11 +208,9 @@ class AgentTicketOverviewLevel0Test < TestCase
|
|||
state: 'closed',
|
||||
}
|
||||
)
|
||||
sleep 6
|
||||
|
||||
# get current overview count
|
||||
overview_counter_after = overview_counter()
|
||||
assert_equal(overview_counter_before['#ticket/view/all_unassigned'], overview_counter_after['#ticket/view/all_unassigned'])
|
||||
await_overview_counter(view: '#ticket/view/all_unassigned', count: overview_counter_before['#ticket/view/all_unassigned'])
|
||||
|
||||
# cleanup
|
||||
tasks_close_all()
|
||||
|
@ -334,8 +334,7 @@ class AgentTicketOverviewLevel0Test < TestCase
|
|||
)
|
||||
|
||||
# get new overview count
|
||||
overview_counter_new = overview_counter()
|
||||
assert_equal(overview_counter_before['#ticket/view/all_unassigned'] - 2, overview_counter_new['#ticket/view/all_unassigned'])
|
||||
await_overview_counter(view: '#ticket/view/all_unassigned', count: overview_counter_before['#ticket/view/all_unassigned'] - 2)
|
||||
|
||||
# open ticket by search
|
||||
ticket_open_by_search(
|
||||
|
@ -463,8 +462,7 @@ class AgentTicketOverviewLevel0Test < TestCase
|
|||
)
|
||||
|
||||
# get new overview count
|
||||
overview_counter_new = overview_counter()
|
||||
assert_equal(overview_counter_before['#ticket/view/all_unassigned'] - 2, overview_counter_new['#ticket/view/all_unassigned'])
|
||||
await_overview_counter(view: '#ticket/view/all_unassigned', count: overview_counter_before['#ticket/view/all_unassigned'] - 2)
|
||||
|
||||
# cleanup
|
||||
tasks_close_all()
|
||||
|
|
|
@ -3,6 +3,20 @@
|
|||
require 'browser_test_helper'
|
||||
|
||||
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
|
||||
@browser = browser_instance
|
||||
login(
|
||||
|
@ -54,7 +68,7 @@ class AgentTicketOverviewTabTest < TestCase
|
|||
link: '#ticket/view/all_unassigned',
|
||||
)
|
||||
|
||||
assert_equal(1, @browser.find_elements(css: '.tasks .task').count)
|
||||
task_count_equals(1)
|
||||
|
||||
ticket_update(
|
||||
data: {
|
||||
|
@ -70,7 +84,7 @@ class AgentTicketOverviewTabTest < TestCase
|
|||
timeout: 8,
|
||||
)
|
||||
|
||||
assert_equal(1, @browser.find_elements(css: '.tasks .task').count)
|
||||
task_count_equals(1)
|
||||
|
||||
ticket_update(
|
||||
data: {
|
||||
|
@ -80,7 +94,7 @@ class AgentTicketOverviewTabTest < TestCase
|
|||
task_type: 'closeTab', # default: stayOnTab / possible: closeTab, closeNextInOverview, stayOnTab
|
||||
)
|
||||
|
||||
assert_equal(0, @browser.find_elements(css: '.tasks .task').count)
|
||||
task_count_equals(0)
|
||||
|
||||
# cleanup
|
||||
tasks_close_all()
|
||||
|
|
|
@ -4,8 +4,9 @@ require 'browser_test_helper'
|
|||
|
||||
class AgentUserManageTest < TestCase
|
||||
def test_agent_customer_ticket_create
|
||||
customer_user_email = "customer-test-#{rand(999_999)}@example.com"
|
||||
firstname = 'Customer Firstname'
|
||||
random_number = rand(999_999)
|
||||
customer_user_email = "customer-test-#{random_number}@example.com"
|
||||
firstname = "Customer Firstname #{random_number}"
|
||||
lastname = 'Customer Lastname'
|
||||
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="#ticket/create"]')
|
||||
|
||||
watch_for(
|
||||
css: '.content.active .newTicket',
|
||||
timeout: 1,
|
||||
)
|
||||
await_text(text: 'New Ticket')
|
||||
|
||||
# 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"]')
|
||||
|
||||
|
@ -77,11 +78,13 @@ class AgentUserManageTest < TestCase
|
|||
css: '.content.active .newTicket input[name="customer_id_completion"]',
|
||||
value: fullname,
|
||||
)
|
||||
sleep 4
|
||||
|
||||
# call new ticket screen again
|
||||
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="#ticket/create"]')
|
||||
|
||||
|
|
|
@ -160,13 +160,11 @@ class FormTest < TestCase
|
|||
value: "some text\nnew line",
|
||||
)
|
||||
click(
|
||||
browser: customer,
|
||||
css: 'body div.zammad-form-modal button[type="submit"]',
|
||||
browser: customer,
|
||||
css: 'body div.zammad-form-modal button[type="submit"]',
|
||||
expect_alert: true,
|
||||
)
|
||||
|
||||
# check warning
|
||||
alert = customer.switch_to.alert
|
||||
alert.dismiss()
|
||||
sleep 10
|
||||
|
||||
# fill form invalid data - within correct time
|
||||
|
|
|
@ -28,7 +28,8 @@ class SwitchToUserTest < TestCase
|
|||
css: '.content.active .dropdown--actions',
|
||||
)
|
||||
click(
|
||||
css: '.content.active .icon-switchView',
|
||||
css: '.content.active .icon-switchView',
|
||||
ajax: false
|
||||
)
|
||||
sleep 3
|
||||
|
||||
|
@ -42,7 +43,7 @@ class SwitchToUserTest < TestCase
|
|||
)
|
||||
login = @browser.find_elements({ css: '.user-menu .user a' })[0].attribute('title')
|
||||
assert_equal(login, 'nicole.braun@zammad.org')
|
||||
click(css: '.switchBackToUser .js-close')
|
||||
click(css: '.switchBackToUser .js-close', ajax: false)
|
||||
|
||||
sleep 5
|
||||
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 params[:wait] if params[:wait]
|
||||
|
||||
if params[:expect_alert]
|
||||
check_alert(params)
|
||||
else
|
||||
await_empty_ajax_queue(params)
|
||||
end
|
||||
end
|
||||
|
||||
=begin
|
||||
|
@ -825,6 +831,7 @@ class TestCase < ActiveSupport::TestCase
|
|||
end
|
||||
|
||||
sleep 0.2
|
||||
await_empty_ajax_queue(params)
|
||||
end
|
||||
|
||||
=begin
|
||||
|
@ -880,6 +887,8 @@ class TestCase < ActiveSupport::TestCase
|
|||
dropdown.select_by(:text, params[:value])
|
||||
#puts "select2 - #{params.inspect}"
|
||||
end
|
||||
|
||||
await_empty_ajax_queue(params)
|
||||
end
|
||||
|
||||
=begin
|
||||
|
@ -1265,16 +1274,17 @@ set type of task (closeTab, closeNextInOverview, stayOnTab)
|
|||
|
||||
=end
|
||||
|
||||
def verify_task(params = {}, fallback = false)
|
||||
def verify_task(params = {})
|
||||
switch_window_focus(params)
|
||||
log('verify_task', params)
|
||||
|
||||
instance = params[:browser] || @browser
|
||||
data = params[:data]
|
||||
|
||||
sleep 1
|
||||
|
||||
begin
|
||||
retries ||= 0
|
||||
sleep 1
|
||||
|
||||
# verify title
|
||||
if data[:title]
|
||||
title = instance.find_elements(css: '.tasks .is-active')[0].text.strip
|
||||
|
@ -1318,10 +1328,8 @@ set type of task (closeTab, closeNextInOverview, stayOnTab)
|
|||
end
|
||||
end
|
||||
rescue => e
|
||||
# just try again
|
||||
if !fallback
|
||||
verify_task(params, true)
|
||||
end
|
||||
retries += 1
|
||||
retry if retries < 5
|
||||
raise "ERROR: #{e.inspect}"
|
||||
end
|
||||
true
|
||||
|
@ -1572,6 +1580,7 @@ wait untill text in selector disabppears
|
|||
.key_up(:control)
|
||||
.perform
|
||||
screenshot(browser: instance, comment: 'shortcut_after')
|
||||
await_empty_ajax_queue(params)
|
||||
end
|
||||
|
||||
=begin
|
||||
|
@ -1588,6 +1597,7 @@ wait untill text in selector disabppears
|
|||
log('window_keys', params)
|
||||
instance = params[:browser] || @browser
|
||||
instance.action.send_keys(params[:value]).perform
|
||||
await_empty_ajax_queue(params)
|
||||
end
|
||||
|
||||
=begin
|
||||
|
@ -2122,19 +2132,14 @@ wait untill text in selector disabppears
|
|||
mute_log: true,
|
||||
)
|
||||
|
||||
found = false
|
||||
7.times do
|
||||
element = instance.find_elements(css: '.content.active .newTicket')[0]
|
||||
if element
|
||||
found = true
|
||||
break
|
||||
end
|
||||
sleep 1
|
||||
end
|
||||
if !found
|
||||
screenshot(browser: instance, comment: 'ticket_create_failed')
|
||||
raise 'no ticket create screen found!'
|
||||
end
|
||||
watch_for(
|
||||
browser: instance,
|
||||
css: '.content.active .newTicket',
|
||||
timeout: 30,
|
||||
)
|
||||
|
||||
# Rumors say there is a modal reaper which will kill your modals if you dont sleep before a new ticket create
|
||||
sleep 3
|
||||
|
||||
if data[:group]
|
||||
if data[:group] == '-NONE-'
|
||||
|
@ -2570,6 +2575,7 @@ wait untill text in selector disabppears
|
|||
end
|
||||
|
||||
instance.find_elements(css: '.content.active .js-submit')[0].click
|
||||
await_empty_ajax_queue(params)
|
||||
|
||||
# do not stay on tab
|
||||
if params[:task_type] == 'closeTab' || params[:task_type] == 'closeNextInOverview'
|
||||
|
@ -2867,7 +2873,7 @@ wait untill text in selector disabppears
|
|||
instance = params[:browser] || @browser
|
||||
|
||||
instance.find_elements(css: '.js-overviewsMenuItem')[0].click
|
||||
sleep 2
|
||||
await_empty_ajax_queue(params)
|
||||
|
||||
execute(
|
||||
browser: instance,
|
||||
|
@ -2878,18 +2884,28 @@ wait untill text in selector disabppears
|
|||
# js: '$(".content.active .overview-header").css("display", "none")',
|
||||
#)
|
||||
|
||||
overviews = {}
|
||||
instance.find_elements(css: '.content.active .sidebar a[href]').each do |element|
|
||||
url = element.attribute('href')
|
||||
url.gsub!(%r{(http|https)://.+?/(.+?)$}, '\\2')
|
||||
overviews[url] = 0
|
||||
#puts url.inspect
|
||||
#puts element.inspect
|
||||
end
|
||||
overviews.each_key do |url|
|
||||
count = instance.find_elements(css: ".content.active .sidebar a[href=\"#{url}\"] .badge")[0].text
|
||||
overviews[url] = count.to_i
|
||||
begin
|
||||
overviews = {}
|
||||
instance.find_elements(css: '.content.active .sidebar a[href]').each do |element|
|
||||
url = element.attribute('href')
|
||||
url.gsub!(%r{(http|https)://.+?/(.+?)$}, '\\2')
|
||||
overviews[url] = 0
|
||||
#puts url.inspect
|
||||
#puts element.inspect
|
||||
end
|
||||
|
||||
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
|
||||
|
||||
log('overview_counter', overviews)
|
||||
overviews
|
||||
end
|
||||
|
@ -3340,6 +3356,7 @@ wait untill text in selector disabppears
|
|||
element.send_keys(data[:name])
|
||||
|
||||
instance.find_elements(css: '.modal button.js-submit')[0].click
|
||||
await_empty_ajax_queue(params)
|
||||
modal_disappear(
|
||||
browser: instance,
|
||||
timeout: 5,
|
||||
|
@ -3458,6 +3475,7 @@ wait untill text in selector disabppears
|
|||
element.clear
|
||||
element.send_keys(data[:first_response_time_in_text])
|
||||
instance.find_elements(css: '.modal button.js-submit')[0].click
|
||||
await_empty_ajax_queue(params)
|
||||
modal_disappear(browser: instance)
|
||||
7.times do
|
||||
element = instance.find_elements(css: 'body')[0]
|
||||
|
@ -3661,6 +3679,7 @@ wait untill text in selector disabppears
|
|||
dropdown.select_by(:text, data[:signature])
|
||||
end
|
||||
instance.find_elements(css: '.modal button.js-submit')[0].click
|
||||
await_empty_ajax_queue(params)
|
||||
modal_disappear(browser: instance)
|
||||
|
||||
element = instance.find_elements(css: 'body')[0]
|
||||
|
@ -3673,6 +3692,7 @@ wait untill text in selector disabppears
|
|||
data[:member]&.each do |member|
|
||||
instance.find_elements(css: 'a[href="#manage"]')[0].click
|
||||
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
|
||||
sleep 3
|
||||
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.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
|
||||
await_empty_ajax_queue(params)
|
||||
modal_disappear(browser: instance)
|
||||
end
|
||||
end
|
||||
|
@ -3933,6 +3954,8 @@ wait untill text in selector disabppears
|
|||
css: '.content.active a[href="#manage/roles"]',
|
||||
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()))
|
||||
|
||||
modal_ready(browser: instance)
|
||||
|
@ -4830,4 +4853,124 @@ wait untill text in selector disabppears
|
|||
screenshot(browser: instance, comment: "object_manager_attribute_#{action}_failed")
|
||||
raise "object_manager_attribute_#{action}_failed"
|
||||
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
|
||||
|
|
Loading…
Reference in a new issue