水豚未通过 ID 找到注销 link

Capybara not finding signout link by id

对于我目前正在开发的 rails 应用程序,我最近稍微更改了设计,以便注销 link 不再具有锚文本 "Sign out" 而是来自推特 bootstrap。 link 的 html 现在看起来像这样:

<a class="btn btn-primary btn-sm" data-method="delete" href="/users/sign_out" rel="nofollow">
  <span class="glyphicon glyphicon-log-out"></span>
</a>

同时我的水豚测试是这样的:

context "when not logged in" do

  it 'cannot create wikis' do
    @free_user = create(:user)
    login_as(@free_user, :scope => :user)

    click_link "Sign out"

    visit root_path
    expect(page).to_not have_link('Create wiki')
  end
end

现在文本 "Sign out" 已不复存在,我需要一种新方法来识别 link。查看水豚(或 this handy cheatsheet)的文档,看起来我可以提供 link 的文本或其 ID。所以我试着给它一个 id:

<a class="btn btn-primary btn-sm" data-method="delete" href="/users/sign_out" id="signout" rel="nofollow">
  <span class="glyphicon glyphicon-log-out"></span>
</a>

所以现在它的 ID 为 "signout" 但是当我对测试进行此更改时,它仍然不会通过。

  1) Standard (free) User when not logged in cannot create wikis
     Failure/Error: click_link "signout"
     Capybara::ElementNotFound:
       Unable to find link "signout"
     # ./spec/features/standard_user_role_spec.rb:107:in `block (3 levels) in <top (required)>'

我尝试通过如上所述创建和登录用户并添加检查页面上的 html 是否包含 Hello 来确保我在测试中仍然是登录用户,因为它说 "Hello" 和用户登录时的用户名:

expect(page).to have_content('Hello')

这给了我另一个我不明白的错误:

  1) Standard (free) User when not logged in cannot create wikis
     Failure/Error: expect(page).to have_content('Hello')
     Capybara::ElementNotFound:
       Unable to find xpath "/html"
     # ./spec/features/standard_user_role_spec.rb:107:in `block (3 levels) in <top (required)>'

那么这里可能发生了什么?

完整规格可用 here

您可以重新添加文本,但除了屏幕阅读器之外,其他人都无法看到它:

<a class="btn btn-primary btn-sm" data-method="delete" href="/users/sign_out" id="signout" rel="nofollow">
  <span class="sr-only">Sign out</span>
  <span class="glyphicon glyphicon-log-out"></span>
</a>

这也稍微提高了可访问性。

context "when not logged in" do

  it 'cannot create wikis' do
    @free_user = create(:user)
    login_as(@free_user, :scope => :user)

    visit root_path
    click_link "Sign out", visible: false 

    expect(page).to_not have_link('Create wiki')
  end
end

请注意,我们明确告诉 Capybara 使用 visible 选项查找隐藏文本。

对于使用 JS 的应用程序,这意味着正在使用例如 json 格式发送请求,并通过单击 link 开始触发。 (假设 HTML 标记相同)。以下调用很有用:

find('Sign Out', visible: false).trigger('click')

id(如果您要添加):

find(:css, "#sign-out", visible: false).trigger('click')