lopata 0.1.3 → 0.1.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
 - data/.yardopts +1 -0
 - data/README.md +6 -2
 - data/exe/lopata +1 -1
 - data/lib/lopata.rb +52 -2
 - data/lib/lopata/active_record.rb +105 -5
 - data/lib/lopata/condition.rb +2 -1
 - data/lib/lopata/configuration.rb +126 -0
 - data/lib/lopata/environment.rb +36 -0
 - data/lib/lopata/factory_bot.rb +52 -16
 - data/lib/lopata/generators/app.rb +2 -2
 - data/lib/lopata/generators/templates/Gemfile +0 -2
 - data/lib/lopata/generators/templates/config/environments/qa.yml +0 -1
 - data/lib/lopata/id.rb +1 -0
 - data/lib/lopata/loader.rb +2 -0
 - data/lib/lopata/observers.rb +1 -0
 - data/lib/lopata/observers/backtrace_formatter.rb +16 -2
 - data/lib/lopata/observers/base_observer.rb +17 -6
 - data/lib/lopata/observers/console_output_observer.rb +31 -8
 - data/lib/lopata/observers/web_logger.rb +30 -33
 - data/lib/lopata/role.rb +91 -0
 - data/lib/lopata/runner.rb +18 -21
 - data/lib/lopata/scenario.rb +57 -7
 - data/lib/lopata/scenario_builder.rb +250 -68
 - data/lib/lopata/shared_step.rb +2 -0
 - data/lib/lopata/step.rb +27 -23
 - data/lib/lopata/version.rb +2 -1
 - data/lib/lopata/world.rb +8 -12
 - metadata +7 -8
 - data/lib/lopata/config.rb +0 -97
 - data/lib/lopata/generators/templates/.rspec +0 -3
 - data/lib/lopata/generators/templates/spec/spec_helper.rb +0 -2
 - data/lib/lopata/rspec/dsl.rb +0 -39
 - data/lib/lopata/rspec/role.rb +0 -74
 
    
        checksums.yaml
    CHANGED
    
    | 
         @@ -1,7 +1,7 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            ---
         
     | 
| 
       2 
2 
     | 
    
         
             
            SHA256:
         
     | 
| 
       3 
     | 
    
         
            -
              metadata.gz:  
     | 
| 
       4 
     | 
    
         
            -
              data.tar.gz:  
     | 
| 
      
 3 
     | 
    
         
            +
              metadata.gz: a6234b218190d6aad3d2465c4ca3c5ab638701cf2afcc13db718546f87d0fa57
         
     | 
| 
      
 4 
     | 
    
         
            +
              data.tar.gz: 4d6312f8f421f834f2bc8412e30307ab29e3c377b256edbe891cc4efaf42315e
         
     | 
| 
       5 
5 
     | 
    
         
             
            SHA512:
         
     | 
| 
       6 
     | 
    
         
            -
              metadata.gz:  
     | 
| 
       7 
     | 
    
         
            -
              data.tar.gz:  
     | 
| 
      
 6 
     | 
    
         
            +
              metadata.gz: 1f1e130381f9551a7b8d2862788478384798d8fbf6ca91d388bb0a54e3c0cc52ccff95542fe6d33f94e4a99d7008c9b258e8f4f2ef8a32f8557b87b35f6e32fe
         
     | 
| 
      
 7 
     | 
    
         
            +
              data.tar.gz: ae371bc70669b963546f1676ec539ffa116a1458582c1547a973a75c66f8d477958494b78c422ababca9b7a0ce725d4dd6d77fd95f377a57d34c73d6ec935d83
         
     | 
    
        data/.yardopts
    ADDED
    
    | 
         @@ -0,0 +1 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            --no-private
         
     | 
    
        data/README.md
    CHANGED
    
    | 
         @@ -1,6 +1,6 @@ 
     | 
|
| 
       1 
     | 
    
         
            -
            # Lopata 
     | 
| 
      
 1 
     | 
    
         
            +
            # Lopata
         
     | 
| 
       2 
2 
     | 
    
         | 
| 
       3 
     | 
    
         
            -
             
     | 
| 
      
 3 
     | 
    
         
            +
            Functional acceptance testing using Ruby.
         
     | 
| 
       4 
4 
     | 
    
         | 
| 
       5 
5 
     | 
    
         
             
            ## Installation
         
     | 
| 
       6 
6 
     | 
    
         | 
| 
         @@ -20,3 +20,7 @@ Run tests: 
     | 
|
| 
       20 
20 
     | 
    
         | 
| 
       21 
21 
     | 
    
         
             
                cd <project-name>
         
     | 
| 
       22 
22 
     | 
    
         
             
                lopata
         
     | 
| 
      
 23 
     | 
    
         
            +
             
     | 
| 
      
 24 
     | 
    
         
            +
            ## Documentation
         
     | 
| 
      
 25 
     | 
    
         
            +
             
     | 
