web-dev-qa-db-fra.com

Capybara matcher pour la présence de bouton ou de lien

Les utilisateurs de la page Web ne font pas la distinction entre "bouton" et "lien stylé en bouton" . Existe-t-il un moyen de vérifier si un "bouton ou un lien" est présent sur la page?

Par exemple, Capybara a l'étape suivante:

page.should have_button('Click me')

qui ne trouve pas les liens dénommés comme des boutons.

28
mirelon

J'ai déjà trouvé une meilleure réponse:

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

Suivi de click_link_or_button défini ici: 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

Il appelle un sélecteur :link_or_button. Ce sélecteur est défini ici: 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

Il appelle cette méthode: 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

J'ai donc essayé de vérifier la présence du sélecteur et cela a fonctionné:

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

Utilisation de la syntaxe expect

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

Cela fonctionne sans qu'il soit nécessaire de définir un matcher personnalisé.

5
ardochhigh

Vous pouvez également utiliser un matcher personnalisé

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

Alors fais

expect(page).to have_link_or_button('Login')
1
idrinkpabst

Je pense que vous pouvez utiliser la méthode d'instance du bouton find:

(Capybara::Element) find_button(locator)

Utiliser id, nom, valeur.

Ou si vous voulez un lien

(Capybara::Element) find_link(locator)

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

0
simonmorley

J'ai eu un cas étrange où des tests de fumée ont défilé à travers différentes pages de connexion centrées sur le client qui présentaient de légères variations en ce qui concerne le bouton de soumission de connexion ... Piloté par une table d'utilisateurs, organisation, etc., concombre.

# 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
0
Jon Kern