Rails, Capybara и субдомены: как посетить определенный субдомен

Рельсы 3, Огурцы 0.9.4, Капибара 0.4.0

Я хочу проверить свои функции с помощью субдомена. Я нашел это решение:

Given /^I visit subdomain "(.+)"$/ do |sub|
  Capybara.default_host = "#{sub}.example.com" #for Rack::Test
  Capybara.app_host = "http://#{sub}.example.com:9887" if Capybara.current_driver == :culerity
end

Он работает, если я запускаю cucumber features/subdomain.feature, но он терпит неудачу, если я запустил cucumber features! Это невероятно, но это правда. Я зарегистрировал текущие URL-адреса и subdomain.example.com для cucumber features/subdomain.feature и www.example.com для cucumber features для одного сценария с

Scenario: subdomain scenario
  Given I visit subdomain "subdomain"

в обоих случаях!

Я не знаю причины...

Есть ли лучший способ тестирования субдоменов с capybara?

Ответ 1

Хорошо, вот что должно быть достаточно простым и легким для понимания взломом Capybara, которое дает желаемое поведение, а именно, чтобы иметь возможность создавать новый сеанс каждый раз, когда вы переключаете субдомены. Это полезно для сайтов, где пользователь регистрируется в одном домене (что приводит к созданию поддомена для его учетной записи), а затем в конечном итоге необходимо перейти к этому поддомену.

Прежде всего (и эта часть довольно распространена среди других решений там), дайте себе возможность изменить Capybara.default_host на этапе Cucumber. Я сделал это так:

Then /^I switch the subdomain to (\w+)$/ do |s|
  Capybara.default_host = "#{s}.smackaho.st"
end

Вставьте этот шаг в свою функцию Cucumber в том месте, где вы хотите использовать новый субдомен. Например:

When I open the email
Then I should see "http://acme.rightbonus.com/users/confirmation" in the email body

Given I switch the subdomain to acme
When I follow "Click here to finish setting up your account" in the email
Then I should be on the user confirmation page for acme

Теперь для волшебной обезьяны, которая делает эту работу. В принципе, вы хотите, чтобы Capybara была достаточно умна, чтобы определить, когда поддомен изменился, и reset его сеансовый объект RackTest.

# features/support/capybara.rb

class Capybara::Driver::RackTest
  # keep track of the default host you started with
  def initialize(app)
    raise ArgumentError,
      "rack-test requires a rack application, but none was given" unless app
    @app = app
    @default_host = Capybara.default_host
  end

  def process(method, path, attributes = {})
    reset_if_host_has_changed
    path = ["http://", @default_host, path].join
    return if path.gsub(/^#{request_path}/, '') =~ /^#/
    path = request_path + path if path =~ /^\?/
    send(method, to_binary(path), to_binary( attributes ), env)
    follow_redirects!
  end

  private

  def build_rack_mock_session # :nodoc:
    puts "building a new Rack::MockSession for " + Capybara.default_host
    Rack::MockSession.new(app, Capybara.default_host || "www.example.com")
  end

  def reset_if_host_has_changed
    if @default_host != Capybara.default_host
      reset! # clears the existing MockSession
      @default_host = Capybara.default_host
    end
  end
end

Этот патч работает с Capybara 0.4.1.1 и, вероятно, не будет работать с разными версиями, если не будет изменен. Удачи.

Ответ 2

Если ваши потребности не включают ничего общего с сеансами, и все, что вам нужно, посещает другой поддомен, я написал эту функцию:

def visit_with_subdomain(uri, options = {})
  domain = Capybara.default_host
  port = Capybara.server_port
  subdomain = options[:subdomain]
  visit "http://#{subdomain}.#{domain}:#{port}#{uri}"
end

Вы можете называть это следующим образом:

visit_with_subdomain some_path, subdomain: some_subdomain

Ответ 3

Если бы одна и та же проблема была бит, и мой тест должен был иногда переключать или перенаправлять назад и вперед между субдоменами.

задан этот шаг:

When /^(?:|I )go to "(.+)"$/ do |url|
  visit url
end

When I go to "http://mysubdomain.example.org" работает в тесте, но если вы перенаправлены приложением или следуете ссылке на какой-либо другой путь, хост возвращается к default_host.

В hassox существует вилка протестирования, которая гарантирует, что проверка стойки отслеживает хост, используемый в предыдущем запросе.

Итак, в моем Gemfile, прежде чем требовать capybara:

  gem 'rack-test', :git => "https://github.com/hassox/rack-test.git"

Теперь, если мне нужно нажать конкретный субдомен (или приложение перенаправляет меня на один, например secure.myapp.com/sign_in), я уверен, что эта функция может больше походить на браузер будет вести себя: это позволит мне оставаться в текущем субдомене до тех пор, пока я не перейду к использованию capybara visit("somesubdomain.example.org") или не перенаправляется приложением на другой хост.