lopata 0.1.1 → 0.1.6

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 9233d9fba2a55749f02037d5ca106c0cb9249debda448aac58ccc2cc724a378e
4
- data.tar.gz: 65ea743e92f5084b6f04b52595296cb80a3d4540f4cb8ba8bc2c774cbc448aaf
3
+ metadata.gz: 51ff4a162c7617388f8856b342449e1475f2438d8a44a6c58c6168373b144969
4
+ data.tar.gz: 10580190d2a63826f971d1730523eacc34ed818b634329da1635db07d2627d27
5
5
  SHA512:
6
- metadata.gz: a706fde4a5acc83b27400ce50c19137b7fd9f296bfb2ac4baeec55e50e5fe48b4bf6e90110611f4f69cd2dc9571a15d1de34e54e8bec094f0c2c2d5cc5ca1a87
7
- data.tar.gz: 2d0764e801260489815f30b8572ffdff7bdf6572fc64b55d0e53c091f8f125925374ae9cf706b1fe0bc956a6d56ef23b6dd1bd767b7ce13de550b4878dc86f4f
6
+ metadata.gz: 76f4fffc7d6755eb63d45a3297177c25b2e947c101dfad38b7a39e8bb474f00e3874d3b3fcf939a81d3ad550cc7d18335ac998104f0b0436db239d1f4688a0f5
7
+ data.tar.gz: '086e6cb580e94035e78607daa4a5ba6a5caf2211e37bc0e5cd9aa7cb1e2579fc22889e6fb90e17e6b4f290016a70d76f86d1d93d307d19e964b7584a3bee0451'
data/README.md CHANGED
@@ -1,6 +1,6 @@
1
- # Lopata - functional acceptance testing
1
+ # Lopata
2
2
 
3
- Motivation: use RSpec for functional testing.
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
@@ -1,6 +1,6 @@
1
1
  #!/usr/bin/env ruby
2
2
  require 'bundler/setup'
3
- require_relative '../lib/lopata/runner'
3
+ require 'lopata/runner'
4
4
 
5
5
  # use default command with arguments if given command is unknown.
6
6
  argv = ARGV.dup
@@ -1,11 +1,14 @@
1
1
  require 'lopata/id'
2
- require 'lopata/config'
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
 
8
9
  module Lopata
10
+ # Define the scenario.
11
+ # @see Lopata::ScenarioBuilder.define
9
12
  def self.define(*args, &block)
10
13
  Lopata::ScenarioBuilder.define(*args, &block)
11
14
  end
@@ -14,7 +17,57 @@ module Lopata
14
17
  def self.xdefine(*args, &block)
15
18
  end
16
19
 
20
+ # Register the shared step
21
+ #
22
+ # @example
23
+ # Lopata.shared_step 'test user' do
24
+ # setup { @user = create(:user) }
25
+ # end
26
+ #
27
+ # Shared step may be used in scenarios by name:
28
+ # @example
29
+ # Lopata.define 'user' do
30
+ # setup 'test user'
31
+ #
32
+ # it 'exists' do
33
+ # expect(@user).to_not be_nil
34
+ # end
35
+ # end
36
+ # @param name [String] shared step unique name
37
+ # @param block shared step action sequence definition
17
38
  def self.shared_step(name, &block)
18
39
  Lopata::SharedStep.register(name, &block)
19
40
  end
41
+
42
+ # Yields the global configuration to a block.
43
+ # @yield [Lopata::Configuration] global configuration
44
+ #
45
+ # @example
46
+ # Lopata.configure do |config|
47
+ # config.before_scenario 'setup test user'
48
+ # end
49
+ # @see Lopata::Configuration
50
+ def self.configure(&block)
51
+ yield Lopata.configuration
52
+ end
53
+
54
+ # Returns global configuration object.
55
+ # @return [Lopata::Configuration]
56
+ # @see Lopata.configure
57
+ def self.configuration
58
+ @configuration ||= Lopata::Configuration.new
59
+ end
60
+
61
+ # @private
62
+ # Internal container for global non-configuration data.
63
+ def self.world
64
+ @world ||= Lopata::World.new
65
+ end
66
+
67
+ # Return global environment object
68
+ # @return [Lopata::Environment]
69
+ # @see Lopata::Environment
70
+ def self.environment
71
+ Lopata.configuration.environment
72
+ end
20
73
  end
