带有子域的水豚 - default_host

Posted

技术标签:

【中文标题】带有子域的水豚 - default_host【英文标题】:Capybara with subdomains - default_host 【发布时间】:2011-09-26 01:29:33 【问题描述】:

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

我的理解是,将Capybara.default_host= 设置为某个值会使我的所有请求都来自该主机。情况似乎并非如此。在this post 中,作者建议只使用主机访问显式 url,但如果我在各处导航,这会变得有点烦人。我只想设置主机,然后能够按预期使用我的 Rails 路径。不知道我做错了什么,但这是我尝试过的:

# 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

这会产生输出:

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

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

【问题讨论】:

也许对某人有帮助 my answer to this question 【参考方案1】:

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

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

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

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

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

那么你可以只使用相对路径来访问页面。

更新:

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

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

【讨论】:

有趣...有机会我会看看这个。谢谢! 看起来 app_host 是赢家,我希望文档能更清楚地说明区别,谢谢! 这非常有效。此外,如果您使用lvh.me 等公共域,您可以使用Capybara.server_port = 31234 自动设置端口,然后使用set_host "lvh.me:31234" 默认主机可用于类似after(:each) do Capybara.app_host = Capybara.default_host end 我可以工作,但是当我有:访问 new_sessions_path/url 我得到错误页面,该域是示例,它应该用于测试。 ://【参考方案2】:

这家伙在这里有正确的答案:

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

你想做的

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

【讨论】:

【参考方案3】:

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

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

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

对于当前的最新版本,我将其放在 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

使用 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

【讨论】:

【参考方案4】:

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

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

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

Capybara.always_include_port = true

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

visit '/page'

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

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

【讨论】:

这个方法也适用于我,其他方法都不起作用。我在 Capybara 2.4.3 上。对于我的应用程序,我还想知道 Capybara 从我的测试环境中选择的端口号。我正在使用 Poltergeist/PhantomJS,我可以从这个电话中获得该信息:Capybara.current_session.server.port【参考方案5】:

截至:

水豚 (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

【讨论】:

这似乎是一个错误,因为水豚的最新版本是 2.13.0。 @Sirasis 是的 2.13 会晚于 2.4

以上是关于带有子域的水豚 - default_host的主要内容,如果未能解决你的问题,请参考以下文章

为啥黄瓜和水豚叫那个?

带有 htaccess 的 CakePHP 子域

带有 CloudFlare 的子域

带有 Mandrill 子域的通用深度链接

带有 dnsmasq 的通配符子域

Next.js 带有子域的域路由