Ruby-on-rails 带有子域的 Capybara - default_host

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/6536503/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-03 01:29:47  来源:igfitidea点击:

Capybara with subdomains - default_host

ruby-on-railsintegration-testingcapybara

提问by brad

I have an app that uses subdomains to switch databases (multi-tenancy). I'm trying to use Capybara for integration testing, and it really relies a lot on subdomains.

我有一个应用程序,它使用子域来切换数据库(多租户)。我正在尝试使用 Capybara 进行集成测试,它确实非常依赖于子域。

My understanding was that setting Capybara.default_host=to something would make all my requests come from this host. This doesn't seem to be the case. In this post, the author recommends just visiting the explicit url with a host, but this becomes a bit annoying if I'm navigating all over the place. I'd like to just set the host, then be able to use my rails paths as expected. Not sure what I'm doing wrong, but here's what I've tried:

我的理解是,设置Capybara.default_host=某些内容会使我的所有请求都来自该主机。情况似乎并非如此。在这篇文章中,作者建议只使用主机访问显式 url,但是如果我在所有地方导航,这会变得有点烦人。我只想设置主机,然后就可以按预期使用我的导轨路径。不知道我做错了什么,但这是我尝试过的:

# spec_helper.rb
RSpec.configure do |config|
  config.before(:each, :type => :request) do
    Capybara.default_host = 'http://app.mydomain.com'
  end
end

# in some_integration_spec.rb
before do
  puts "Capybara.default_host: #{Capybara.default_host}"
  puts "some_app_url: #{some_app_url}"
end

This yields the output:

这产生了输出:

Capybara.default_host: http://app.mydomain.com
some_app_url: http://www.example.com/some_path

What am I doing wrong? default_hostappears to do nothing. As I say, I don't want to have to say visit(Capybara.default_host + some_app_path)as that's a bit annoying each time. Why else does this default_host option exist?

我究竟做错了什么? default_host似乎什么都不做。正如我所说,我不想说visit(Capybara.default_host + some_app_path),因为每次都有些烦人。为什么还有这个 default_host 选项存在?

回答by Lachlan Cotter

I'm not sure of the intended use of default_host, but app_hostdoes what you need. I've found I first need to call the rails session method host!in order to set the host string that will be passed to controllers in the request object.

我不确定 的预期用途default_host,但app_host可以满足您的需求。我发现我首先需要调用 rails session 方法host!来设置将传递给请求对象中的控制器的主机字符串。

Then you need to set Capybara.app_hostto tell Capybara to call your app via the web server instead of just making the calls in process. If you don't do that then Capybara wigs out when it encounters redirects and drops the host information in the second request.

然后你需要设置Capybara.app_host告诉 Capybara 通过网络服务器调用你的应用程序,而不是仅仅在进程中进行调用。如果您不这样做,则 Capybara 在遇到重定向时会退出,并在第二个请求中丢弃主机信息。

I'm not sure why this doesn't take care of the Rails requestend of things automatically, but I've found that unless I set the host in both places explicitly, then I get inconsistent results.

我不确定为什么这不会request自动处理Rails端的事情,但我发现除非我在两个地方都明确设置主机,否则我会得到不一致的结果。

def set_host (host)
  host! host
  Capybara.app_host = "http://" + host
end

before(:each) do
  set_host "lvh.me:3000"
end

Then you can just use relative paths to access pages.

然后您可以使用相对路径来访问页面。

Update:

更新:

Capybara 2.xand rspec-rails 2.12.0introduced "Feature" specs for running Capybara acceptance tests. The new FeatureExampleGroupmodule in rspec-railsis different from RequestExampleGroupand no longer has access to the rack-test host!method. Now you want to use default_url_optionsinstead:

Capybara 2.xrspec-rails 2.12.0引入了用于运行Capybara验收测试的“功能”规范。新FeatureExampleGroup模块 in与机架测试方法rspec-rails不同,RequestExampleGroup并且不再可以访问该host!方法。现在你想default_url_options改用:

def set_host (host)
  # host! host
  default_url_options[:host] = host
  Capybara.app_host = "http://" + host
end

回答by Andrew

When you need to change the URL to include the subdomain, you can specify the app_hostin your step definitions. Use a domain like lvh.mesince it points to 127.0.0.1:

当您需要更改 URL 以包含子域时,您可以app_host在步骤定义中指定。使用像这样的域,lvh.me因为它指向127.0.0.1

Capybara.app_host = "http://#{subdomain}.lvh.me"

Capybara assumes that when you're specifying an app_hostthat you're testing a remote server running on port 80, but in our case, we're testing a local app which is running on a random port specified by Capybara. To fix this, in your env.rbfile, add this line:

Capybara 假设当您指定 一个 时app_host,您正在测试在端口 80 上运行的远程服务器,但在我们的示例中,我们正在测试在 Capybara 指定的随机端口上运行的本地应用程序。要解决此问题,请在您的env.rb文件中添加以下行:

Capybara.always_include_port = true

Now when you visit a page of your app...

现在,当您访问应用程序页面时...

visit '/page'

...the url will specify the subdomain as well as the port that the app is running on.

...该 url 将指定子域以及应用程序运行的端口。

FYI: This worked for me using Capybara 2.0.2.

仅供参考:这对我使用 Capybara 2.0.2 有用。

回答by Jacob

This guy has the right answer here:

这个人在这里有正确的答案:

http://zurb.com/forrst/posts/Testing_Subdomains_in_Capybara-g4M

http://zurb.com/forrst/posts/Testing_Subdomains_in_Capybara-g4M

You want to do

你想做

Capybara.current_session.driver.reset!
Capybara.default_host = 'http://app.mydomain.com'

回答by James Tan

as of:

作为:

  • capybara (2.4.1)
  • capybara-webkit (1.3.0)

    Capybara.server_host = "example.com"
    Capybara.server_port = 3050
    Capybara.run_server = true
    Capybara.javascript_driver = :webkit #requires capybara-webkit
    
  • 水豚 (2.4.1)
  • 水豚-webkit (1.3.0)

    Capybara.server_host = "example.com"
    Capybara.server_port = 3050
    Capybara.run_server = true
    Capybara.javascript_driver = :webkit #requires capybara-webkit
    

回答by Rimian

This is not exactly the same situation as you but this might help some people:

这与您的情况不完全相同,但这可能对某些人有所帮助:

For my current project, I'm using powwith many subdomains. The test suite also has to run on a different port.

对于我当前的项目,我将pow与许多子域一起使用。测试套件还必须在不同的端口上运行。

The solution depends on which version of capybara you're running.

解决方案取决于您运行的是哪个版本的水豚。

For the current latest release I put this in custom_env.rb:

对于当前的最新版本,我将其放在 custom_env.rb 中:

Capybara.server_host = 'myapp.dev'
Capybara.server_port = 9887
Capybara.run_server = true

# I don't remember what this was for. Another team member wrote this part...
module ActionDispatch
  module Integration #:nodoc:
    class Session
      def host
        [Capybara.server_host, Capybara.server_port].join(':')
      end
    end
  end
end

With capybara 1.1.2, I had had to make the above change but server_hostbecomes app_hostAND modify lib/capybara/server.rb in the gem like this:

使用 capybara 1.1.2,我不得不进行上述更改,但server_host变成app_host并修改了 gem 中的 lib/capybara/server.rb,如下所示:

def url(path)
  ..
  if path =~ /^http/
    path
  else
    # Was this (Capybara.app_host || "http://#{host}:#{port}") + path.to_s
    (Capybara.app_host || "http://#{host}") + ":#{port}" + path.to_s
  end
end