2012-12-13 11 views
26

Gli utenti nella pagina Web non fanno distinzione tra "pulsante" e "collegamento con stile come pulsante". C'è un modo per aggiungere controllare se un "pulsante o collegamento" è presente sulla pagina?Matcher Capybara per presenza di pulsante o collegamento

Per esempio Capybara ha passo:

page.should have_button('Click me') 

che non trova i collegamenti in stile come pulsanti.

+0

Stavo per farlo a causa dei collegamenti Javascript, ma poi ho deciso di non: in questo caso almeno, * è * possibile distinguere. Ad esempio, al centro clic si apre una nuova scheda e, al passaggio del mouse, la destinazione del collegamento viene visualizzata solo per il collegamento. La migliore pratica è: non usare i collegamenti in quel caso e non permetterli nei test. –

+1

C'è comunque un caso in cui ne vale la pena: la negazione. Altrimenti, se si cambiano i collegamenti in pulsanti, i test diventano automaticamente silenziosi. –

risposta

49

ho già scoperto risposta migliore:

page.should have_selector(:link_or_button, 'Click me') 

Seguito da click_link_or_button che è definito qui: https://github.com/jnicklas/capybara/blob/master/lib/capybara/node/actions.rb#L12

def click_link_or_button(locator) 
    find(:link_or_button, locator).click 
end 
alias_method :click_on, :click_link_or_button 

Si chiede un selettore :link_or_button . Questo selettore viene definito qui: https://github.com/jnicklas/capybara/blob/master/lib/capybara/selector.rb#L143

Capybara.add_selector(:link_or_button) do 
    label "link or button" 
    xpath { |locator| XPath::HTML.link_or_button(locator) } 
end 

Si chiama questo metodo: http://rdoc.info/github/jnicklas/xpath/XPath/HTML#link_or_button-instance_method

# File 'lib/xpath/html.rb', line 33 

def link_or_button(locator) 
    link(locator) + button(locator) 
end 

Così ho provato a verificare la presenza del selettore e ha funzionato:

page.should have_selector(:link_or_button, 'Click me') 
0

Penso che si possa utilizzare il ritrovamento metodo di istanza del pulsante:

(Capybara::Element) find_button(locator) 

Utilizzando id, nome, valore.

O se si desidera un collegamento

(Capybara::Element) find_link(locator) 

Da: http://rubydoc.info/github/jnicklas/capybara/master/Capybara/Node/Finders#find_button-instance_method

+0

Io volevo piuttosto trovarlo con una chiamata invece di 2 – mirelon

+0

Sembra che tu abbia un modo più carino :) – simonmorley

1

Personalmente mi sento di dare il vostro pulsante o collegare un id e potete trovare che l'uso di

page.should have_css('#foo')

In questo modo puoi fare riferimento al link o al pulsante senza preoccuparti della sua implementazione.

ho sempre trovato questo utile: https://gist.github.com/428105

1

Puoi utilizzare anche un matcher personalizzato

RSpec::Matchers::define :have_link_or_button do |text| 
    match do |page| 
    Capybara.string(page.body).has_selector?(:link_or_button, text: text) 
    end 
end 

Poi fate

expect(page).to have_link_or_button('Login') 
0

ho avuto un caso strano in cui alcuni test di fumo hanno marciato attraverso le varie pagine di login customer-centric che hanno avuto lievi variazioni sul fare il login pulsante di invio ... Guidato da una tabella di cetriolo di utente, org , eccetera.

# A bit of a hack, org_name is normally a subdomain, but sometimes it is the complete domain 
def login(user, org_name) 
    # Use the below to automatically hit each user's org's server 
    if org_name.include? '.com' 
    Capybara.app_host = "http://#{org_name}" 
    else 
    Capybara.app_host = "http://#{org_name}.mydomain.com" 
    end 

    visit '/' 
    fill_in 'username', :with => user 
    fill_in 'userpwd', :with => '***' 
    begin 
    page.find(:link_or_button, 'submit') 
    click_on 'submit' 
    rescue Capybara::ElementNotFound 
    page.find(:link_or_button, 'Log In') 
    click_on 'Log In' 
    rescue Capybara::ElementNotFound 
     pending "Need to determine how to invoke the Login button for #{org_name} near Line ##{__LINE__} of #{__method__} in #{__FILE__} " 
    end 

    # ----------------------- 
    # Work-around for modal popup saying SSL is mismatched if you are using actual production URLs 
    # The rescue is for cases that do not exhibit the modal pop-up 
    page.driver.browser.switch_to.alert.accept rescue Selenium::WebDriver::Error::NoAlertPresentError 

    # Ensure that login was successful 
    page.should_not have_content 'Login failed' 
end 
1

Utilizzando la aspettarsi sintassi

expect(page).to have_selector(:link_or_button, 'Click me') 

Questo funziona senza la necessità di definire un matcher personalizzato.

+0

^Questo. La dovrebbe /: la sintassi dovrebbe essere deprecata –

Problemi correlati