browser_test_helper.rb 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124
  1. module BrowserTestHelper
  2. # Finds an element and clicks it - wrapped in one method.
  3. #
  4. # @example
  5. # click('.js-channel .btn.email')
  6. #
  7. # click(:href, '#settings/branding')
  8. #
  9. def click(*args)
  10. find(*args).click
  11. end
  12. # This is a wrapper around the Selenium::WebDriver::Wait class
  13. # with additional methods.
  14. # @see BrowserTestHelper::Waiter
  15. #
  16. # @example
  17. # wait(5).until { ... }
  18. #
  19. # @example
  20. # wait(5, interval: 0.5).until { ... }
  21. #
  22. def wait(seconds = Capybara.default_max_wait_time, **kargs)
  23. wait_args = Hash(kargs).merge(timeout: seconds)
  24. wait_handle = Selenium::WebDriver::Wait.new(wait_args)
  25. Waiter.new(wait_handle)
  26. end
  27. # Moves the mouse from its current position by the given offset.
  28. # If the coordinates provided are outside the viewport (the mouse will end up outside the browser window)
  29. # then the viewport is scrolled to match.
  30. #
  31. # @example
  32. # move_mouse_by(x, y)
  33. # move_mouse_by(100, 200)
  34. #
  35. def move_mouse_by(x_axis, y_axis)
  36. page.driver.browser.action.move_by(x_axis, y_axis).perform
  37. end
  38. # Clicks and hold (without releasing) in the middle of the given element.
  39. #
  40. # @example
  41. # click_and_hold(ticket)
  42. # click_and_hold(tr[data-id='1'])
  43. #
  44. def click_and_hold(element)
  45. page.driver.browser.action.click_and_hold(element).perform
  46. end
  47. # Releases the depressed left mouse button at the current mouse location.
  48. #
  49. # @example
  50. # release_mouse
  51. #
  52. def release_mouse
  53. page.driver.browser.action.release.perform
  54. end
  55. class Waiter < SimpleDelegator
  56. # This method is a derivation of Selenium::WebDriver::Wait#until
  57. # which ignores Capybara::ElementNotFound exceptions raised
  58. # in the given block.
  59. #
  60. # @example
  61. # wait(5).until_exists { find('[data-title="example"]') }
  62. #
  63. def until_exists
  64. self.until do
  65. yield
  66. rescue Capybara::ElementNotFound # rubocop:disable Lint/HandleExceptions
  67. end
  68. rescue Selenium::WebDriver::Error::TimeOutError => e
  69. # cleanup backtrace
  70. e.set_backtrace(e.backtrace.drop(3))
  71. raise e
  72. end
  73. # This method is a derivation of Selenium::WebDriver::Wait#until
  74. # which ignores Capybara::ElementNotFound exceptions raised
  75. # in the given block.
  76. #
  77. # @example
  78. # wait(5).until_disappear { find('[data-title="example"]') }
  79. #
  80. def until_disappears
  81. self.until do
  82. yield
  83. false
  84. rescue Capybara::ElementNotFound
  85. true
  86. end
  87. rescue Selenium::WebDriver::Error::TimeOutError => e
  88. # cleanup backtrace
  89. e.set_backtrace(e.backtrace.drop(3))
  90. raise e
  91. end
  92. # This method loops a given block until the result of it is constant.
  93. #
  94. # @example
  95. # wait(5).until_constant { find('.total').text }
  96. #
  97. def until_constant
  98. previous = nil
  99. loop do
  100. sleep __getobj__.instance_variable_get(:@interval)
  101. latest = yield
  102. break if latest == previous
  103. previous = latest
  104. end
  105. end
  106. end
  107. end
  108. RSpec.configure do |config|
  109. config.include BrowserTestHelper, type: :system
  110. end