Рубин Селен Капибара не истекает - PullRequest
0 голосов
/ 08 мая 2018

У меня проблемы с моими спецификациями, не истекающими.Некоторые из моих спецификаций доходят до определенной точки и просто зависают.Я уверен, что что-то не так с одной из спецификаций, приводящей к ее поломке, но я не могу понять, почему они просто зависают бесконечно, когда у меня определено время ожидания ...

# frozen-string-literal: true
require 'rspec'
require 'capybara/rspec'
require 'capybara/dsl'
require 'selenium-webdriver'
require 'site_prism'

Dir[File.dirname(__FILE__) + '/page_objects/*/*.rb'].each do |page_object|
  require page_object
end

def wait_for_ajax
  Timeout.timeout(Capybara.default_max_wait_time) do
    loop until page.evaluate_script('jQuery.active').zero? && page.has_no_css?(".k-loading-color")
  end
end

def whole_page
  Capybara.current_session
end

Capybara.register_driver :selenium do |app|
  Capybara::Selenium::Driver.new(app, browser: :chrome)
end

Capybara.default_driver = :selenium
Capybara.app_host = #REDACTED
Capybara.default_max_wait_time = 20

RSpec.configure do |config|
  config.before(:each) do
    config.include Capybara::DSL
  end

  config.after(:each) do
    Capybara.reset_sessions! 
  end
end

1 Ответ

0 голосов
/ 08 мая 2018

Вы не упоминаете, над какими командами он висит, но я собираюсь догадаться, что это ваш wait_for_ajax метод. Если это так, то это потому, что вы используете Timeout.timeout, который является наиболее опасным для использования методом, предоставляемым Ruby. Это работает путем запуска второго потока, который будет вызывать исключение в исходном потоке по истечении времени ожидания. Проблема в том, что исключение может возникнуть в любом месте исходного потока, что означает, что если блок внутри вызова timeout делает что-то нетривиальное, он может оказаться в полностью невосстановимом состоянии (сетевые соединения и т. Д.). В принципе, Timeout.timeout может быть безопасно использован только с ОЧЕНЬ детальным знанием каждой мелочи, происходящей в его блоке, что означает, что его эффективно никогда не следует использовать ни при каких вызовах в стороннюю библиотеку. Вместо этого вы должны просто использовать таймер и спать, если вам нужно время ожидания. Что-то вроде

def wait_for_ajax
  start = Time.now
  until page.evaluate_script('jQuery.active').zero? && page.has_no_css?(".k-loading-color", wait: false) do
    sleep 0.1
    raise <Some Error> if (Time.now - start) > Capybara.default_max_wait_time
  end
end

Как говорится, вам действительно не нужно wait_for_ajax с удобным интерфейсом и правильно написанными тестами.

Кроме того, включив capybara/rspec, вы уже настроили для вызова reset_sessions после каждого теста и для включения Capybara::DSL в типы тестов, которые должны быть включены в - https://github.com/teamcapybara/capybara/blob/master/lib/capybara/rspec.rb#L9 - поэтому, добавляя свой собственный блок after, вы просто заканчиваете тем, что вызываете reset_sessions дважды после каждого теста, который является пустой тратой времени.

...