Убедитесь, что элемент отсутствует с помощью Capybara

Используя Capybara, мне нужно утверждать, что элемент формы отсутствует, например, «Тогда я не должен видеть текстовое поле «Имя пользователя»». Поскольку find выдает исключение, если элемент не найден, это лучшее, что я придумал. Есть ли способ лучше?

Then /^I should not see the "([^\"]+)" ([^\s]+) field$/ do |name, type|
  begin
    # Capybara throws an exception if the element is not found
    find(:xpath, "//input[@type='#{type}' and @name='#{name}']")
    # We get here if we find it, so we want this step to fail
    false
  rescue Capybara::ElementNotFound
    # Return true if there was an element not found exception
    true
  end 
end

Я новичок в Capybara, поэтому могу упустить что-то очевидное.


person michaeltwofish    schedule 06.05.2011    source источник


Ответы (7)


Вы можете сделать это, используя капибары has_no_selector? метод в сочетании с магическими сопоставлениями rspecs. Затем вы можете использовать его следующим образом:

 page.should have_no_selector(:xpath, "//input[@type='#{type}' and @name='#{name}']")

Более подробную информацию об утверждениях, которые вы можете выполнять, можно найти на странице документации капибары здесь в разделе "Запросы".

person Derek Ekins    schedule 06.05.2011
comment
Я знал, что упускаю из виду что-то очевидное :) - person michaeltwofish; 07.05.2011
comment
Стоит отметить, что это решение не позволяет Capybara ожидать появления элемента, поэтому с ним ваши тесты должны выполняться быстрее. Кстати, вы также можете сделать page.should have_no_field(name). - person djanowski; 22.08.2013
comment
Также, для всех, кто интересуется. page.should_not have_xpath("...") не сработало, а этот способ сработал! Спасибо! Редактировать: неважно... говорил слишком рано - person Alex Villa; 21.03.2014
comment
также стоит отметить, что вы также можете использовать селекторы css: have_no_selector(:css, '#my-dom-id') - person Shawn; 10.06.2014

Фактически вы можете использовать уже существующие методы, определенные сопоставителями Capybara.

assert has_no_field?('Username')

Кроме того, доступны дополнительные методы, которые могут помочь вам найти различные типы элементов на вашей странице.

has_link? , has_no_link?
has_button?, has_no_button?
has_field?, has_no_field?
has_checked_field?, has_no_checked_field?
has_select?, has_no_select?

И многое другое. . .

person 5_nd_5    schedule 21.02.2014
comment
Важно выделить в верхней части списка: has_css? / has_no_css? Пример: assert has_no_css?('.my-class') assert has_no_css?('#my-id') Источник: devhints.io/capybara Вы также можете добавить == false или == true, если хотите получить дополнительное описание (хотя это и не обязательно) - person PolarisTLX; 09.04.2019

Вот что я использую:

expect(page).to have_no_css('.test')
person nroose    schedule 16.02.2016
comment
спасибо за это простое и чистое решение. я научился использовать множество динамически создаваемых идентификаторов элементов для оптимизации спецификаций функций, и это именно то, что мне было нужно прямо сейчас, чтобы справиться с моим набором тестов... спасибо - person Florian Eck; 31.10.2016

Я попробовал решение, предложенное Дереком, однако столкнулся с некоторыми ложноотрицательными результатами.

Это

page.should have_no_selector(:xpath, "//input[@type='#{type}' and @name='#{name}']")

проходит даже тогда, когда по какой-то причине он должен выйти из строя.

Я добился успеха с синтаксисом RSpec raise_error

expect { find(:xpath, "//input[@type='#{type}' and @name='#{name}']") }.to raise_error

Я думаю, что это ближе к тому, что вы спрашиваете в любом случае. Поэтому я выдвинул это в качестве ответа.

person Zack Xu    schedule 04.11.2013
comment
Этот! Я даже не понимаю, для чего нужен have_no_selector, если он не ждет... - person smoyth; 19.05.2015

Лучший способ сделать это — найти элемент и утверждать, что его нет. Это не только создает повторно используемый код, но и весь тест не взорвется, если не сможет его найти.

Вот что я делаю...

определить свой объект

def username
    page.find('.username')
end

Затем взаимодействуйте с объектом в вашем файле спецификаций.

username.should be_true

Вам действительно все равно, находится ли элемент на странице (в большинстве случаев). Что вас волнует, когда вы пишете тесты, так это то, можете ли вы взаимодействовать с этим элементом... вот почему я сначала определяю объект, а затем использую "имя пользователя" для взаимодействия с ним... посмотрите, сколько повторно используемого кода вы можете сгенерировать? Теперь вы можете щелкнуть, навести курсор, подтвердить наличие элемента, ввести текст в элемент и т. д.

Кроме того, вам определенно следует рассмотреть возможность использования css вместо xpath, когда это возможно. xpath легче взломать и сложнее прочитать.

person Whitney Imura    schedule 16.05.2013
comment
Эй, Уитни, метод find вызывает исключение ElementNotFoundException, которого OP пытается избежать. Как ваш метод обходит это? - person Derek Ekins; 20.06.2013
comment
Положительное утверждение, что тег исчез, — это то, для чего Capybara; тестирование слоя представления с его динамическим JavaScript. - person Phlip; 25.01.2014

У меня такая же проблема. Но так как я использую Capybara с Minitest, принятое решение мне не помогло. Я подумал, что должен добавить это, если кто-то в той же ситуации, что и я, найдет этот вопрос.

Также можно использовать:

assert page.has_no_xpath?('//input[@type='#{type}' and @name='#{name}'"]')

person Kristiina    schedule 10.07.2013

В файле спецификации

expect(@app.some_page_name.is_visible?('search_button')) == true

В файле страницы

element :search_button, :xpath, "//div[@class='dummy']"

В файле base_page

def is_visible?(value)
  begin
    eval(value).visible?
    return true
  rescue => e
    p e.message
    return false
  end
end
person Prashanth Sams    schedule 16.07.2019