123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179 |
- # Copyright (C) 2012-2024 Zammad Foundation, https://zammad-foundation.org/
- class Capybara::Node::Element
- # This is an extension to each node to check if the element
- # is moving or in a fixed position. This is especially helpful
- # for animated elements that cause flanky tests.
- # NOTE: In CI env a special sleep is performed between checks
- # because animations can be slow.
- #
- # @param [Integer] checks the number of performed movement checks
- #
- # @example
- # find('.clues-close').in_fixed_position.click
- # => waits till clues moved to final position and performs click afterwards
- #
- # @raise [RuntimeError] raised in case the element is
- # still moving after max number of checks was passed
- #
- # @return [Capybara::Node::Element] the element/node
- def in_fixed_position(checks: 100, wait: 0.2)
- previous = native.location
- (checks + 1).times do
- sleep wait
- current = native.location
- return self if previous == current
- previous = current
- end
- raise "Element still moving after #{checks} checks"
- end
- end
- module ZammadCapybarActionDelegator
- def select(...)
- super.tap do
- await_empty_ajax_queue
- end
- end
- def unselect(...)
- 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(...)
- 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
- def fill_in(...)
- super.tap do
- await_empty_ajax_queue
- end
- end
- def hot_keys
- mac_platform? ? %i[control alt] : %i[shift control]
- end
- def magic_key
- mac_platform? ? :command : :control
- end
- def mac_platform?
- Gem::Platform.local.os.eql? 'darwin'
- end
- def check(...)
- 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
- attr_reader :element
- include ZammadCapybarSelectorDelegator
- def initialize(context:, element:)
- @context = context
- @element = element
- 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
|