@@ -0,0 +1,99 @@
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
+ #
34
+ module ActiveRecord
35
+ # To be included in Lopata::Scenario. The methods may be used in runtime.
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
47
+ def cleanup(*objects)
48
+ return if Lopata.configuration.keep
49
+ objects.flatten.compact.each do |o|
50
+ begin
51
+ o.reload.destroy!
52
+ rescue ::ActiveRecord::RecordNotFound
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!
57
+ end
58
+ end
59
+ end
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
71
+ def reload(*objects)
72
+ objects.flatten.compact.each(&:reload)
73
+ end
74
+ end
75
+
76
+ # To be included in Lopata::ScenarioBuilder. The methods may be used in build time.
77
+ module DSL
78
+ # Mark instance variables to call #destroy at teardown phase of scenario or context running.
79
+ #
80
+ # Does nothing if 'keep' mode is enabled.
81
+ #
82
+ # @param vars [Array<Symbol, String>] instance variable names to be destroyed on teardown phase.
83
+ def cleanup(*vars, &block)
84
+ unless vars.empty?
85
+ teardown do
86
+ cleanup vars.map { |v| instance_variable_get "@#{v}" }
87
+ end
88
+ end
89
+ teardown &block if block_given?
90
+ end
91
+ end
92
+ end
93
+ end
94
+
95
+ params = Lopata.environment['db']
96
+ ActiveRecord::Base.establish_connection(params) if params
97
+
98
+ Lopata::Scenario.include Lopata::ActiveRecord::Methods
99
+ Lopata::ScenarioBuilder.include Lopata::ActiveRecord::DSL
@@ -1,12 +1,11 @@
1
1
  module Lopata
2
+ # @private
2
3
  class Condition
3
4
  attr_reader :condition, :positive
4
5
  def initialize(condition, positive: true)
5
6
  @condition, @positive = condition, positive
6
7
  end
7
8
 
8
- EMPTY = new({})
9
-
10
9
  alias positive? positive
11
10
 
12
11
  def match?(scenario)
@@ -20,7 +19,7 @@ module Lopata
20
19
  when Hash
21
20
  condition.keys.all? { |k| metadata[k] == condition[k] }
22
21
  when Array
23
- condition.map { |key| metadata[key] }.none?(&:nil?)
22
+ condition.map { |key| metadata[key] }.all?
24
23
  else
25
24
  metadata[condition]
26
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
@@ -0,0 +1,36 @@
1
+ require_relative 'active_record'
2
+
3
+ module Lopata
4
+ module FactoryBot
5
+ # To be included in Lopata::Scenario
6
+ module Methods
7
+ def create(*params)
8
+ cleanup_later ::FactoryBot.create(*params)
9
+ 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
+ end
22
+
23
+ # To be included in Lopata::ScenarioBuilder
24
+ module DSL
25
+ end
26
+ end
27
+ end
28
+
29
+ Lopata::Scenario.include Lopata::FactoryBot::Methods
30
+ Lopata::ScenarioBuilder.include Lopata::FactoryBot::DSL
31
+
32
+ Lopata.configure do |c|
33
+ c.after_scenario { cleanup @created_objects }
34
+ end
35
+
36
+ ::FactoryBot.find_definitions
@@ -11,10 +11,8 @@ module Lopata
11
11
  def create_root_files
12
12
  template 'Lopatafile', "#{name}/Lopatafile"
13
13
  template 'Gemfile', "#{name}/Gemfile"
14
- template '.rspec', "#{name}/.rspec"
15
14
  template 'config/environments/qa.yml', "#{name}/config/environments/qa.yml"
16
15
  template 'config/initializers/capybara.rb', "#{name}/config/initializers/capybara.rb"
17
- template 'spec/spec_helper.rb', "#{name}/spec/spec_helper.rb"
18
16
  end
19
17
 
20
18
  def init_dirs