Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Select an option

  • Save antonfefilov/e2d4725de127916ed6689503ca5bd16c to your computer and use it in GitHub Desktop.

Select an option

Save antonfefilov/e2d4725de127916ed6689503ca5bd16c to your computer and use it in GitHub Desktop.

Revisions

  1. @mcrowe mcrowe revised this gist Apr 19, 2014. 2 changed files with 4 additions and 0 deletions.
    2 changes: 2 additions & 0 deletions dashboard_spec.rb
    Original file line number Diff line number Diff line change
    @@ -1,3 +1,5 @@
    # spec/features/dashboard_spec.rb

    require 'spec_helper'

    describe 'the dashboard' do
    2 changes: 2 additions & 0 deletions signed_in.rb
    Original file line number Diff line number Diff line change
    @@ -1,3 +1,5 @@
    # spec/sessions/signed_in.rb

    CapybaraSessionFactory.define_session 'signed in' do
    visit '/signup'
    fill_in 'First name', with: 'Bob'
  2. @mcrowe mcrowe revised this gist Apr 19, 2014. 2 changed files with 20 additions and 0 deletions.
    13 changes: 13 additions & 0 deletions dashboard_spec.rb
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,13 @@
    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
    7 changes: 7 additions & 0 deletions signed_in.rb
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,7 @@
    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
  3. @mcrowe mcrowe created this gist Apr 19, 2014.
    107 changes: 107 additions & 0 deletions capybara_session_factory.rb
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,107 @@
    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