Как повторно использовать сеансы Capybara между тестами?
Я хочу продолжать использовать один и тот же сеанс, и я имею в виду сеанс Rails между различными тегами интеграции Test::Unit
, которые используют Capybara. Объект Capybara::Session
одинаковый во всех тестах, поскольку он повторно используется, но когда я обращаюсь к другой странице в другом тесте, я немедленно выхожу из системы.
Копаем я обнаружил, что capybara_session.driver.browser.manage.all_cookies
очищается между одним тестом и следующим.
Любые идеи как? или почему? или как его избежать?
Попытка обойти это, я сохранил файл cookie в переменной класса и повторно добавил позже:
capybara_session.driver.browser.manage.add_cookie(@@cookie)
и, похоже, работает, файл cookie есть, но когда есть запрос, cookie заменяется на другой, поэтому он не имеет никакого эффекта.
Есть ли другой способ достижения этого?
Ответы
Ответ 1
Добавьте следующее после кода capybara, который взаимодействует со страницей:
Capybara.current_session.instance_variable_set(:@touched, false)
or
page.instance_variable_set(:@touched, false)
Если это не сработает, это может помочь:
https://github.com/railsware/rack_session_access
http://collectiveidea.com/blog/archives/2012/01/05/capybara-cucumber-and-how-the-cookie-crumbles/
Ответ 2
Если вы пытаетесь объединить отдельные примеры в историю (стиль огурца, но без огурца), вы можете использовать драгоценный камень, называемый rspec-шагами, чтобы выполнить это. Например, обычно это не будет работать:
describe "logging in" do
it "when I visit the sign-in page" do
visit "/login"
end
it "and I fill in my registration info and click submit" do
fill_in :username, :with => 'Foo'
fill_in :password, :with => 'foobar'
click_on "Submit"
end
it "should show a successful login" do
page.should have_content("Successfully logged in")
end
end
Поскольку rspec откатывает все свои переменные экземпляра, сеансы, файлы cookie и т.д.
Если вы устанавливаете rspec-шаги (обратите внимание: в настоящее время несовместимо с rspec новее, чем 2.9), вы можете заменить "описать" на "шаги", а Rspec и capybara сохранит состояние между примерами, что позволит вам построить более длинную историю, например:
steps "logging in" do
it "when I visit the sign-in page" #... etc.
it "and I fill in" # ... etc.
it "should show a successful" # ... etc.
end
Ответ 3
Вы можете предотвратить вызов @browser.manage.delete_all_cookies
, который происходит между тестами путем обезглавливания метода Capybara::Selenium::Driver#reset!
. Это не чистый способ сделать это, но он должен работать...
Добавьте следующий код в свой проект, чтобы он выполнялся после require 'capybara'
:
class Capybara::Selenium::Driver < Capybara::Driver::Base
def reset!
# Use instance variable directly so we avoid starting the browser just to reset the session
if @browser
begin
#@browser.manage.delete_all_cookies <= cookie deletion is commented out!
rescue Selenium::WebDriver::Error::UnhandledError => e
# delete_all_cookies fails when we've previously gone
# to about:blank, so we rescue this error and do nothing
# instead.
end
@browser.navigate.to('about:blank')
end
end
end
Для интереса, оскорбительная строка видна в Capybara codebase здесь: https://github.com/jnicklas/capybara/blob/master/lib/capybara/selenium/driver.rb#L71
Ответ 4
Возможно, стоит опубликовать причину, по которой вам нужно такое поведение. Обычно, имея необходимость в обезьянном патче Capybara, является признаком того, что вы пытаетесь использовать его для чего-то, для чего он не предназначался. Часто можно реструктурировать тесты, так что вам не нужны файлы cookie, сохраненные в тестах интеграции.