Capybara::ElementNotFound: 找不到 xpath "//a[@href']"
Capybara::ElementNotFound: Unable to find xpath "//a[@href']"
我正在接受这个测试
feature 'Edit post' do
let(:post) { build(:post) }
scenario 'can edit post' do
visit root_path
find(:xpath, "//a[@href='/posts/1']").click
click_link 'Edit'
fill_in 'Title', with: 'This is an updated post'
click_button 'Save'
expect(page).to have_content('Post was successfully updated')
expect(page).to have_content('This is an updated post')
end
end
当我 运行 测试时,我得到以下错误,据我所知,它说 Capybara 找不到 link
Failure/Error: find(:xpath, "//a[@href='/posts/1']").click
Capybara::ElementNotFound:
Unable to find xpath "//a[@href='/posts/1']"
但是,如果我在浏览器上打开应用程序,我可以单击 root_path
(索引)中的 show
link 并访问显示操作,这让我觉得有一个我的测试脚本出错。我该如何解决这个问题?
更新
我确实放了page.html,这就是我得到的
<tbody>
<tr>
<td>Nihil neque corrupti atque qui eum omnis sapiente harum.</td>
<td>["Alias quas culpa expedita voluptatem vel. Eos aut autem tempora saepe odit iste. Iste ducimus dolorem a corrupti esse enim sint. Fugiat eum doloremque soluta ut voluptate sit. Nostrum unde in nobis quam ut adipisci quos cupiditate.", "Fugiat voluptatem qui totam fugit culpa et. Id omnis repellendus labore mollitia earum dignissimos ipsum. Eum rem qui excepturi culpa aut. Cum adipisci aspernatur nulla qui odio. Sequi minima doloremque iure ea possimus maiores alias."]</td>
<td><a href="/articles/1">Show</a></td>
<td><a href="/articles/1/edit">Edit</a></td>
<td><a data-confirm="Are you sure?" rel="nofollow" data-method="delete" href="/articles/1">Destroy</a></td>
</tr>
</tbody>
</table>
<br>
<a href="/articles/new">New Article</a>
</body>
当使用 let
时,对象是延迟构建的。这意味着它不存在,直到您在测试中实际引用它一次。由于您从不引用它,因此它从未构建,因此不存在。如果在这种情况下切换到 let!
,它将强制构建
let!(:post) { create(:post) }
您遇到的另一个问题是您不能假定它将使用 1 的 ID 构建,因此您可能希望在 url[=17= 中使用 post ID ]
find(:xpath, ".//a[@href='/posts/#{post.id}']").click
(注意前导 . 没有它就没有作用域,在使用 xpath 表达式时习惯把它放在那里 - https://github.com/teamcapybara/capybara#beware-the-xpath--trap)这实际上会更好地阅读并且不会像
那样脆弱
click_link(href: post_path(post))
尽管在功能测试中验证 hrefs 不是最佳做法。您最好根据其中显示的文字点击 link
click_link(post.name) #whatever is actually shown on the page
我正在接受这个测试
feature 'Edit post' do
let(:post) { build(:post) }
scenario 'can edit post' do
visit root_path
find(:xpath, "//a[@href='/posts/1']").click
click_link 'Edit'
fill_in 'Title', with: 'This is an updated post'
click_button 'Save'
expect(page).to have_content('Post was successfully updated')
expect(page).to have_content('This is an updated post')
end
end
当我 运行 测试时,我得到以下错误,据我所知,它说 Capybara 找不到 link
Failure/Error: find(:xpath, "//a[@href='/posts/1']").click
Capybara::ElementNotFound:
Unable to find xpath "//a[@href='/posts/1']"
但是,如果我在浏览器上打开应用程序,我可以单击 root_path
(索引)中的 show
link 并访问显示操作,这让我觉得有一个我的测试脚本出错。我该如何解决这个问题?
更新 我确实放了page.html,这就是我得到的
<tbody>
<tr>
<td>Nihil neque corrupti atque qui eum omnis sapiente harum.</td>
<td>["Alias quas culpa expedita voluptatem vel. Eos aut autem tempora saepe odit iste. Iste ducimus dolorem a corrupti esse enim sint. Fugiat eum doloremque soluta ut voluptate sit. Nostrum unde in nobis quam ut adipisci quos cupiditate.", "Fugiat voluptatem qui totam fugit culpa et. Id omnis repellendus labore mollitia earum dignissimos ipsum. Eum rem qui excepturi culpa aut. Cum adipisci aspernatur nulla qui odio. Sequi minima doloremque iure ea possimus maiores alias."]</td>
<td><a href="/articles/1">Show</a></td>
<td><a href="/articles/1/edit">Edit</a></td>
<td><a data-confirm="Are you sure?" rel="nofollow" data-method="delete" href="/articles/1">Destroy</a></td>
</tr>
</tbody>
</table>
<br>
<a href="/articles/new">New Article</a>
</body>
当使用 let
时,对象是延迟构建的。这意味着它不存在,直到您在测试中实际引用它一次。由于您从不引用它,因此它从未构建,因此不存在。如果在这种情况下切换到 let!
,它将强制构建
let!(:post) { create(:post) }
您遇到的另一个问题是您不能假定它将使用 1 的 ID 构建,因此您可能希望在 url[=17= 中使用 post ID ]
find(:xpath, ".//a[@href='/posts/#{post.id}']").click
(注意前导 . 没有它就没有作用域,在使用 xpath 表达式时习惯把它放在那里 - https://github.com/teamcapybara/capybara#beware-the-xpath--trap)这实际上会更好地阅读并且不会像
那样脆弱click_link(href: post_path(post))
尽管在功能测试中验证 hrefs 不是最佳做法。您最好根据其中显示的文字点击 link
click_link(post.name) #whatever is actually shown on the page