Capybara / Selenium / Chrome: тест проходит только при вызове save_screenshot

#ruby-on-rails #selenium #rspec #capybara

#ruby-on-rails #селен #rspec #capybara

Вопрос:

Я нахожусь в процессе перехода с Poltergeist на безголовый Chrome.

Gemfile:

 group :test do
  # Capybara - Headless, JavaScript-executing browser for Selenium
  gem 'selenium-webdriver'  # Selenium webdriver (needed to use Chrome driver)
  gem 'webdrivers', '~> 4.0', require: false # Run Selenium tests more easily with automatic installation and updates for all supported webdrivers.
  gem 'capybara-screenshot' # Automatically save screen shots when a scenario fails
  ...
end
 

spec/support/capybara.rb:

 Capybara.javascript_driver = :selenium_chrome_headless
 

У меня есть спецификация, которая проверяет, применяет ли фокусировка элемента класс CSS к элементу.

 it 'shows the fullscreen toggler on focus', js: true do
  visit new_user_path
  page.execute_script("$('#user_about').focus()")
  expect(page).to have_css '.textarea-fullscreenizer-toggler'
end
 

С Poltergeist он прошел. С :selenium_chrome_headless ним не:

 expected to find visible css ".textarea-fullscreenizer-toggler" within #<Capybara::Node::Element tag="div" path="/HTML/BODY[1]/MAIN[1]/DIV[1]/DIV[1]/FORM[1]/FIELDSET[1]/DIV[1]/DIV[1]/DIV[5]"> but there were no matches. Also found "", which matched the selector but not all filters. 
 

При :selenium_chrome этом он проходит! Так что кажется, что безголовый и не безголовый водитель делают разные вещи! Это довольно неудобно.

Интересно, что при установке a save_screenshot после фокусировки элемента спецификация также проходит с безголовым chrome!

Что я могу здесь сделать? Я на правильном пути? Должен ли я попробовать https://github.com/twalpole/apparition вместо водителя?

Ответ №1:

Вы также можете попробовать что-то подобное для безголового chrome в вспомогательном файле capybara.rb.

 require "selenium/webdriver"

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

Capybara.register_driver :headless_chrome do |app|
  capabilities = Selenium::WebDriver::Remote::Capabilities.chrome(
    chromeOptions: { args: %w(headless disable-gpu) }
  )

  Capybara::Selenium::Driver.new app,
    browser: :chrome,
    desired_capabilities: capabilities
end

Capybara.javascript_driver = :headless_chrome
 

Это сработало для меня. Может сработать и для вас.

Комментарии:

1. Для меня это не запускает Chrome в headless режиме.

Ответ №2:

Мне кажется, что проблема со временем. Я предполагаю, что вызов jQuery, который вы используете для запуска фокуса, занимает некоторое время, пока сопоставитель уже выполнен. Однако, поскольку он находит элемент, который еще не виден, он выдает ошибку. Вставка скриншота может занять достаточно времени, чтобы JavaScript оценил вашу команду.

Вы пытались явно сопоставить видимый элемент, например expect(page).to have_selector('.textarea-fullscreenizer-toggler', visible: true) ? Кроме того, триггер фокусировки также может быть выполнен следующим образом: find('#user_about').trigger('focus') . Это также может решить проблему, поскольку она возвращается после запуска события.

Ответ №3:

Предоставленная вами ошибка, очевидно, не возвращается для кода, как показано, поскольку предоставленный вами код ничего не определяет и не проверяет наличие текста. В будущем было бы намного лучше, если бы ошибка соответствовала коду. При этом приведенный ниже ответ является предположением, основанным на доступной информации.

Проблема, скорее всего, в том, что ваше выполнение JS происходит до полной загрузки страницы, и поэтому страница сбрасывает фокус. Это может произойти, потому visit что не гарантирует, что страница полностью загружена / стабильна при возврате. Для синхронизации вам нужно ожидание перед execute_script вызовом, которое проверяет наличие чего-либо на странице, что указывало бы, что страница загружена / стабильна.

посетите ожидаемый путь new_user_path(страница).для have_css(‘ввод #первый_вход: фокус’) # подождите, пока первоначально сфокусированный элемент не будет загружен / отображен / сфокусирован на странице.execute_script(«$(‘#user_about’).фокус ()»)

Обратите внимание, что использование execute_script , как правило, является плохой идеей в тестах, поскольку оно не выполняет то, что сделал бы пользователь — вам было бы намного лучше, если бы Capybara выполняла любые действия, которые выполнял бы пользователь, чтобы сфокусировать элемент, о котором вы заботитесь.

Комментарии:

1. Вы правы, я удалил text: ... фильтр из кода, поскольку он не имеет отношения к делу, но забыл также удалить его из сообщения об ошибке. Скоро я подробнее рассмотрю то, что вы пишете. Спасибо.