-
-
Save antonfefilov/e2d4725de127916ed6689503ca5bd16c to your computer and use it in GitHub Desktop.
Saving and restoring Capybara sessions
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
module CapybaraSessionFactory | |
class SessionAlreadyDefined < StandardError; end | |
class SessionNotDefined < StandardError; end | |
# Parse a capybara session mode, which has the form | |
# "[driver]:[session_name]:[application_id]" | |
# | |
class CapybaraModeParser | |
attr_reader :driver, :session_name, :application_id | |
def initialize(mode) | |
@mode = mode | |
parse | |
end | |
private | |
def parse | |
@driver, @session_name, @application_id = @mode.split(':') | |
end | |
end | |
class Session | |
include Capybara::DSL | |
def initialize(name, setup_proc) | |
@name, @setup_proc = name, setup_proc | |
@is_setup = false | |
end | |
def setup? | |
@is_setup | |
end | |
def run_setup | |
return if setup? | |
instance_eval(&@setup_proc) | |
@is_setup = true | |
end | |
def capybara_session_name | |
"capybara_session_factory_#{@name}" | |
end | |
end | |
class << self | |
# Defines a new session and its setup code. | |
# | |
def define_session(name, &setup_proc) | |
raise SessionAlreadyDefined if sessions.key?(name) | |
sessions[name] = Session.new(name, setup_proc) | |
end | |
# Loads a session by name. | |
# The setup code is only run on the first load. | |
# | |
def load_session(name) | |
raise SessionNotDefined unless sessions.key?(name) | |
session = sessions[name] | |
Capybara.using_session(name) do | |
session.run_setup unless session.setup? | |
yield | |
end | |
end | |
private | |
def sessions | |
@sessions ||= {} | |
end | |
# Returns true if the capybara mode string corresponds to a | |
# CapybaraSessionFactory session. | |
# | |
def managed_session_mode?(mode) | |
parser = CapybaraModeParser.new(mode) | |
sessions.key?(parser.session_name) | |
end | |
end | |
end | |
class << Capybara | |
# Force capybara not to reset sessions that are managed by CapybaraSessionFactory. | |
# This let's sessions persist between tests. | |
# | |
# TODO: Capybara doesn't allow management of its "session_pool", so we need to monkey-path. | |
# Capybara should be updated with a session manager strategy so this is not required. | |
# | |
def reset_sessions! | |
session_pool.each do |mode, session| | |
session.reset! unless CapybaraSessionFactory.managed_session_mode?(mode) | |
end | |
end | |
alias_method :reset!, :reset_sessions! | |
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# spec/features/dashboard_spec.rb | |
require 'spec_helper' | |
describe 'the dashboard' do | |
it 'has a welcome message' do | |
CapybaraSessionFactory.load_session('signed in') do | |
click_link 'Dashboard' | |
expect(page).to have_content 'Welcome to your dashboard' | |
end | |
end | |
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# spec/sessions/signed_in.rb | |
CapybaraSessionFactory.define_session 'signed in' do | |
visit '/signup' | |
fill_in 'First name', with: 'Bob' | |
fill_in 'Email', with: '[email protected]' | |
fill_in 'Password', with: 'password' | |
click_button 'Sign Up' | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment