Как определить количество элементов, используя Capybara с правильным сообщением об ошибке? - PullRequest
80 голосов
/ 18 июля 2011

Я знаю, что в Capybara вы можете сделать что-то вроде этого:

page.should have_css("ol li", :count => 2)

Однако, если предположить, что на странице есть, например, только один соответствующий элемент, ошибка не очень описательная:

  1) initial page load shows greetings
 Failure/Error: page.should have_css("ol li", :count => 2)
 expected css "ol li" to return something

Вместо этого довольно неясного сообщения об ошибке, есть способ написать утверждение таким образом, чтобы вывод ошибки был что-то вроде «При совпадении« ol li », ожидаемое: 2, найденное: 1».Очевидно, я мог бы сделать собственную логику для такого поведения - я спрашиваю, есть ли способ сделать это «из коробки»?

Для чего это стоит, я использую драйвер Selenium и RSpec.

Ответы [ 6 ]

168 голосов
/ 11 июня 2013

Мне это нравится намного лучше.

expect(page).to have_selector('input', count: 12)

https://github.com/jnicklas/capybara/blob/415e2db70d3b19b46a4d3d0fe62f50400f9d2b61/spec/rspec/matchers_spec.rb

22 голосов
/ 25 июля 2011

Ну, так как кажется, что поддержки нет "из коробки", я написал этот пользовательский сопоставитель:

RSpec::Matchers.define :match_exactly do |expected_match_count, selector|
    match do |context|
        matching = context.all(selector)
        @matched = matching.size
        @matched == expected_match_count
    end

    failure_message_for_should do
        "expected '#{selector}' to match exactly #{expected_match_count} elements, but matched #{@matched}"
    end

    failure_message_for_should_not do
        "expected '#{selector}' to NOT match exactly #{expected_match_count} elements, but it did"
    end
end

Теперь вы можете делать такие вещи, как:

describe "initial page load", :type => :request do
    it "has 12 inputs" do
        visit "/"
        page.should match_exactly(12, "input")
    end
end

и получим вывод наподобие:

  1) initial page load has 12 inputs
     Failure/Error: page.should match_exactly(12, "input")
       expected 'input' to match exactly 12 elements, but matched 13

Пока что все получится, я попытаюсь сделать эту часть Капибары.

14 голосов
/ 10 июля 2013

Я думаю, что следующее проще, дает довольно четкий вывод и устраняет необходимость в специальном сопоставителе.

page.all("ol li").count.should eql(2)

Затем выводится сообщение об ошибке:

      expected: 2
       got: 3

  (compared using eql?)
  (RSpec::Expectations::ExpectationNotMetError)
9 голосов
/ 10 марта 2015

Редактировать: Как указал @ThomasWalpole, использование all отключает ожидание / повторную попытку Капибары, поэтому ответ @pandaPower выше намного лучше.

Как насчет этого?

  within('ol') do
    expect( all('.opportunity_title_wrap').count ).to eq(2)
  end
3 голосов
/ 02 сентября 2013

Текущая рекомендация (9/2/2013), рекомендованная Capybara, следующая ( источник ):

page.assert_selector('p#foo', :count => 4)

0 голосов
/ 04 сентября 2014

Ответ @pandaPower очень хороший, но синтаксис для меня немного изменился:

expect(page).to have_selector('.views-row', :count => 30)
...