ChatGPT解决这个技术问题 Extra ChatGPT

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

页面 url 类似于 /people?search=name,而我使用 capybara 的 current_path 方法,它只返回 /people

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

但它没有说

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

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

"/people?search=name" is not a path"/people" 是路径

n
nzifnab

我已经更新了这个答案以反映水豚的现代惯例。我认为这是理想的,因为这是公认的答案,并且在寻找解决方案时会提到很多人。话虽如此,检查当前路径的正确方法是使用 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
R
Robert Starsi

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

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

你是如何处理主机部分的?
您还可以在较新版本的 Capybara 中使用 current_path 并将其与 people_path(...) 匹配
当我没有命名路径时...我只有 /users/register... 那么我应该如何使用它呢?
如果它发生在渲染上,所以 URL 与 html 页面不同怎么办?
T
Thomas Walpole

只是为现代更新这个问题。当前使用 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/)

在这些现代时代,这应该被标记为答案。这将避免很多模糊的时间问题,谢谢!
@Vanuan rspec 已弃用 should 语法。您应该努力在今后的规范中使用 expect().to
only_path: true 现在是 ignore_query: true
L
Lasse Bunk

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

要获取路径和查询字符串,例如 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

希望这可以帮助。


C
Ciro Santilli Путлер Капут 六四事

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

current_url[current_host.size..-1]

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 逻辑。
w
woto

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