RSpec + безголовый Chrome для внешнего интеграционного теста

Я пытаюсь протестировать часть своего приложения Rails 5.1, в котором используется Vue.js. Проблема, с которой я сталкиваюсь, заключается в том, что, например, при создании списка код Vue выглядит так:

<div v-for="(amenity, idx) in amenities">
  <div class="custom-control custom-checkbox">
    <input type="checkbox" class="custom-control-input" v-bind:id="amenity.text" v-model="checkedAmenities[idx]" :value="amenity.id">
    <label class="custom-control-label" v-bind="{ 'for': amenity.text }" >{{ amenity.text }}</label>
  </div>
</div>

и фактический HTML, который это создает после оценки, выглядит следующим образом:

<div>
  <div class="custom-control custom-checkbox">
    <input id="Air conditioning" class="custom-control-input" value="0" type="checkbox"> <label for="Air conditioning" class="custom-control-label">Air conditioning</label>
  </div>
</div>

В итоге я получаю эту ошибку в своих спецификациях:

Capybara::ElementNotFound:
  Unable to find visible checkbox "Some amenity" that is not disabled

Это связано с тем, что удобства определены в компоненте Vue, но не выводятся в HTML, пока они не будут проанализированы интерпретатором JS, как мне кажется.

Я пытаюсь протестировать Chrome Headless. Я создал следующий файл chrome_driver.rb:

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

и в моем rails_helper.rb:

require 'selenium/webdriver'

RSpec.configure do |config|
  # ...
  Capybara.javascript_driver = :headless_chrome
end

мой тест RSpec выглядит примерно так:

scenario 'successfully', js: true do
  # do some things here..

  check('Some amenity')
  click_button 'Next'
  click_link 'Create Listing'

  expect(page).to have_content 'Listing was created successfully!'
end

но, как уже упоминалось, ошибка, которую я получаю:

Capybara::ElementNotFound:
  Unable to find visible checkbox "Some amenity" that is not disabled

Любая идея, как я могу заставить Chrome безголовый анализировать код Vue.js, чтобы удобства заполнялись во внешнем интерфейсе?

Заранее спасибо!!


person DaniG2k    schedule 02.04.2018    source источник


Ответы (2)


Судя по именам классов обертки div, custom-control custom-checkbox, я почти уверен, что проблема здесь не в том, что поля заполняются неправильно (вы можете использовать save_and_open_screenshot, чтобы проверить это, или вывести page.html), а скорее в фактическом html Элемент <input type="checkbox" ...> на самом деле не виден на странице (как говорит вам ошибка). Это, вероятно, было сделано для того, чтобы придать флажку причудливый стиль, показывая изображения для отмеченных/не отмеченных состояний. Чтобы установить флажок в этом случае, у вас есть несколько вариантов. Первый вариант — выяснить, какой элемент на самом деле нужно щелкнуть пользователю, чтобы изменить настройку, и позволить Capybara сделать это. Например

find(:label, 'Some amenity').click

Более чистое решение, когда есть правильно связанный элемент метки, состоит в том, чтобы сообщить методу check, что ему разрешено щелкнуть метку, если это необходимо.

check('Some amenity', allow_label_click: true)

Если вы хотите, чтобы check, uncheck и choose всегда разрешалось щелкать соответствующую метку, когда флажок/переключатель скрыт, вы можете сделать это по умолчанию, установив

Capybara.automatic_label_click = true
person Thomas Walpole    schedule 02.04.2018
comment
Правильно, я использую Bootstrap 4 custom-checkbox, который действительно создает флажок ввода, который не является фактическим input[type="checkbox"]. Последний, вероятно, выбирается с помощью Javascript после нажатия пользовательского флажка. Тем не менее, я до сих пор не смог заставить его работать с описанными вами методами. Я буду продолжать пытаться увидеть, нужно ли мне выбрать что-то еще. - person DaniG2k; 02.04.2018
comment
@DaniG2k Добавьте в свой вопрос фактический HTML-код, созданный для этого элемента управления, а не шаблон vue, потому что похоже, что ваши элементы label, вероятно, на самом деле неправильно связаны с флажками. - person Thomas Walpole; 02.04.2018
comment
Хорошо, я добавил фактически сгенерированный HTML к вопросу для примера удобства. - person DaniG2k; 02.04.2018
comment
@ DaniG2k И это ваша проблема - идентификаторы HTML не могут содержать пробелы, что означает, что атрибут for фактически не связывает метку с флажком - вы хотите использовать что-то другое, кроме текста, для атрибута id ввода и атрибут for метки - person Thomas Walpole; 02.04.2018
comment
@ DaniG2k Это решило вашу проблему? Если это так, пожалуйста, не забудьте принять ответ, чтобы вопрос был помечен как отвеченный. - person Thomas Walpole; 03.04.2018

Если ваша метка содержит ссылку, она будет нажата, а не сам флажок:

check('Some amenity', allow_label_click: true)

Вы можете решить это следующим образом:

check('Some amenity', visible: :hidden)
person Zoran Kikic    schedule 01.04.2019