2012-12-13 2 views
26

Benutzer auf der Web-Seite unterscheiden nicht zwischen "Button" und "Link styled als Schaltfläche". Gibt es eine Möglichkeit hinzuzufügen, überprüfen Sie, ob ein "Knopf oder Link" auf der Seite vorhanden ist?Capybara Matcher für die Anwesenheit von Button oder Link

Zum Beispiel Capybara hat Schritt:

page.should have_button('Click me') 

, die keine Links als Schaltflächen Stil findet.

+0

Ich wollte das wegen Javascript-Links machen, aber dann entschied ich mich nicht: in diesem Fall ist es * möglich * zu unterscheiden. Z. B. öffnet sich bei einem mittleren Klick ein neuer Tab, und beim Hover wird das Link-Ziel nur für den Link angezeigt. Die beste Vorgehensweise ist: Verwenden Sie in diesem Fall keine Links und lassen Sie sie nicht in Tests zu. –

+1

Es gibt jedoch einen Fall, in dem es sich lohnt: Negation. Andernfalls, wenn Sie Links in Schaltflächen ändern, werden die Tests stillschweigend immer ausgeführt. –

Antwort

49

ich bereits herausgefunden, bessere Antwort:

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

Gefolgt von click_link_or_button, die hier definiert: 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 

Es einen Selektor ruft :link_or_button . Dieser Selektor hier definiert ist: 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 

Es diese Methode aufruft: 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 

So habe ich versucht, die Anwesenheit der Wähler zu überprüfen, und es funktionierte:

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

Persönlich würde ich Ihren Knopf geben oder eine ID verknüpfen und für die aussehen

page.should have_css('#foo')

Auf diese Weise unter Verwendung von Sie können auf den Link oder die Schaltfläche verweisen, ohne sich über die Implementierung Gedanken machen zu müssen.

ich diese nützliche immer finden: https://gist.github.com/428105

1

Sie können Verwenden Sie auch einen benutzerdefinierten Matcher

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 

Dann tun

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

ich einen seltsamen Fall hatte, wo einige Rauchversuche über verschiedene kundenorientierte Login-Seiten marschierten die auf tun die Login leichten Variationen hatte Submit-Button ... durch eine Gurke Tabelle anzeigen Driven, org , etc.

# 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

die Verwendung erwarten Syntax

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

Dies funktioniert, ohne dass ein benutzerdefinierten Matcher zu definieren.

+0

^This. Die Syntax sollte sollte nicht mehr verwendet werden –