Сопоставители Capybara RSpec ждут элементов?

При написании тестовой среды/тестов с использованием Capybara + RSpec я столкнулся с этим предложением для тестирования НЕ существования элемента:

expect(page).to have_no_button('Save')   # OK
expect(page).not_to have_button('Save')  # Bad

Я был смущен, почему, пока не увидел, что было сказано:

Use should have_no_* versions with RSpec matchers because should_not have_* doesn’t wait for a timeout from the driver.

Это правда? Если нет... не имеет ли смысл с точки зрения объектной модели страницы иметь метод для проверки и возврата, существует ли <element> (я обычно использую .visible?), чтобы вы могли использовать сопоставитель rspec для выполнения expect(page_object).to be_method_visible или expect(page_object).not_to be_method_visible?

В отличие от необходимости писать 2 отдельных метода в объектах вашей страницы (если это правда, что not_to не будет ждать)

В качестве примера моих методов утверждения в моей объектной модели страницы, вот что я делаю для проверки «ссылки для выхода»

def logged_in?
    logout_text.visible?
end

private
def logout_text
    find 'a', text: 'Log Out'
end

И тогда в спецификации я бы сказал: expect(page_object).to be_logged_in

Поэтому я бы использовал что-то подобное для других элементов.

Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
0
617
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Я не знаю, где вы наткнулись на это предложение (может быть, оно действительно очень старое), но для любой «последней» версии Capybara (по крайней мере, за последние 4 года) при использовании предоставленных Capybara сопоставителей это неверно.

Предполагая, что have_button и have_no_button являются предоставленными Capybara сопоставителями (а не встроенным have_xxx => has_xxx? сопоставителем RSpecs, вызывающим has_button? метод, который вы определили на своем объекте страницы), два приведенных вами примера

expect(page).to have_no_button('Save')
expect(page).not_to have_button('Save')

будет вести себя одинаково. Они оба проверяют наличие кнопки и возвращаются, когда ее не существует, или вызывают исключение, если Capybara.default_max_wait_time секунд прошло, а кнопка все еще видна на странице.

Эти примеры были взяты с сайта, который я видел. В основном я хочу проверить, что кнопка НЕ ​​существует. Я занимаюсь объектной моделью страницы... поэтому мне имело смысл создать метод, который возвращает логическое значение, если кнопка visible?, а затем просто использовать .to be_method или .not_to be_method. Возможно, я неправильно использую сопоставители rspec, так как я использую to be вместо to have, но я возвращаю логическое значение из моих методов (редактирование сделано в посте)

msmith1114 09.04.2019 17:49

@msmith1114 msmith1114 Проблема с асинхронным поведением браузера заключается в том, что вам нужно поведение ожидания для стабильности теста. Если вы вызываете логические методы, это будет означать, что иногда вы ожидаете, что оно будет истинным, а иногда ложным - какое из них следует ожидать? С утверждениями/ожиданиями Капибара может точно знать, чего ждать. Если вы используете логические методы, вы, вероятно, захотите отключить в них ожидание, а затем самостоятельно обрабатывать ожидание/стабильность.

Thomas Walpole 09.04.2019 17:54

@msmith Чтение вашего обновленного вопроса - метод logged_in? никогда не будет работать - если не существует ссылки с «Выйти из системы» (должно быть выполнено как find_link('Log Out'), а не как селектор CSS) (или если ссылка не видна), find поднимется исключение - так что он никогда не доберется до вызова visible? на нем

Thomas Walpole 09.04.2019 18:06

Как мне тогда структурировать его в объекте страницы? Я пытаюсь не использовать методы селена/капибары в реальной спецификации. Я хочу иметь метод, который я могу утверждать (внутри самой тестовой спецификации, а не иметь утверждение в объекте страницы)

msmith1114 09.04.2019 18:13

@ msmith1114 Именно поэтому объект страницы так основан на мнении. Для того, что вы хотите, вы, вероятно, хотите написать свои собственные сопоставители RSpec (или, по крайней мере, иметь методы, которые возвращают экземпляры сопоставителей Capybara) и включить их в свой тестовый класс, т.е. вам нужно получить метод с именем be_logged_in доступен в вашем тестовом примере, который возвращает Capybaras have_link('Log Out'), чтобы вы могли затем вызвать expect(page).to be_logged_in - есть много способов, которыми вы могли бы закончить с этим, проще всего, вероятно, перезаписать стандартное поведение RSpecs be_xxx

Thomas Walpole 09.04.2019 18:20

Похоже, я вроде как просто против правдивости, верно? Или, если он терпит неудачу, он на самом деле не возвращает истинное или ложное значение из этих методов, если элемент не существует, поэтому он всегда будет говорить, что он успешен? (Потому что сейчас кажется, что to be_method_true, по крайней мере, не «проваливается» при тестировании)

msmith1114 09.04.2019 20:42

@ msmith1114 Я не знаю, что вы имеете в виду под to be_method_true, но все может работать нормально, пока у вас не будет асинхронного поведения на странице — или вы можете возвращать правдивый объект, который никогда не выйдет из строя, или сообщения об ошибках при сбое могут выглядеть как будто они не имеют ничего общего с тем, что вы утверждаете. т.е. Ваш 'is_logged_in?' метод никогда не может вернуть false, поэтому expect(page).to be_logged_in вполне может работать, если элемент находится на странице, но expect(page).not_to be_logged_in? не может работать.

Thomas Walpole 09.04.2019 21:06

Другие вопросы по теме