diff --git a/spec/support/capybara/browser_test_helper.rb b/spec/support/capybara/browser_test_helper.rb index 54f8c8ee1..02baeef72 100644 --- a/spec/support/capybara/browser_test_helper.rb +++ b/spec/support/capybara/browser_test_helper.rb @@ -1,5 +1,35 @@ module BrowserTestHelper + # Sometimes tests refer to elements that get removed/re-added to the DOM when + # updating the UI. This causes Selenium to throw a StaleElementReferenceError exception. + # This method catches this error and retries the given amount of times re-raising + # the exception if the element is still stale. + # @see https://developer.mozilla.org/en-US/docs/Web/WebDriver/Errors/StaleElementReference WebDriver definition + # + # @example + # retry_on_stale do + # find('.now-here-soon-gone').click + # end + # + # retry_on_stale(retries: 10) do + # find('.now-here-soon-gone').click + # end + # + # @raise [Selenium::WebDriver::Error::StaleElementReferenceError] If element is still stale after given number of retries + def retry_on_stale(retries: 3) + tries ||= 0 + + yield + rescue Selenium::WebDriver::Error::StaleElementReferenceError + raise if tries == retries + + wait_time = tries + tries += 1 + + Rails.logger.info "Stale element found. Retry #{tries}/retries (sleeping: #{wait_time})" + sleep wait_time + end + # Finds an element and clicks it - wrapped in one method. # # @example diff --git a/spec/support/capybara/common_actions.rb b/spec/support/capybara/common_actions.rb index 18d218ec9..684cb95ab 100644 --- a/spec/support/capybara/common_actions.rb +++ b/spec/support/capybara/common_actions.rb @@ -180,11 +180,13 @@ module CommonActions end def open_article_meta - wrapper = all(%(div.ticket-article-item)).last + retry_on_stale do + wrapper = all('div.ticket-article-item').last - wrapper.find('.article-content .textBubble').click - wait(3).until do - wrapper.find('.article-content-meta .article-meta.top').in_fixed_position + wrapper.find('.article-content .textBubble').click + wait(3).until do + wrapper.find('.article-content-meta .article-meta.top').in_fixed_position + end end end