capivara afirma os atributos de um elemento


87

Estou usando RSpec2 e Capybara para testes de aceitação.

Gostaria de afirmar que o link está desabilitado ou não na Capivara. Como posso fazer isso?

Respostas:


91

Como você está desativando o link? É uma classe que você está adicionando? Um atributo?

# Check for a link that has a "disabled" class:
page.should have_css("a.my_link.disabled")
page.should have_xpath("//a[@class='disabled']")

# Check for a link that has a "disabled" attribute:
page.should have_css("a.my_link[disabled]")
page.should have_xpath("//a[@class='disabled' and @disabled='disabled']")

# Check that the element is visible
find("a.my_link").should be_visible
find(:xpath, "//a[@class='disabled']").should be_visible

Os seletores xpath reais podem estar incorretos. Eu não uso o xpath com frequência!


Obrigado @idlefingers, quero afirmar usando o xpath também. Como posso fazer isso?
Kriysna,

Eu atualizei minha resposta. Se os seletores xpath estiverem errados, você terá que pesquisar no Google ou abrir uma nova pergunta.
idlefingers

Observe que isso não funcionará para o teste de visualização, pois capivara não foi feita para funcionar com visualizações. (Webrat é.)
Peter Ehrlich

144

Outra solução simples é acessar o atributo HTML que você está procurando com []:

find('#my_element')['class']
# => "highlighted clearfix some_other_css_class"

find('a#my_element')['href']
# => "http://example.com

# or in general, find any attribute, even if it does not exist
find('a#my_element')['no_such_attribute']
# => ""

Observe que Capybaratentará automaticamente aguardar a conclusão das solicitações assíncronas, mas pode não funcionar em alguns casos:

Esta é uma solução alternativa se você estiver tendo problemas com afirmações em elementos que são atualizados de forma assíncrona:


4
Solução útil de Vrey. Obrigado!
Alexander Kuznetsov

Eu tenho uma string com a localização do css, por exemplo. find('a#my_element[href]'), seria possível recuperar o valor deste atributo? Tentando expressões como, find('a#my_element[href]').valuemas não parece funcionar :(
mickael

@mickael Experimente find('a#my_element[href]').textou find('a#my_element[href]').native. Deixe-me saber se algum deles der os resultados esperados.
bowsersenior

1
Sei que esses comentários são muito antigos, mas usei-os desta forma: page.find ('# my_element') ['href = "<href_value>"'] e funcionou muito bem
Dono

Isso não vai esperar que a consulta se torne verdadeira se você quiser fazer uma afirmação sobre uma mudança assíncrona.
sj26

4

Foi um pouco confuso descobrir o xpath correto, aqui está o correto,
usando capivara 0.4.1.1

# <a href="https://stackoverflow.com/clowns?ordered_by=clumsyness" class="weep">View Clowns</a>  

page.should have_xpath("//a[@class='weep'][@href='/clowns?ordered_by=clumsyness']", :text => "View Clowns")

Se você só tem um link sem classe, use

page.should have_link('View Clowns', :href => '/clowns?ordered_by=clumsyness')

Infelizmente, algo assim não funcionará:

page.should have_link('This will not work!', :href => '/clowns?ordered_by=clumsyness', :class => "weep")

A opção de classe será ignorada.


4

Eu recomendo usar have_linke find_link(name)[:disabled]em duas afirmações separadas. Embora executar a segunda asserção sozinha seja mais simples, isso faz com que as mensagens de erro sobre links ausentes pareçam mais agradáveis, tornando os resultados do teste mais fáceis de ler.

expect(page).to have_link "Example"
expect(find_link("Example")[:disabled]).to be false

Observe que "Example"pode ser alterado para o nome ou id do link.


1
page.should have_link('It will work this way!', {:href => '/clowns?ordered_by=clumsyness', :class => "smile"})

have_link espera um hash de opções que estará vazio se você não fornecer nenhuma. Você pode especificar quaisquer atributos que o link deva ter - apenas certifique-se de passar todas as opções em UM hash.

Espero que isto ajude

PS: Para atributos como o método de dados, você deve passar o nome do atributo como uma string, já que o hífen quebra o símbolo.


6
Nunca funcionou e não funciona com Capivara. Não sei por que 9 pessoas votaram a favor.
Andrei Botalov,

Isso não funciona mais em Capivara 2. Pessoas que usam Capivara <2 podem usar o acima
Tian

@Tian não funcionou em Capivara <2. Eu sugiro que você vote negativamente esta resposta.
Andrei Botalov

class:não é válido
Amir Raminfar

1

Sempre que possível, você deve tentar usar os wrappers fornecidos pelo Capybara, que funcionarão de forma mais consistente entre os drivers.

Para o caso específico de disabled, um wrapper foi introduzido em 2.1: https://github.com/jnicklas/capybara/blob/fc56557a5463b9d944207f2efa401faa5b49d9ef/History.md#version-210

Se você usá-lo, obterá resultados sensíveis tanto no RackTest quanto no Poltergeist:

HTML:

<input type="text" id="disabled-false"            ></div>
<input type="text" id="disabled-true"     disabled></div>
<input type="text" id="disabled-js-true"          ></div>
<input type="text" id="disabled-js-false" disabled></div>
<script>
  document.getElementById('disabled-js-true').disabled = true
  document.getElementById('disabled-js-false').disabled = false
</script>

Testes:

!all(:field, 'disabled-false',    disabled: false).empty? or raise
 all(:field, 'disabled-false',    disabled: true ).empty? or raise
 all(:field, 'disabled-true',     disabled: false).empty? or raise
!all(:field, 'disabled-true',     disabled: true ).empty? or raise
 all(:field, 'disabled-js-true',  disabled: true ).empty? or raise
 all(:field, 'disabled-js-false', disabled: false).empty? or raise

Capybara.current_driver = :poltergeist
!all(:field, 'disabled-false',    disabled: false).empty? or raise
 all(:field, 'disabled-false',    disabled: true ).empty? or raise
 all(:field, 'disabled-true',     disabled: false).empty? or raise
!all(:field, 'disabled-true',     disabled: true ).empty? or raise
!all(:field, 'disabled-js-true',  disabled: true ).empty? or raise
!all(:field, 'disabled-js-false', disabled: false).empty? or raise

Observe como, ao usar isso em vez de seletores CSS, os testes de Javascript funcionarão sem nenhuma alteração se você começar a usar um driver compatível com Js.

Arquivo de teste executável aqui .


0

bowsersenior , obrigado por uma dica

Outra solução simples é acessar o atributo HTML que você está procurando com []

Aqui está um exemplo:

let(:action_items) { page.find('div.action_items') }

it "action items displayed as buttons" do
  action_items.all(:css, 'a').each do |ai|
    expect(ai[:class]).to match(/btn/)
  end
end

0

Usando a sintaxe de Rspec3, fiz desta forma:

expect(page).not_to have_selector(:link_or_button, 'Click here')

0

Simplesmente você pode usar o page.has_css?método

page.has_css?('.class_name') 

isso retornará truese o elemento existir.

Faça alguma ação com base na validação.

page.has_css?('.class_name') do
  #some code
end

0

De acordo com os documentos, você pode usar a sintaxe do acessador [atributo]:

find('#selector')['class'] => "form-control text optional disabled"

Para deficientes físicos, você também pode fazer o seguinte:

expect(find('#selector').disabled?).to be(true)
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.