Sé que en Capybara, puedes hacer algo como esto:
page.should have_css("ol li", :count => 2)
Sin embargo, asumiendo que la página tiene, por ejemplo, un solo elemento coincidente, el error no es muy descriptivo:
1) initial page load shows greetings
Failure/Error: page.should have_css("ol li", :count => 2)
expected css "ol li" to return something
En lugar de este mensaje de error bastante oscuro, ¿hay alguna manera de escribir la aserción de tal manera que la salida de error sea algo como 'Al coincidir con' ol li ', esperado: 2, encontrado: 1'. Obviamente, yo mismo podría hacer una lógica personalizada para tal comportamiento; me pregunto si hay alguna manera de hacer esto "fuera de la caja".
Por lo que vale, estoy usando el controlador Selenium y RSpec.
page.should have_css("ol li", :count => 2)
ya no se hubiera implementado.Respuestas:
Me gusta mucho más esto.
expect(page).to have_selector('input', count: 12)
https://github.com/jnicklas/capybara/blob/415e2db70d3b19b46a4d3d0fe62f50400f9d2b61/spec/rspec/matchers_spec.rb
fuente
have_css
:expect(page).to have_css('input', count: 12)
Bueno, como parece que no hay soporte fuera de la caja, escribí este comparador personalizado:
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
Ahora puedes hacer cosas como:
describe "initial page load", :type => :request do it "has 12 inputs" do visit "/" page.should match_exactly(12, "input") end end
y obtener resultados como:
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
Por ahora funciona, buscaré hacer esta parte de Capybara.
fuente
Creo que lo siguiente es más simple, ofrece un resultado bastante claro y elimina la necesidad de un comparador personalizado.
page.all("ol li").count.should eql(2)
Esto luego se imprime en caso de error:
expected: 2 got: 3 (compared using eql?) (RSpec::Expectations::ExpectationNotMetError)
fuente
Editar: como lo señaló @ThomasWalpole, el uso
all
deshabilita la espera / reintento de Capybara, por lo que la respuesta anterior de @pandaPower es mucho mejor.¿Qué tal esto?
within('ol') do expect( all('.opportunity_title_wrap').count ).to eq(2) end
fuente
within
, está llamando.count
a los resultadosall
que deshabilita la espera / reintento. Al llamarcount
a los resultados deall
(para los cuales una "matriz" vacía es un retorno válido), convierte a un número entero y lo compara. Si esa comparación falla, la expectativa falla. Si, en cambio, pasa la opción de conteo a uno de los comparadores de Capybara, carpincho esperará / volverá a intentar encontrar el selector especificado hasta que coincida la opción de conteo (o Capybara.default_max_wait_time expire).La mejor práctica actual (2/9/2013) recomendada por Capybara es la siguiente ( fuente ):
page.assert_selector('p#foo', :count => 4)
fuente
La respuesta de @pandaPower es muy buena, pero la sintaxis fue ligeramente diferente para mí:
expect(page).to have_selector('.views-row', :count => 30)
fuente