如何使用 Capybara 获取带有查询字符串的当前路径

Posted

技术标签:

【中文标题】如何使用 Capybara 获取带有查询字符串的当前路径【英文标题】:How to get current path with query string using Capybara 【发布时间】:2011-07-10 20:18:20 【问题描述】:

页面网址类似于/people?search=name 当我使用水豚的current_path 方法时,它只返回/people

current_path.should == people_path(:search => 'name')

但它失败了

expected: "/people?search=name"
got: "/people"

我们怎样才能让它通过?有没有办法做到这一点?

【问题讨论】:

"/people?search=name"is not a path。 "/people" 是路径 【参考方案1】:

我已更新此答案以反映水豚中的现代惯例。我认为这是理想的,因为这是公认的答案,并且在寻找解决方案时会提到很多人。话虽如此,检查当前路径的正确方法是使用 Capybara 提供的 has_current_path? 匹配器,如下所述:Click Here

示例用法:

expect(page).to have_current_path(people_path(search: 'name'))

正如您在文档中看到的,还有其他选项可用。如果当前页面是/people?search=name,但您只关心它在/people 页面上而不考虑参数,您可以发送only_path 选项:

expect(page).to have_current_path(people_path, only_path: true)

另外,如果你想比较整个 URL:

expect(page).to have_current_path(people_url, url: true)

感谢 Tom Walpole 指出了这种方法。

【讨论】:

我可能很快就会需要这种语法,我正在为遗留应用程序编写测试。使用current_path.should == 现在正在工作(尽管我需要添加一个尾部正斜杠作为字符串)。提前感谢您提供我可能需要的代码。 URI.parse(current_url).request_uri 更简洁。请参阅@Lasse Bunk 的答案。 从 Capybara 2.5 开始,这不再是最佳答案。请参阅下面的@tom-walpole 的回答。 由于提问者不太可能改变接受的答案,我已经更新了答案以反映现代。这对于寻找解决方案并看到第一个答案的新用户应该更有帮助。感谢@OddityOverseer 指出来 对于新的 Capybara 版本,使用 ignore_query: true 而不是 only_path: true【参考方案2】:

我将 _path 方法替换为 _url 以实现完整的 url 与参数的比较。

current_url.should == people_url(:search => 'name')

【讨论】:

host部分是怎么处理的? 您还可以在 Capybara 的较新版本中使用 current_path 并将其与 people_path(...) 匹配 当我没有命名路径...我只有 /users/register... 那我应该如何使用它呢? 如果它发生在渲染上,导致 URL 与 html 页面不同怎么办?【参考方案3】:

我知道已选择了一个答案,但我只是想提供一个替代解决方案。所以:

要获取路径和查询字符串,如 Rails 中的request.fullpath,您可以这样做:

URI.parse(current_url).request_uri.should == people_path(:search => 'name')

你也可以在你的测试类中做一个辅助方法(比如ActionDispatch::IntegrationTest),就像这样(我就是这么做的):

def current_fullpath
  URI.parse(current_url).request_uri
end

希望这会有所帮助。

【讨论】:

【参考方案4】:

编辑:正如 Tinynumberes 所提到的,对于带有端口号的 URL,这将失败。把它放在这里,以防其他人有同样的好主意。

current_url[current_host.size..-1]

golf 与 URI.parse(current_url).request_uri 一样好(35 个字符),但可能更快,因为不涉及显式 URI 解析。

我已提出拉取请求,将其添加到 Capybara:https://github.com/jnicklas/capybara/pull/1405

【讨论】:

如果current_url 可能包含端口号,这将不起作用。例如。给定current_urlhttp://foo.com:8888/some/pathcurrent_url[current_host.size..-1] 将等于:8888/some/path。此外,在幕后current_host 与@nzifnab 在接受的答案中推荐的URI.parse 逻辑相同。【参考方案5】:

只是为现代更新这个问题。当前使用 Capybara 2.5+ 时检查 current_paths 的最佳实践是使用 current_path 匹配器,它将使用 Capybara 等待行为来检查路径。如果要检查 request_uri(路径和查询字符串)

expect(page).to have_current_path(people_path(:search => 'name'))  

如果只想要路径部分(忽略查询字符串)

expect(page).to have_current_path(people_path, only_path: true) # Capybara < 2.16
expect(page).to have_current_path(people_path, ignore_query: true) # Capybara >= 2.16

如果想匹配完整的url

expect(page).to have_current_path(people_url, url: true) # Capybara < 2.16
expect(page).to have_current_path(people_url) # Capybara >= 2.16

匹配器将采用与 == 或正则表达式进行比较的字符串进行匹配

expect(page).to have_current_path(/search=name/)

【讨论】:

在现代这应该被标记为 the 答案。这将解决很多模糊的时间问题,谢谢! @Vanuan rspec 已弃用 should 语法。你应该努力在未来的规范中使用expect().to only_path: true 现在是ignore_query: true【参考方案6】:

请注意作者提到的in this comment。 current_url 的使用会导致测试不稳定。

【讨论】:

以上是关于如何使用 Capybara 获取带有查询字符串的当前路径的主要内容,如果未能解决你的问题,请参考以下文章

带有完整查询字符串的 Javascript document.referrer

使用 Capybara,如何切换到带有“_blank”目标的链接的新窗口?

如何在 Capybara 中获取父节点?

如何使用 capybara 使用验证码登录表单?

如何检查表单域是不是使用 capybara 正确预填?

Capybara:生成服务器时如何运行代码?