| 
      
 26 
     | 
    
         
            +
            See [features description](https://github.com/avolochnev/lopata/tree/master/features) for documentation.
         
     | 
    
        data/exe/lopata
    CHANGED
    
    
    
        data/lib/lopata.rb
    CHANGED
    
    | 
         @@ -1,11 +1,15 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            require 'lopata/id'
         
     | 
| 
       2 
     | 
    
         
            -
            require 'lopata/ 
     | 
| 
      
 2 
     | 
    
         
            +
            require 'lopata/configuration'
         
     | 
| 
      
 3 
     | 
    
         
            +
            require 'lopata/environment'
         
     | 
| 
       3 
4 
     | 
    
         
             
            require 'lopata/scenario_builder'
         
     | 
| 
       4 
5 
     | 
    
         
             
            require 'lopata/scenario'
         
     | 
| 
       5 
6 
     | 
    
         
             
            require 'lopata/step'
         
     | 
| 
       6 
7 
     | 
    
         
             
            require 'lopata/shared_step'
         
     | 
| 
       7 
8 
     | 
    
         | 
| 
      
 9 
     | 
    
         
            +
            # Namespace for all Lopata code.
         
     | 
| 
       8 
10 
     | 
    
         
             
            module Lopata
         
     | 
| 
      
 11 
     | 
    
         
            +
              # Define the scenario.
         
     | 
| 
      
 12 
     | 
    
         
            +
              # @see Lopata::ScenarioBuilder.define
         
     | 
| 
       9 
13 
     | 
    
         
             
              def self.define(*args, &block)
         
     | 
| 
       10 
14 
     | 
    
         
             
                Lopata::ScenarioBuilder.define(*args, &block)
         
     | 
| 
       11 
15 
     | 
    
         
             
              end
         
     | 
| 
         @@ -14,11 +18,57 @@ module Lopata 
     | 
|
| 
       14 
18 
     | 
    
         
             
              def self.xdefine(*args, &block)
         
     | 
| 
       15 
19 
     | 
    
         
             
              end
         
     | 
| 
       16 
20 
     | 
    
         | 
| 
      
 21 
     | 
    
         
            +
              # Register the shared step
         
     | 
| 
      
 22 
     | 
    
         
            +
              #
         
     | 
| 
      
 23 
     | 
    
         
            +
              # @example
         
     | 
| 
      
 24 
     | 
    
         
            +
              #     Lopata.shared_step 'test user' do
         
     | 
| 
      
 25 
     | 
    
         
            +
              #       setup { @user = create(:user) }
         
     | 
| 
      
 26 
     | 
    
         
            +
              #     end
         
     | 
| 
      
 27 
     | 
    
         
            +
              #
         
     | 
| 
      
 28 
     | 
    
         
            +
              # Shared step may be used in scenarios by name:
         
     | 
| 
      
 29 
     | 
    
         
            +
              # @example
         
     | 
| 
      
 30 
     | 
    
         
            +
              #     Lopata.define 'user' do
         
     | 
| 
      
 31 
     | 
    
         
            +
              #       setup 'test user'
         
     | 
| 
      
 32 
     | 
    
         
            +
              #
         
     | 
| 
      
 33 
     | 
    
         
            +
              #       it 'exists' do
         
     | 
| 
      
 34 
     | 
    
         
            +
              #         expect(@user).to_not be_nil
         
     | 
| 
      
 35 
     | 
    
         
            +
              #       end
         
     | 
| 
      
 36 
     | 
    
         
            +
              #     end
         
     | 
| 
      
 37 
     | 
    
         
            +
              # @param name [String] shared step unique name
         
     | 
| 
      
 38 
     | 
    
         
            +
              # @param block [Block] shared step action sequence definition
         
     | 
| 
       17 
39 
     | 
    
         
             
              def self.shared_step(name, &block)
         
     | 
| 
       18 
40 
     | 
    
         
             
                Lopata::SharedStep.register(name, &block)
         
     | 
| 
       19 
41 
     | 
    
         
             
              end
         
     | 
| 
       20 
42 
     | 
    
         | 
| 
      
 43 
     | 
    
         
            +
              # Yields the global configuration to a block.
         
     | 
| 
      
 44 
     | 
    
         
            +
              # @yield [Lopata::Configuration] global configuration
         
     | 
| 
      
 45 
     | 
    
         
            +
              #
         
     | 
| 
      
 46 
     | 
    
         
            +
              # @example
         
     | 
| 
      
 47 
     | 
    
         
            +
              #     Lopata.configure do |config|
         
     | 
| 
      
 48 
     | 
    
         
            +
              #       config.before_scenario 'setup test user'
         
     | 
| 
      
 49 
     | 
    
         
            +
              #     end
         
     | 
| 
      
 50 
     | 
    
         
            +
              # @see Lopata::Configuration
         
     | 
| 
       21 
51 
     | 
    
         
             
              def self.configure(&block)
         
     | 
| 
       22 
     | 
    
         
            -
                yield Lopata 
     | 
| 
      
 52 
     | 
    
         
            +
                yield Lopata.configuration
         
     | 
| 
      
 53 
     | 
    
         
            +
              end
         
     | 
| 
      
 54 
     | 
    
         
            +
             
     | 
| 
      
 55 
     | 
    
         
            +
              # Returns global configuration object.
         
     | 
| 
      
 56 
     | 
    
         
            +
              # @return [Lopata::Configuration]
         
     | 
| 
      
 57 
     | 
    
         
            +
              # @see Lopata.configure
         
     | 
| 
      
 58 
     | 
    
         
            +
              def self.configuration
         
     | 
| 
      
 59 
     | 
    
         
            +
                @configuration ||= Lopata::Configuration.new
         
     | 
| 
      
 60 
     | 
    
         
            +
              end
         
     | 
| 
      
 61 
     | 
    
         
            +
             
     | 
| 
      
 62 
     | 
    
         
            +
              # @private
         
     | 
| 
      
 63 
     | 
    
         
            +
              # Internal container for global non-configuration data.
         
     | 
| 
      
 64 
     | 
    
         
            +
              def self.world
         
     | 
| 
      
 65 
     | 
    
         
            +
                @world ||= Lopata::World.new
         
     | 
| 
      
 66 
     | 
    
         
            +
              end
         
     | 
| 
      
 67 
     | 
    
         
            +
             
     | 
| 
      
 68 
     | 
    
         
            +
              # Return global environment object
         
     | 
| 
      
 69 
     | 
    
         
            +
              # @return [Lopata::Environment]
         
     | 
| 
      
 70 
     | 
    
         
            +
              # @see Lopata::Environment
         
     | 
| 
      
 71 
     | 
    
         
            +
              def self.environment
         
     | 
| 
      
 72 
     | 
    
         
            +
                Lopata.configuration.environment
         
     | 
| 
       23 
73 
     | 
    
         
             
              end
         
     | 
| 
       24 
74 
     | 
    
         
             
            end
         
     | 
    
        data/lib/lopata/active_record.rb
    CHANGED
    
    | 
         @@ -1,25 +1,118 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            module Lopata
         
     | 
| 
      
 2 
     | 
    
         
            +
              # Helpers for ActiveRecord usage in tests.
         
     | 
| 
      
 3 
     | 
    
         
            +
              #
         
     | 
| 
      
 4 
     | 
    
         
            +
              # Make helpers available in scenarios by
         
     | 
| 
      
 5 
     | 
    
         
            +
              #
         
     | 
| 
      
 6 
     | 
    
         
            +
              #     require 'lopata/active_record'
         
     | 
| 
      
 7 
     | 
    
         
            +
              #
         
     | 
| 
      
 8 
     | 
    
         
            +
              # @example
         
     | 
| 
      
 9 
     | 
    
         
            +
              #
         
     | 
| 
      
 10 
     | 
    
         
            +
              #     # Configure db connection at config/environments/qa.yml like rails:
         
     | 
| 
      
 11 
     | 
    
         
            +
              #     # db:
         
     | 
| 
      
 12 
     | 
    
         
            +
              #     #   adapter: postgresql
         
     | 
| 
      
 13 
     | 
    
         
            +
              #     #   host: your.database.host
         
     | 
| 
      
 14 
     | 
    
         
            +
              #     #   username: username
         
     | 
| 
      
 15 
     | 
    
         
            +
              #     #   password: password
         
     | 
| 
      
 16 
     | 
    
         
            +
              #     #   database: database
         
     | 
| 
      
 17 
     | 
    
         
            +
              #     require 'active_record'
         
     | 
| 
      
 18 
     | 
    
         
            +
              #     require 'lopata/active_record'
         
     | 
| 
      
 19 
     | 
    
         
            +
              #
         
     | 
| 
      
 20 
     | 
    
         
            +
              #     class User < ActiveRecord::Base; end
         
     | 
| 
      
 21 
     | 
    
         
            +
              #
         
     | 
| 
      
 22 
     | 
    
         
            +
              #     Lopata.define 'User creation' do
         
     | 
| 
      
 23 
     | 
    
         
            +
              #       setup do
         
     | 
| 
      
 24 
     | 
    
         
            +
              #         @user = User.create!(username: 'testuser')
         
     | 
| 
      
 25 
     | 
    
         
            +
              #       end
         
     | 
| 
      
 26 
     | 
    
         
            +
              #       # Remove user from database after scenario
         
     | 
| 
      
 27 
     | 
    
         
            +
              #       cleanup :user
         
     | 
| 
      
 28 
     | 
    
         
            +
              #
         
     | 
| 
      
 29 
     | 
    
         
            +
              #       it 'works' do
         
     | 
| 
      
 30 
     | 
    
         
            +
              #         expect(@user).to_not be_nil
         
     | 
| 
      
 31 
     | 
    
         
            +
              #       end
         
     | 
| 
      
 32 
     | 
    
         
            +
              #     end
         
     | 
| 
      
 33 
     | 
    
         
            +
              #
         
     | 
| 
       2 
34 
     | 
    
         
             
              module ActiveRecord
         
     | 
| 
       3 
     | 
    
         
            -
                # To be included in Lopata::Scenario
         
     | 
| 
      
 35 
     | 
    
         
            +
                # To be included in Lopata::Scenario. The methods may be used in runtime.
         
     | 
| 
       4 
36 
     | 
    
         
             
                module Methods
         
     | 
| 
      
 37 
     | 
    
         
            +
                  # Destroy ActiveRecord objects.
         
     | 
| 
      
 38 
     | 
    
         
            +
                  #
         
     | 
| 
      
 39 
     | 
    
         
            +
                  # Does nothing if 'keep' mode is enabled:
         
     | 
| 
      
 40 
     | 
    
         
            +
                  #
         
     | 
| 
      
 41 
     | 
    
         
            +
                  #     Lopata.configure do |c|
         
     | 
| 
      
 42 
     | 
    
         
            +
                  #       c.keep = true
         
     | 
| 
      
 43 
     | 
    
         
            +
                  #     end
         
     | 
| 
      
 44 
     | 
    
         
            +
                  #
         
     | 
| 
      
 45 
     | 
    
         
            +
                  # @param objects [Array<ActiveRecord::Base, Array<ActiveRecord::Base>, nil>] to be destroyed
         
     | 
| 
      
 46 
     | 
    
         
            +
                  # @see Lopata::Configuration#keep
         
     | 
| 
       5 
47 
     | 
    
         
             
                  def cleanup(*objects)
         
     | 
| 
       6 
     | 
    
         
            -
                    return if Lopata 
     | 
| 
      
 48 
     | 
    
         
            +
                    return if Lopata.configuration.keep
         
     | 
| 
       7 
49 
     | 
    
         
             
                    objects.flatten.compact.each do |o|
         
     | 
| 
       8 
50 
     | 
    
         
             
                      begin
         
     | 
| 
       9 
51 
     | 
    
         
             
                        o.reload.destroy!
         
     | 
| 
       10 
52 
     | 
    
         
             
                      rescue ::ActiveRecord::RecordNotFound
         
     | 
| 
       11 
     | 
    
         
            -
                        # Already destroyed
         
     | 
| 
      
 53 
     | 
    
         
            +
                        # Already destroyed - skip
         
     | 
| 
      
 54 
     | 
    
         
            +
                      rescue ::ActiveRecord::InvalidForeignKey
         
     | 
| 
      
 55 
     | 
    
         
            +
                        # Possible async job created new relationships (e.g. history records). Try again once.
         
     | 
| 
      
 56 
     | 
    
         
            +
                        o.reload.destroy!
         
     | 
| 
       12 
57 
     | 
    
         
             
                      end
         
     | 
| 
       13 
58 
     | 
    
         
             
                    end
         
     | 
| 
       14 
59 
     | 
    
         
             
                  end
         
     | 
| 
       15 
60 
     | 
    
         | 
| 
      
 61 
     | 
    
         
            +
                  # Reload ActiveRecord objects
         
     | 
| 
      
 62 
     | 
    
         
            +
                  #
         
     | 
| 
      
 63 
     | 
    
         
            +
                  # @example
         
     | 
| 
      
 64 
     | 
    
         
            +
                  #
         
     | 
| 
      
 65 
     | 
    
         
            +
                  #     # use in steps
         
     | 
| 
      
 66 
     | 
    
         
            +
                  #     reload @a, @b
         
     | 
| 
      
 67 
     | 
    
         
            +
                  #     # instead of
         
     | 
| 
      
 68 
     | 
    
         
            +
                  #     @a.reload; @b.reload
         
     | 
| 
      
 69 
     | 
    
         
            +
                  #
         
     | 
| 
      
 70 
     | 
    
         
            +
                  # @param objects [Array<ActiveRecord::Base, Array<ActiveRecord::Base>, nil>] to be reloaded
         
     | 
| 
       16 
71 
     | 
    
         
             
                  def reload(*objects)
         
     | 
| 
       17 
     | 
    
         
            -
                    objects.flatten.each(&:reload)
         
     | 
| 
      
 72 
     | 
    
         
            +
                    objects.flatten.compact.each(&:reload)
         
     | 
| 
      
 73 
     | 
    
         
            +
                  end
         
     | 
| 
      
 74 
     | 
    
         
            +
             
     | 
| 
      
 75 
     | 
    
         
            +
                  # Marks object to be destroyed at the end of scenario
         
     | 
| 
      
 76 
     | 
    
         
            +
                  #
         
     | 
| 
      
 77 
     | 
    
         
            +
                  # @param object [ActiveRecord::Base] the object to be destoryed at the end of scenario
         
     | 
| 
      
 78 
     | 
    
         
            +
                  # @return the given object, so chains can be build
         
     | 
| 
      
 79 
     | 
    
         
            +
                  def cleanup_later(object)
         
     | 
| 
      
 80 
     | 
    
         
            +
                    return nil unless object
         
     | 
| 
      
 81 
     | 
    
         
            +
                    @created_objects ||= []
         
     | 
| 
      
 82 
     | 
    
         
            +
                    @created_objects << object
         
     | 
| 
      
 83 
     | 
    
         
            +
                    object
         
     | 
| 
      
 84 
     | 
    
         
            +
                  end
         
     | 
| 
      
 85 
     | 
    
         
            +
             
     | 
| 
      
 86 
     | 
    
         
            +
                  # Find ActiveRecord object of given class by params.
         
     | 
| 
      
 87 
     | 
    
         
            +
                  # Marks the returned object to be destroyed at the end of scenario.
         
     | 
| 
      
 88 
     | 
    
         
            +
                  #
         
     | 
| 
      
 89 
     | 
    
         
            +
                  # @example
         
     | 
| 
      
 90 
     | 
    
         
            +
                  #     action do
         
     | 
| 
      
 91 
     | 
    
         
            +
                  #       # UI actions creating the user
         
     | 
| 
      
 92 
     | 
    
         
            +
                  #       @user = find_created(User, username: 'testuser')
         
     | 
| 
      
 93 
     | 
    
         
            +
                  #     end
         
     | 
| 
      
 94 
     | 
    
         
            +
                  #     it 'created' do
         
     | 
| 
      
 95 
     | 
    
         
            +
                  #       expect(@user).to_not be_nil
         
     | 
| 
      
 96 
     | 
    
         
            +
                  #     end
         
     | 
| 
      
 97 
     | 
    
         
            +
                  #     # No cleanup needed
         
     | 
| 
      
 98 
     | 
    
         
            +
                  #     # cleanup :user
         
     | 
| 
      
 99 
     | 
    
         
            +
                  #
         
     | 
| 
      
 100 
     | 
    
         
            +
                  # @param cls [Class] active record model class
         
     | 
| 
      
 101 
     | 
    
         
            +
                  # @param params [Hash] options for record finding
         
     | 
| 
      
 102 
     | 
    
         
            +
                  # @return [ActiveRecord::Base, nil] the object or nil if not found
         
     | 
| 
      
 103 
     | 
    
         
            +
                  # @see #cleanup_later called on the hood
         
     | 
| 
      
 104 
     | 
    
         
            +
                  def find_created(cls, params)
         
     | 
| 
      
 105 
     | 
    
         
            +
                    cleanup_later cls.where(params).take
         
     | 
| 
       18 
106 
     | 
    
         
             
                  end
         
     | 
| 
       19 
107 
     | 
    
         
             
                end
         
     | 
| 
       20 
108 
     | 
    
         | 
| 
       21 
     | 
    
         
            -
                # To be included in Lopata::ScenarioBuilder
         
     | 
| 
      
 109 
     | 
    
         
            +
                # To be included in Lopata::ScenarioBuilder. The methods may be used in build time.
         
     | 
| 
       22 
110 
     | 
    
         
             
                module DSL
         
     | 
| 
      
 111 
     | 
    
         
            +
                  # Mark instance variables to call #destroy at teardown phase of scenario or context running.
         
     | 
| 
      
 112 
     | 
    
         
            +
                  #
         
     | 
| 
      
 113 
     | 
    
         
            +
                  # Does nothing if 'keep' mode is enabled.
         
     | 
| 
      
 114 
     | 
    
         
            +
                  #
         
     | 
| 
      
 115 
     | 
    
         
            +
                  # @param vars [Array<Symbol, String>] instance variable names to be destroyed on teardown phase.
         
     | 
| 
       23 
116 
     | 
    
         
             
                  def cleanup(*vars, &block)
         
     | 
| 
       24 
117 
     | 
    
         
             
                    unless vars.empty?
         
     | 
| 
       25 
118 
     | 
    
         
             
                      teardown do
         
     | 
| 
         @@ -32,5 +125,12 @@ module Lopata 
     | 
|
| 
       32 
125 
     | 
    
         
             
              end
         
     | 
| 
       33 
126 
     | 
    
         
             
            end
         
     | 
| 
       34 
127 
     | 
    
         | 
| 
      
 128 
     | 
    
         
            +
            Lopata.configure do |c|
         
     | 
| 
      
 129 
     | 
    
         
            +
              c.after_scenario { cleanup @created_objects }
         
     | 
| 
      
 130 
     | 
    
         
            +
            end
         
     | 
| 
      
 131 
     | 
    
         
            +
             
     | 
| 
      
 132 
     | 
    
         
            +
            params = Lopata.environment['db']
         
     | 
| 
      
 133 
     | 
    
         
            +
            ActiveRecord::Base.establish_connection(params) if params
         
     | 
| 
      
 134 
     | 
    
         
            +
             
     | 
| 
       35 
135 
     | 
    
         
             
            Lopata::Scenario.include Lopata::ActiveRecord::Methods
         
     | 
| 
       36 
136 
     | 
    
         
             
            Lopata::ScenarioBuilder.include Lopata::ActiveRecord::DSL
         
     | 
    
        data/lib/lopata/condition.rb
    CHANGED
    
    | 
         @@ -1,4 +1,5 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            module Lopata
         
     | 
| 
      
 2 
     | 
    
         
            +
              # @private
         
     | 
| 
       2 
3 
     | 
    
         
             
              class Condition
         
     | 
| 
       3 
4 
     | 
    
         
             
                attr_reader :condition, :positive
         
     | 
| 
       4 
5 
     | 
    
         
             
                def initialize(condition, positive: true)
         
     | 
| 
         @@ -18,7 +19,7 @@ module Lopata 
     | 
|
| 
       18 
19 
     | 
    
         
             
                  when Hash
         
     | 
| 
       19 
20 
     | 
    
         
             
                    condition.keys.all? { |k| metadata[k] == condition[k] }
         
     | 
| 
       20 
21 
     | 
    
         
             
                  when Array
         
     | 
| 
       21 
     | 
    
         
            -
                    condition.map { |key| metadata[key] }. 
     | 
| 
      
 22 
     | 
    
         
            +
                    condition.map { |key| metadata[key] }.all?
         
     | 
| 
       22 
23 
     | 
    
         
             
                  else
         
     | 
| 
       23 
24 
     | 
    
         
             
                    metadata[condition]
         
     | 
| 
       24 
25 
     | 
    
         
             
                  end
         
     | 
| 
         @@ -0,0 +1,126 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            module Lopata
         
     | 
| 
      
 2 
     | 
    
         
            +
              # Stores runtime configuration information
         
     | 
| 
      
 3 
     | 
    
         
            +
              #
         
     | 
| 
      
 4 
     | 
    
         
            +
              # @see Lopata.configure
         
     | 
| 
      
 5 
     | 
    
         
            +
              # @see Lopata.configuration
         
     | 
| 
      
 6 
     | 
    
         
            +
              class Configuration
         
     | 
| 
      
 7 
     | 
    
         
            +
                # Build an object to store runtime configuration options and set defaults
         
     | 
| 
      
 8 
     | 
    
         
            +
                def initialize
         
     | 
| 
      
 9 
     | 
    
         
            +
                  @before_start_hooks = []
         
     | 
| 
      
 10 
     | 
    
         
            +
                  @before_scenario_steps = []
         
     | 
| 
      
 11 
     | 
    
         
            +
                  @after_scenario_steps = []
         
     | 
| 
      
 12 
     | 
    
         
            +
                  @observers = [Lopata::Observers::ConsoleOutputObserver.new]
         
     | 
| 
      
 13 
     | 
    
         
            +
                  @role_descriptions = {}
         
     | 
| 
      
 14 
     | 
    
         
            +
                  @env = :qa
         
     | 
| 
      
 15 
     | 
    
         
            +
                end
         
     | 
| 
      
 16 
     | 
    
         
            +
             
     | 
| 
      
 17 
     | 
    
         
            +
                # Add the hook to be called before scenarios running
         
     | 
| 
      
 18 
     | 
    
         
            +
                # The block will be called after framework initialization and before scenarios parsing.
         
     | 
| 
      
 19 
     | 
    
         
            +
                # It usually allow to require and initialize the libraries used for project testing.
         
     | 
| 
      
 20 
     | 
    
         
            +
                #
         
     | 
| 
      
 21 
     | 
    
         
            +
                # @example
         
     | 
| 
      
 22 
     | 
    
         
            +
                #     Lopata.configure do |c|
         
     | 
| 
      
 23 
     | 
    
         
            +
                #       c.before_start do
         
     | 
| 
      
 24 
     | 
    
         
            +
                #         require 'active_record'
         
     | 
| 
      
 25 
     | 
    
         
            +
                #       end
         
     | 
| 
      
 26 
     | 
    
         
            +
                #     end
         
     | 
| 
      
 27 
     | 
    
         
            +
                def before_start(&block)
         
     | 
| 
      
 28 
     | 
    
         
            +
                  @before_start_hooks << block
         
     | 
| 
      
 29 
     | 
    
         
            +
                end
         
     | 
| 
      
 30 
     | 
    
         
            +
             
     | 
| 
      
 31 
     | 
    
         
            +
                # @private
         
     | 
| 
      
 32 
     | 
    
         
            +
                def run_before_start_hooks
         
     | 
| 
      
 33 
     | 
    
         
            +
                  @before_start_hooks.each(&:call)
         
     | 
| 
      
 34 
     | 
    
         
            +
                end
         
     | 
| 
      
 35 
     | 
    
         
            +
             
     | 
| 
      
 36 
     | 
    
         
            +
                # Defines 'before scenario' steps.
         
     | 
| 
      
 37 
     | 
    
         
            +
                # Given steps will be runned before each scenario in context of scenario.
         
     | 
| 
      
 38 
     | 
    
         
            +
                # It may be shared step names, and|or block.
         
     | 
| 
      
 39 
     | 
    
         
            +
                #
         
     | 
| 
      
 40 
     | 
    
         
            +
                # @example
         
     | 
| 
      
 41 
     | 
    
         
            +
                #     Lopata.configure do |c|
         
     | 
| 
      
 42 
     | 
    
         
            +
                #       c.before_scenario 'setup test user'
         
     | 
| 
      
 43 
     | 
    
         
            +
                #     end
         
     | 
| 
      
 44 
     | 
    
         
            +
                #
         
     | 
| 
      
 45 
     | 
    
         
            +
                # @param steps [Array<String>] name of shared steps
         
     | 
| 
      
 46 
     | 
    
         
            +
                # @param block [Proc] block of code
         
     | 
| 
      
 47 
     | 
    
         
            +
                def before_scenario(*steps, &block)
         
     | 
| 
      
 48 
     | 
    
         
            +
                  before_scenario_steps.append(*steps) unless steps.empty?
         
     | 
| 
      
 49 
     | 
    
         
            +
                  before_scenario_steps.append(block) if block_given?
         
     | 
| 
      
 50 
     | 
    
         
            +
                end
         
     | 
| 
      
 51 
     | 
    
         
            +
             
     | 
| 
      
 52 
     | 
    
         
            +
                # Defines 'after scenario' steps.
         
     | 
| 
      
 53 
     | 
    
         
            +
                # Given steps will be runned after each scenario in context of scenario.
         
     | 
| 
      
 54 
     | 
    
         
            +
                # It may be shared step names, and|or block.
         
     | 
| 
      
 55 
     | 
    
         
            +
                #
         
     | 
| 
      
 56 
     | 
    
         
            +
                # @example
         
     | 
| 
      
 57 
     | 
    
         
            +
                #     Lopata.configure do |c|
         
     | 
| 
      
 58 
     | 
    
         
            +
                #       c.after_scenario 'cleanup test user'
         
     | 
| 
      
 59 
     | 
    
         
            +
                #     end
         
     | 
| 
      
 60 
     | 
    
         
            +
                #
         
     | 
| 
      
 61 
     | 
    
         
            +
                # @param steps [Array<String>] name of shared steps
         
     | 
| 
      
 62 
     | 
    
         
            +
                # @param block [Proc] block of code
         
     | 
| 
      
 63 
     | 
    
         
            +
                def after_scenario(*steps, &block)
         
     | 
| 
      
 64 
     | 
    
         
            +
                  after_scenario_steps.append(*steps) unless steps.empty?
         
     | 
| 
      
 65 
     | 
    
         
            +
                  after_scenario_steps.append(block) if block_given?
         
     | 
| 
      
 66 
     | 
    
         
            +
                end
         
     | 
| 
      
 67 
     | 
    
         
            +
             
     | 
| 
      
 68 
     | 
    
         
            +
                # @private
         
     | 
| 
      
 69 
     | 
    
         
            +
                attr_reader :before_scenario_steps, :after_scenario_steps
         
     | 
| 
      
 70 
     | 
    
         
            +
             
     | 
| 
      
 71 
     | 
    
         
            +
                # Add an observer to the set Lopata to be used for this run.
         
     | 
| 
      
 72 
     | 
    
         
            +
                #
         
     | 
| 
      
 73 
     | 
    
         
            +
                # @param observer [Lopata::Observers::BaseObserver] a observer instance.
         
     | 
| 
      
 74 
     | 
    
         
            +
                #
         
     | 
| 
      
 75 
     | 
    
         
            +
                # @see Lopata::Observers::BaseObserver
         
     | 
| 
      
 76 
     | 
    
         
            +
                def add_observer(observer)
         
     | 
| 
      
 77 
     | 
    
         
            +
                  @observers << observer
         
     | 
| 
      
 78 
     | 
    
         
            +
                end
         
     | 
| 
      
 79 
     | 
    
         
            +
             
     | 
| 
      
 80 
     | 
    
         
            +
                # @private
         
     | 
| 
      
 81 
     | 
    
         
            +
                attr_reader :observers
         
     | 
| 
      
 82 
     | 
    
         
            +
             
     | 
| 
      
 83 
     | 
    
         
            +
                # @private
         
     | 
| 
      
 84 
     | 
    
         
            +
                def filters
         
     | 
| 
      
 85 
     | 
    
         
            +
                  @filters ||= []
         
     | 
| 
      
 86 
     | 
    
         
            +
                end
         
     | 
| 
      
 87 
     | 
    
         
            +
             
     | 
| 
      
 88 
     | 
    
         
            +
                # @private
         
     | 
| 
      
 89 
     | 
    
         
            +
                attr_accessor :web_logging_params
         
     | 
| 
      
 90 
     | 
    
         
            +
             
     | 
| 
      
 91 
     | 
    
         
            +
                # @private
         
     | 
| 
      
 92 
     | 
    
         
            +
                def init_lopata_logging(url, project_code, build_number)
         
     | 
| 
      
 93 
     | 
    
         
            +
                  require 'lopata/observers/web_logger'
         
     | 
| 
      
 94 
     | 
    
         
            +
                  self.web_logging_params = { url: url, project_code: project_code, build_number: build_number }
         
     | 
| 
      
 95 
     | 
    
         
            +
                  add_observer Lopata::Observers::WebLogger.new
         
     | 
| 
      
 96 
     | 
    
         
            +
                end
         
     | 
| 
      
 97 
     | 
    
         
            +
             
     | 
| 
      
 98 
     | 
    
         
            +
                # @return [Hash{Symbol => String}] map or role codes to role name.
         
     | 
| 
      
 99 
     | 
    
         
            +
                # @see Lopata::Role
         
     | 
| 
      
 100 
     | 
    
         
            +
                attr_accessor :role_descriptions
         
     | 
| 
      
 101 
     | 
    
         
            +
             
     | 
| 
      
 102 
     | 
    
         
            +
                # @return [Symbol,nil] user role to be used in scenario if not specified
         
     | 
| 
      
 103 
     | 
    
         
            +
                # @see Lopata::Role
         
     | 
| 
      
 104 
     | 
    
         
            +
                attr_accessor :default_role
         
     | 
| 
      
 105 
     | 
    
         
            +
             
     | 
| 
      
 106 
     | 
    
         
            +
                # @return [Symbol] environment code.
         
     | 
| 
      
 107 
     | 
    
         
            +
                #   Default is :qa
         
     | 
| 
      
 108 
     | 
    
         
            +
                # @see Lopata::Environment
         
     | 
| 
      
 109 
     | 
    
         
            +
                attr_accessor :env
         
     | 
| 
      
 110 
     | 
    
         
            +
             
     | 
| 
      
 111 
     | 
    
         
            +
                # @return [Boolean] keep generated test data after scenarios running.
         
     | 
| 
      
 112 
     | 
    
         
            +
                #   Default is false
         
     | 
| 
      
 113 
     | 
    
         
            +
                #   Set to true for keeping generated data.
         
     | 
| 
      
 114 
     | 
    
         
            +
                #   Use 'lopata --keep' modifier to set keep mode on running.
         
     | 
| 
      
 115 
     | 
    
         
            +
                # @see Lopata::ActiveRecord::Methods#cleanup
         
     | 
| 
      
 116 
     | 
    
         
            +
                attr_accessor :keep
         
     | 
| 
      
 117 
     | 
    
         
            +
             
     | 
| 
      
 118 
     | 
    
         
            +
                # @private
         
     | 
| 
      
 119 
     | 
    
         
            +
                attr_accessor :environment
         
     | 
| 
      
 120 
     | 
    
         
            +
             
     | 
| 
      
 121 
     | 
    
         
            +
                # @private
         
     | 
| 
      
 122 
     | 
    
         
            +
                def load_environment
         
     | 
| 
      
 123 
     | 
    
         
            +
                  self.environment = Lopata::Environment.new(env)
         
     | 
| 
      
 124 
     | 
    
         
            +
                end
         
     | 
| 
      
 125 
     | 
    
         
            +
              end
         
     | 
| 
      
 126 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,36 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            module Lopata
         
     | 
| 
      
 2 
     | 
    
         
            +
              # Settings of test enviromnet the scenarios to be runned.
         
     | 
| 
      
 3 
     | 
    
         
            +
              #
         
     | 
| 
      
 4 
     | 
    
         
            +
              # Lopata allows to define different environments the scenarios to be runned on.
         
     | 
| 
      
 5 
     | 
    
         
            +
              # Set environment name via command line 'lopata -e stage' or via configuration:
         
     | 
| 
      
 6 
     | 
    
         
            +
              #
         
     | 
| 
      
 7 
     | 
    
         
            +
              #     Lopata.configure do |c|
         
     | 
| 
      
 8 
     | 
    
         
            +
              #       c.env = :stage
         
     | 
| 
      
 9 
     | 
    
         
            +
              #     end
         
     | 
| 
      
 10 
     | 
    
         
            +
              #
         
     | 
| 
      
 11 
     | 
    
         
            +
              # The environment params are loaded from './config/environments/<env>.yml'.
         
     | 
| 
      
 12 
     | 
    
         
            +
              class Environment
         
     | 
| 
      
 13 
     | 
    
         
            +
                # Loads environment configuration for given env
         
     | 
| 
      
 14 
     | 
    
         
            +
                # @param env [Symbol] environment key
         
     | 
| 
      
 15 
     | 
    
         
            +
                #    Loads golobl configured environment if not given.
         
     | 
| 
      
 16 
     | 
    
         
            +
                # @see Lopata::Configuration#env
         
     | 
| 
      
 17 
     | 
    
         
            +
                def initialize(env = Lopata.configuration.env)
         
     | 
| 
      
 18 
     | 
    
         
            +
                  require 'yaml'
         
     | 
| 
      
 19 
     | 
    
         
            +
                  @config = {}
         
     | 
| 
      
 20 
     | 
    
         
            +
                  config_filename = "./config/environments/#{Lopata.configuration.env}.yml"
         
     | 
| 
      
 21 
     | 
    
         
            +
                  @config = YAML::load(File.open(config_filename)) if File.exists?(config_filename)
         
     | 
| 
      
 22 
     | 
    
         
            +
                end
         
     | 
| 
      
 23 
     | 
    
         
            +
             
     | 
| 
      
 24 
     | 
    
         
            +
                # Access to environment settings
         
     | 
| 
      
 25 
     | 
    
         
            +
                # @param key [Symbol] environment configuration key is set on yml configuration.
         
     | 
| 
      
 26 
     | 
    
         
            +
                def [](key)
         
     | 
| 
      
 27 
     | 
    
         
            +
                  @config[key]
         
     | 
| 
      
 28 
     | 
    
         
            +
                end
         
     | 
| 
      
 29 
     | 
    
         
            +
             
     | 
| 
      
 30 
     | 
    
         
            +
                %w{url}.each do |opt|
         
     | 
| 
      
 31 
     | 
    
         
            +
                  define_method opt do
         
     | 
| 
      
 32 
     | 
    
         
            +
                    @config[opt]
         
     | 
| 
      
 33 
     | 
    
         
            +
                  end
         
     | 
| 
      
 34 
     | 
    
         
            +
                end
         
     | 
| 
      
 35 
     | 
    
         
            +
              end
         
     | 
| 
      
 36 
     | 
    
         
            +
            end
         
     | 
    
        data/lib/lopata/factory_bot.rb
    CHANGED
    
    | 
         @@ -1,23 +1,63 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            require_relative 'active_record'
         
     | 
| 
       2 
2 
     | 
    
         | 
| 
       3 
3 
     | 
    
         
             
            module Lopata
         
     | 
| 
      
 4 
     | 
    
         
            +
              # Helpers for FactoryBot usage in tests.
         
     | 
| 
      
 5 
     | 
    
         
            +
              #
         
     | 
| 
      
 6 
     | 
    
         
            +
              # Make helpers available in scenarios by
         
     | 
| 
      
 7 
     | 
    
         
            +
              #
         
     | 
| 
      
 8 
     | 
    
         
            +
              #     require 'lopata/factory_bot'
         
     | 
| 
      
 9 
     | 
    
         
            +
              #
         
     | 
| 
      
 10 
     | 
    
         
            +
              # Automatically adds ActiveRecord helpers.
         
     | 
| 
      
 11 
     | 
    
         
            +
              # @see Lopata::ActiveRecord
         
     | 
| 
      
 12 
     | 
    
         
            +
              #
         
     | 
| 
      
 13 
     | 
    
         
            +
              # Allows to create ActiveRecord object by FactoryBot definitions.
         
     | 
| 
      
 14 
     | 
    
         
            +
              # All the objects created by FactoryBot helpers will be destroyed automatically
         
     | 
| 
      
 15 
     | 
    
         
            +
              # at the end of scenario.
         
     | 
| 
      
 16 
     | 
    
         
            +
              # @see Lopata::ActiveRecord::Methods#cleanup
         
     | 
| 
      
 17 
     | 
    
         
            +
              #
         
     | 
| 
      
 18 
     | 
    
         
            +
              # @example
         
     | 
| 
      
 19 
     | 
    
         
            +
              #
         
     | 
| 
      
 20 
     | 
    
         
            +
              #     # Configure db connection at config/environments/qa.yml like rails:
         
     | 
| 
      
 21 
     | 
    
         
            +
              #     # db:
         
     | 
| 
      
 22 
     | 
    
         
            +
              #     #   adapter: postgresql
         
     | 
| 
      
 23 
     | 
    
         
            +
              #     #   host: your.database.host
         
     | 
| 
      
 24 
     | 
    
         
            +
              #     #   username: username
         
     | 
| 
      
 25 
     | 
    
         
            +
              #     #   password: password
         
     | 
| 
      
 26 
     | 
    
         
            +
              #     #   database: database
         
     | 
| 
      
 27 
     | 
    
         
            +
              #     require 'active_record'
         
     | 
| 
      
 28 
     | 
    
         
            +
              #     require 'factory_bot'
         
     | 
| 
      
 29 
     | 
    
         
            +
              #     require 'lopata/facotory_bot'
         
     | 
| 
      
 30 
     | 
    
         
            +
              #
         
     | 
| 
      
 31 
     | 
    
         
            +
              #     class User < ActiveRecord::Base; end
         
     | 
| 
      
 32 
     | 
    
         
            +
              #
         
     | 
| 
      
 33 
     | 
    
         
            +
              #     FactoryBot.define do
         
     | 
| 
      
 34 
     | 
    
         
            +
              #       factory :user do
         
     | 
| 
      
 35 
     | 
    
         
            +
              #         username { 'testuser' }
         
     | 
| 
      
 36 
     | 
    
         
            +
              #       end
         
     | 
| 
      
 37 
     | 
    
         
            +
              #     end
         
     | 
| 
      
 38 
     | 
    
         
            +
              #
         
     | 
| 
      
 39 
     | 
    
         
            +
              #     Lopata.define 'User creation' do
         
     | 
| 
      
 40 
     | 
    
         
            +
              #       setup do
         
     | 
| 
      
 41 
     | 
    
         
            +
              #         @user = create(:user)
         
     | 
| 
      
 42 
     | 
    
         
            +
              #       end
         
     | 
| 
      
 43 
     | 
    
         
            +
              #       # No cleanup needed - @user will be destroyed automatically
         
     | 
| 
      
 44 
     | 
    
         
            +
              #       # cleanup :user
         
     | 
| 
      
 45 
     | 
    
         
            +
              #
         
     | 
| 
      
 46 
     | 
    
         
            +
              #       it 'works' do
         
     | 
| 
      
 47 
     | 
    
         
            +
              #         expect(@user).to_not be_nil
         
     | 
| 
      
 48 
     | 
    
         
            +
              #       end
         
     | 
| 
      
 49 
     | 
    
         
            +
              #     end
         
     | 
| 
      
 50 
     | 
    
         
            +
              #
         
     | 
| 
       4 
51 
     | 
    
         
             
              module FactoryBot
         
     | 
| 
       5 
52 
     | 
    
         
             
                # To be included in Lopata::Scenario
         
     | 
| 
       6 
53 
     | 
    
         
             
                module Methods
         
     | 
| 
      
 54 
     | 
    
         
            +
                  # Wrapper for FactoryBot#create
         
     | 
| 
      
 55 
     | 
    
         
            +
                  # Calls the FactoryBot#create with given paramters and returns it result.
         
     | 
| 
      
 56 
     | 
    
         
            +
                  # Additionally store the created object for destroying at the end of scenario.
         
     | 
| 
      
 57 
     | 
    
         
            +
                  # @see Lopata::ActiveRecord::Methods#cleanup
         
     | 
| 
       7 
58 
     | 
    
         
             
                  def create(*params)
         
     | 
| 
       8 
59 
     | 
    
         
             
                    cleanup_later ::FactoryBot.create(*params)
         
     | 
| 
       9 
60 
     | 
    
         
             
                  end
         
     | 
| 
       10 
     | 
    
         
            -
             
     | 
| 
       11 
     | 
    
         
            -
                  def find_created(cls, params)
         
     | 
| 
       12 
     | 
    
         
            -
                    cleanup_later cls.where(params).take
         
     | 
| 
       13 
     | 
    
         
            -
                  end
         
     | 
| 
       14 
     | 
    
         
            -
             
     | 
| 
       15 
     | 
    
         
            -
                  def cleanup_later(object)
         
     | 
| 
       16 
     | 
    
         
            -
                    return nil unless object
         
     | 
| 
       17 
     | 
    
         
            -
                    @created_objects ||= []
         
     | 
| 
       18 
     | 
    
         
            -
                    @created_objects << object
         
     | 
| 
       19 
     | 
    
         
            -
                    object
         
     | 
| 
       20 
     | 
    
         
            -
                  end
         
     | 
| 
       21 
61 
     | 
    
         
             
                end
         
     | 
| 
       22 
62 
     | 
    
         | 
| 
       23 
63 
     | 
    
         
             
                # To be included in Lopata::ScenarioBuilder
         
     | 
| 
         @@ -29,8 +69,4 @@ end 
     | 
|
| 
       29 
69 
     | 
    
         
             
            Lopata::Scenario.include Lopata::FactoryBot::Methods
         
     | 
| 
       30 
70 
     | 
    
         
             
            Lopata::ScenarioBuilder.include Lopata::FactoryBot::DSL
         
     | 
| 
       31 
71 
     | 
    
         | 
| 
       32 
     | 
    
         
            -
             
     | 
| 
       33 
     | 
    
         
            -
              c.after_scenario { cleanup @created_objects }
         
     | 
| 
       34 
     | 
    
         
            -
            end
         
     | 
| 
       35 
     | 
    
         
            -
             
     | 
| 
       36 
     | 
    
         
            -
            ::FactoryBot.find_definitions unless Lopata::Config.readonly
         
     | 
| 
      
 72 
     | 
    
         
            +
            ::FactoryBot.find_definitions
         
     |