Rspec, have_xpath против have_css фильтрация поиска в DOM

#ruby-on-rails #ruby #xpath #rspec #magicsuggest

#ruby-on-rails #ruby #xpath #rspec #magicsuggest

Вопрос:

Я использую действительно хорошую библиотеку MagicSuggest.

Базовый пример использования: здесь

Как можно видеть, как только вы инициализируете magic suggest в выбранном вами input , он добавляет новые div с предварительно исправленными class параметрами.

Чтобы отобразить возможные варианты выбора, нужно нажать на значок выпадающего списка, который Magic Suggest указывает на его предоставление class="ms-trigger" . В раскрывающемся списке показано, что имеет class="ms-res-ctn" , где каждый выбранный параметр имеет class="ms-res-item" .

Я тестирую, что всякий раз, когда я нажимаю на class="ms-res-item" , это добавляется к входным данным, а затем обновляет мою модель через ajax (хотя это другая тема).

Чего я не могу понять, так это:

 #Somewhere in my test
expect(page).to have_css('div.ms-res-item') #<-- This WORKS

expect(page).to have_xpath('.//div[@class="ms-res-item"]') #<- This DOESNT
  

Я точно знаю, что 'div > .ms-res-item' это есть, я просто не знаю, почему have_xpath или find(:xpath,...) не могу его найти, тогда как have_css могу.

** Обновление: ** Это параметры, которые я вижу после проверки DOM

 <div class="ms-res-item ms-res-item-active" data-json={"id":"paris","name":"paris"}>
<div class="ms-res-item" data-json={"id":"newyork","name":"newyork"}>
  

Ответ №1:

Имена классов CSS, добавленные к элементам DOM, являются динамическими, и поэтому иногда вы сталкиваетесь с такими вещами:

 <div class="ms-res-item " data-json="{amp;quot;idamp;quot;:amp;quot;New Yorkamp;quot;,amp;quot;nameamp;quot;:amp;quot;New Yorkamp;quot;}">New York</div>
  

Теперь, когда вы делаете это:

 expect(page).to have_xpath('.//div[@class="ms-res-item"]')
  

Он ищет точное значение "ms-res-item" для class атрибута. Как вы можете видеть, это неверно, поскольку значение просто анализируется как строка и "ms-res-item " != "ms-res-item"

Итак, 2 варианта:

1 / это проект с открытым исходным кодом. Вы можете отправить запрос на очистку определений классов (или, что еще лучше, сделайте это самостоятельно, а затем запросите запрос на слияние).

2 / вы можете изменить свой код на expect(page).to have_xpath('.//div[contains(@class,"ms-res-item")]')

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

1. Привет, Николас, очень полезный ответ! Я вообще не заметил этого пробела. Я обязательно попытаюсь очистить его сам и отправить запрос на слияние, когда у меня будет немного времени. Спасибо за эту замечательную библиотеку! 🙂

2. karlipoppins: Я отредактировал свой вопрос, добавив буквальный код, который добавляет magic-suggest. По-видимому, один из параметров имеет пробел, тогда как другой вариант нет, разве он не должен соответствовать второму? have_xpath имеет дело с динамически добавляемым контентом в DOM, не так ли?

Ответ №2:

Я думаю, вам нужен selenium для тестирования функций JS в Rspec.
1) Итак, установите драгоценный камень ‘selenium-webdriver’, ‘~> 2.42.0’. Пакет.
2) Если у вас есть проверки в ваших тестах, вам также потребуется установить gem ‘database_cleaner’, ‘~> 1.3.0’.
если вам нужен database_cleaner, вам нужно будет установить config.use_transactional_fixtures = false в spec helper и иметь файл, который выглядит следующим образом:https://gist.github.com/EvanTedesco/e2232e09cd16bb2faab4 в вашем файле поддержки спецификации.

3) после ит-блока (или сценария, который вы используете) вам нужен js: true ex:

 it "does supercool stuff", js:true do.  
end
  

4) прибыль.

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

1. привет, спасибо! Но я уже использую database_cleaner , и мне приходится использовать poltergeist driver вместо selenium по другим причинам. Также js: :true включен 🙂