33

网页上的用户不区分“按钮”和“链接样式为按钮”。有没有办法添加检查页面上是否存在“按钮或链接”?

例如水豚有步骤:

page.should have_button('Click me')

它找不到样式为按钮的链接。

4

7 回答 7

56

更新的答案(应该在 RSpec 3.0+ 中弃用匹配器):

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

前:

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

随后在click_link_or_button此处定义: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

它调用一个选择器:link_or_button。这个选择器在这里定义: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

它调用此方法: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

所以我试图检查选择器的存在并且它有效:

page.should have_selector(:link_or_button, 'Click me')
于 2013-01-17T10:57:25.343 回答
5

使用期望语法

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

这无需定义自定义匹配器即可工作。

于 2016-12-13T08:52:49.090 回答
2

您还可以使用自定义匹配器

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

然后做

expect(page).to have_link_or_button('Login')
于 2013-04-18T00:30:12.857 回答
1

就我个人而言,我会给你的按钮或链接一个 id 并使用

page.should have_css('#foo')

这样您就可以参考链接或按钮,而不必担心其实现。

我总是觉得这很有用:https ://gist.github.com/428105

于 2012-12-14T07:56:36.067 回答
0

我认为您可以使用查找按钮实例方法:

(Capybara::Element) find_button(locator)

使用 ID、名称、值。

或者如果你想要一个链接

(Capybara::Element) find_link(locator)

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

于 2012-12-13T19:30:09.033 回答
0

我有一个奇怪的案例,其中一些冒烟测试在各种以客户为中心的登录页面上进行,这些页面在执行登录提交按钮时略有不同......由用户、组织等的 Cucumber 表驱动。

# 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
于 2013-08-04T15:08:15.423 回答
0

如果是 html:

<a class="top-menu__item">text123
    <span class="label">
        <span class="label">86</span>
    </span>
</a>

不行:

  assert page.has_selector?(:link_or_button, text: 'text123')
  assert page.should have_selector(:link_or_button, text: 'text123')
于 2019-06-06T06:47:24.523 回答