tune_spec 0.1.0 → 0.3.0

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: ba1ac17c65ab0ae068e158cc836591d4abaef024
4
- data.tar.gz: 3d92daa8e33f2d4e0a8e1ecf12bb46e76f47f969
3
+ metadata.gz: 94acadc6b27a86f11ef371aac9e2a90f180ea57b
4
+ data.tar.gz: 28eee0395583b8732170a452bec26176ecb2f1d0
5
5
  SHA512:
6
- metadata.gz: 42ac8bd3f9dffa5a88c4505ec3e9c5b0bc9294a8fd0b808641790e325f5bd165d6b3b73faa9adb0496979fc97dada22ab41d58e4c0db6d1b65f610032204dd1e
7
- data.tar.gz: 8451e1019f006a943aeadef2cae531b74d361d81b053d1d1f2d147d8414cd5c2a21a232f0afd1ed7876c24f54a9ae17ef6c3ae1c11ce5ce52452a236d8f7300a
6
+ metadata.gz: d4377597a557a0ddc9208e1fb88be8204debdced3dd17f2325f1580e0c9efa1a7a827d35dd3cd4500a15f20f35ac08a0253c6e799f528b97f673212e745becbf
7
+ data.tar.gz: 916bf7c6f7c77d25ffd7d4b0467b8991bbd6ffbc62ddcb63aa2ab8bb514a0afaadc18c1fffab1f5639ac59f86430072da8c7f89e3752777d466aad767a38972d
data/.gitignore CHANGED
@@ -1,2 +1,7 @@
1
+ *.gem
2
+ .yardoc/
3
+ doc/
4
+
1
5
  /tags
2
6
  *.swp
7
+ *.vim
data/Gemfile CHANGED
@@ -1,6 +1,8 @@
1
- source "https://rubygems.org"
1
+ # frozen_string_literal: true
2
2
 
3
- git_source(:github) {|repo_name| "https://github.com/#{repo_name}" }
3
+ source 'https://rubygems.org'
4
+
5
+ git_source(:github) { |repo_name| "https://github.com/#{repo_name}" }
4
6
 
5
7
  # Specify your gem's dependencies in tune_spec.gemspec
6
8
  gemspec
data/Gemfile.lock CHANGED
@@ -1,20 +1,43 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- tune_spec (0.1.0)
4
+ tune_spec (0.3.0)
5
5
 
6
6
  GEM
7
7
  remote: https://rubygems.org/
8
8
  specs:
9
- rake (10.5.0)
9
+ ast (2.3.0)
10
+ minitest (5.10.3)
11
+ parallel (1.12.0)
12
+ parser (2.4.0.0)
13
+ ast (~> 2.2)
14
+ powerpack (0.1.1)
15
+ rainbow (2.2.2)
16
+ rake
17
+ rake (12.1.0)
18
+ rubocop (0.50.0)
19
+ parallel (~> 1.10)
20
+ parser (>= 2.3.3.1, < 3.0)
21
+ powerpack (~> 0.1)
22
+ rainbow (>= 2.2.2, < 3.0)
23
+ ruby-progressbar (~> 1.7)
24
+ unicode-display_width (~> 1.0, >= 1.0.1)
25
+ ruby-progressbar (1.9.0)
26
+ unicode-display_width (1.3.0)
27
+ yard (0.9.9)
28
+ yard-doctest (0.1.10)
29
+ minitest
30
+ yard
10
31
 
11
32
  PLATFORMS
12
33
  ruby
13
34
 
14
35
  DEPENDENCIES
15
36
  bundler (~> 1.15)
16
- rake (~> 10.0)
37
+ rubocop (~> 0.50.0)
17
38
  tune_spec!
39
+ yard (~> 0.9.9)
40
+ yard-doctest (~> 0.1.10)
18
41
 
19
42
  BUNDLED WITH
20
- 1.15.4
43
+ 1.16.0.pre.3
data/README.md CHANGED
@@ -20,7 +20,53 @@ Or install it yourself as:
20
20
 
21
21
  ## Usage
22
22
 
23
- TODO: Write usage instructions here
23
+ To initialize framework folder structure run:
24
+
25
+ $ tune --init
26
+
27
+ It creates a folder tree within your working directory:
28
+
29
+ ```
30
+ lib
31
+ ├── groups
32
+ ├── pages
33
+ └── steps
34
+ ```
35
+
36
+ In your framework include the module:
37
+
38
+ ```ruby
39
+ include TuneSpec::Instances
40
+ ```
41
+
42
+ Then you can use TuneSpec DSL to store instances of your Groups, Steps and Page objects.
43
+ Assume that you have LoginPage object and LoginSteps and LoginGroups:
44
+ ```ruby
45
+ pages(:login).fill_in 'Email', with: 'user@example.com'
46
+ pages(:login).fill_in 'Password', with: 'password'
47
+ pages(:login).login.click
48
+ ```
49
+
50
+ Or in your LoginSteps you can describe steps as a a group of interactions and verifications on a page:
51
+ ```ruby
52
+ steps(:login).visit_page
53
+ steps(:login).login_with_valid_credentials
54
+ steps(:login).verify_login
55
+ ```
56
+
57
+ You can go further and organize your steps within a group when details don't matter
58
+ ```ruby
59
+ groups(:login).complete
60
+ ```
61
+
62
+ The default instantiation of each of your objects is configurable:
63
+ ```ruby
64
+ TuneSpec.configure do |config|
65
+ config.page_opts = { env: ENV['TEST_ENV'] }
66
+ config.steps_opts = { env: ENV['TEST_ENV'], page: :home }
67
+ config.groups_opts = {}
68
+ end
69
+ ```
24
70
 
25
71
  ## Development
26
72
 
data/bin/console CHANGED
@@ -1,7 +1,8 @@
1
1
  #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
2
3
 
3
- require "bundler/setup"
4
- require "tune_spec"
4
+ require 'bundler/setup'
5
+ require 'tune_spec'
5
6
 
6
- require "irb"
7
+ require 'irb'
7
8
  IRB.start(__FILE__)
data/doctest_helper.rb ADDED
@@ -0,0 +1,52 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'tune_spec'
4
+ require 'fileutils'
5
+
6
+ include TuneSpec::Instances
7
+ TEST_ENV = 'STG'
8
+
9
+ TuneSpec.configure do |conf|
10
+ conf.directory = 'test'
11
+ conf.groups_opts = { env: TEST_ENV }
12
+ conf.steps_opts = { env: TEST_ENV }
13
+ conf.page_opts = { env: TEST_ENV }
14
+ end
15
+
16
+ def create_file(name, type)
17
+ folder_name = type == :page ? 'pages' : type.to_s
18
+ file_name = "test/#{folder_name}/#{name}_#{type}.rb"
19
+ FileUtils.mkdir_p("test/#{folder_name}")
20
+ File.open(file_name, 'w+') { |f| f << file_content(name, type) }
21
+ end
22
+
23
+ def file_content(name, type)
24
+ <<~FILE
25
+ class_name = "#{name.capitalize}#{type.capitalize}"
26
+ klass = Object.const_set(class_name, Class.new)
27
+
28
+ klass.class_eval do
29
+ case "#{type}"
30
+ when 'groups'
31
+ define_method('initialize') do |env|; end
32
+ define_method('complete') do; end
33
+ when 'steps'
34
+ define_method('initialize') do |env, page_object|; end
35
+ define_method('verify_result') do; end
36
+ when 'page'
37
+ define_method('initialize') do |env|; end
38
+ define_method('click_element') do; end
39
+ end
40
+ end
41
+ FILE
42
+ end
43
+
44
+ create_file(:login, :groups)
45
+ create_file(:calculator, :steps)
46
+ create_file(:home, :page)
47
+
48
+ YARD::Doctest.configure do |doctest|
49
+ doctest.after_run do
50
+ FileUtils.rm_rf('test')
51
+ end
52
+ end
data/exe/tune CHANGED
@@ -1,4 +1,5 @@
1
1
  #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
2
3
 
3
4
  require 'bundler/setup'
4
5
  require 'tune_spec/parser'
@@ -0,0 +1,33 @@
1
+ # frozen_string_literal: true
2
+
3
+ module TuneSpec
4
+ # Defines all configurable attributes of TuneSpec
5
+ module Configuration
6
+ VALID_CONFIG_KEYS = %i[directory page_opts steps_opts groups_opts].freeze
7
+
8
+ DEFAULT_DIRECTORY = 'lib'
9
+
10
+ DEFAULT_PAGE_OPTS = {}.freeze
11
+
12
+ DEFAULT_STEPS_OPTS = {}.freeze
13
+
14
+ DEFAULT_GROUPS_OPTS = {}.freeze
15
+
16
+ VALID_CONFIG_KEYS.each { |key| attr_accessor key }
17
+
18
+ # Make sure the default values are set when the module is 'extended'
19
+ def self.extended(base)
20
+ base.reset
21
+ end
22
+
23
+ def configure
24
+ yield self
25
+ end
26
+
27
+ def reset
28
+ VALID_CONFIG_KEYS.each do |key|
29
+ send("#{key}=", self::Configuration.const_get("DEFAULT_#{key}".upcase))
30
+ end
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,23 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'tuner'
4
+
5
+ module TuneSpec
6
+ module Instances
7
+ # Defines the group behavior and rules
8
+ class Groups < Tuner
9
+ class << self
10
+ # Groups specific rules
11
+ def rules_passed?(instance, _args)
12
+ instance
13
+ end
14
+
15
+ private
16
+
17
+ def file_directory
18
+ "#{TuneSpec.directory}/#{type}"
19
+ end
20
+ end
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,23 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'tuner'
4
+
5
+ module TuneSpec
6
+ module Instances
7
+ # Defines pages behavior and rules
8
+ class Page < Tuner
9
+ class << self
10
+ # Page specific rules
11
+ def rules_passed?(instance, _args)
12
+ instance
13
+ end
14
+
15
+ private
16
+
17
+ def file_directory
18
+ "#{TuneSpec.directory}/#{type}s"
19
+ end
20
+ end
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,35 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'tuner'
4
+
5
+ module TuneSpec
6
+ module Instances
7
+ # Defines the steps behavior and rules
8
+ class Steps < Tuner
9
+ class << self
10
+ # Steps specific rules
11
+ def rules_passed?(instance, args)
12
+ same_page?(instance, args[1]) if args
13
+ end
14
+
15
+ private
16
+
17
+ # Verifies if the step requires a page_object
18
+ def same_page?(instance, page)
19
+ return false unless instance
20
+ return true unless instance.respond_to?(:page_object)
21
+ return true unless general_steps?(instance)
22
+ page.instance_of?(instance.page_object.class)
23
+ end
24
+
25
+ def general_steps?(instance)
26
+ argument_required?(:page_object, instance.class)
27
+ end
28
+
29
+ def file_directory
30
+ "#{TuneSpec.directory}/#{type}"
31
+ end
32
+ end
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,62 @@
1
+ # frozen_string_literal: true
2
+
3
+ module TuneSpec
4
+ module Instances
5
+ # Abstract class for Group, Step and Page
6
+ class Tuner
7
+ class << self
8
+ def instance_method_name(name)
9
+ "#{name}_#{type}".downcase
10
+ end
11
+
12
+ # A hook to define rules by subclasses
13
+ def rules_passed?(_instance, _args)
14
+ raise "Implement a #rules_passed? method for #{self}"
15
+ end
16
+
17
+ def format_args(args, object_klass)
18
+ default_args = fetch_default_args
19
+ args.tap do |arr|
20
+ default_args.each do |key, value|
21
+ arr.insert(0, value) if argument_required?(key, object_klass)
22
+ end
23
+ end
24
+ end
25
+
26
+ def call_object(file_name)
27
+ ensure_required(file_name)
28
+ const_name = file_name.split('_').each(&:capitalize!).join('')
29
+ const_get(const_name)
30
+ end
31
+
32
+ private
33
+
34
+ def type
35
+ @type ||= itself.to_s.split('::').last.downcase
36
+ end
37
+
38
+ def fetch_default_args
39
+ TuneSpec.__send__("#{type}_opts".downcase)
40
+ end
41
+
42
+ def argument_required?(arg, klass)
43
+ klass.instance_method(:initialize).parameters.flatten.include?(arg)
44
+ end
45
+
46
+ def ensure_required(name)
47
+ path = load_files.detect { |f| f.include?("/#{name}.rb") }
48
+ path ? require("./#{path}") : raise("Unable to find #{name}.rb")
49
+ end
50
+
51
+ def load_files
52
+ @files ||= Dir.glob("#{file_directory}/**/*")
53
+ end
54
+
55
+ # A hook to implement folder name by subclass
56
+ def file_directory
57
+ raise "Implement a #folder_name method for #{self}"
58
+ end
59
+ end
60
+ end
61
+ end
62
+ end
@@ -0,0 +1,76 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'instances/groups'
4
+ require_relative 'instances/steps'
5
+ require_relative 'instances/page'
6
+
7
+ module TuneSpec
8
+ # Maps instance variables of pages, steps and groups
9
+ # to corresponding objects under framework directory
10
+ module Instances
11
+ # Creates an instance of Group or calls an existing
12
+ #
13
+ # @param name [Symbol, String] the prefix of the Groups object class
14
+ # @param args [Any] additional optional arguments
15
+ # @param block [Block] that yields to self
16
+ # @return [GroupObject]
17
+ # @example
18
+ # groups(:login).complete
19
+ def groups(name, *args, &block)
20
+ instance_handler(name, Groups, *args, block)
21
+ end
22
+
23
+ # Creates an instance of Step or calls an existing
24
+ #
25
+ # @param name [Symbol, String] the prefix of the Step object class
26
+ # @param args [Any] additional optional arguments
27
+ # @param block [Block] that yields to self
28
+ # @return [StepObject]
29
+ # @example
30
+ # steps(:calculator, page: :home).verify_result
31
+ def steps(name, *args, page: nil, &block)
32
+ args.insert(0, pages(page)) if page
33
+ instance_handler(name, Steps, *args, block)
34
+ end
35
+
36
+ # Creates an instance of Page or calls an existing
37
+ #
38
+ # @param name [Symbol, String] the prefix of the Page object class
39
+ # @param args [Any] additional optional arguments
40
+ # @param block [Block] that yields to self
41
+ # @return [PageObject]
42
+ # @example
43
+ # pages(:home).click_element
44
+ def pages(name, *args, &block)
45
+ instance_handler(name, Page, *args, block)
46
+ end
47
+
48
+ private
49
+
50
+ # @private
51
+ def instance_handler(name, klass, *args, block)
52
+ method_name = klass.instance_method_name(name)
53
+ create_instance_method(method_name, klass)
54
+ instance_klass = klass.call_object(method_name)
55
+ formatted_args = klass.format_args(args, instance_klass)
56
+ call_instance_method(method_name, *formatted_args, block)
57
+ end
58
+
59
+ # @private
60
+ def create_instance_method(method_name, klass)
61
+ return if respond_to?(method_name)
62
+ define_singleton_method(method_name) do |*args|
63
+ instance_var = instance_variable_get("@#{method_name}")
64
+ return instance_var if klass.rules_passed?(instance_var, args)
65
+ new_instance = klass.call_object(method_name).new(*args)
66
+ instance_variable_set("@#{method_name}", new_instance)
67
+ end
68
+ end
69
+
70
+ # @private
71
+ def call_instance_method(method_name, *args, block)
72
+ return __send__(method_name, *args) unless block
73
+ __send__(method_name, *args).instance_eval(&block)
74
+ end
75
+ end
76
+ end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'optparse'
2
4
  require 'fileutils'
3
5
 
@@ -18,7 +20,8 @@ module TuneSpec
18
20
  parser.parse!(original_args)
19
21
  end
20
22
 
21
- def parser
23
+ # rubocop:disable MethodLength
24
+ def parser
22
25
  OptionParser.new do |parser|
23
26
  parser.summary_width = 34
24
27
 
@@ -27,9 +30,9 @@ module TuneSpec
27
30
  parser.on('--init [PATH]',
28
31
  'Create framework folder structure') do |dir|
29
32
  base_path = dir || 'lib'
30
- %w[groups pages steps].each do |dir|
33
+ %w[groups pages steps].each do |folder|
31
34
  FileUtils.mkdir_p(base_path)
32
- path = "#{base_path}/#{dir}"
35
+ path = "#{base_path}/#{folder}"
33
36
  exists = directory_exists?(path)
34
37
  print_directory(path, exists)
35
38
  create_directory(path) unless exists
@@ -45,7 +48,7 @@ module TuneSpec
45
48
  end
46
49
 
47
50
  def create_directory(dir)
48
- Dir.mkdir(dir)
51
+ Dir.mkdir(dir)
49
52
  end
50
53
 
51
54
  def directory_exists?(dir)
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module TuneSpec
2
- VERSION = "0.1.0"
4
+ VERSION = '0.3.0'
3
5
  end
data/lib/tune_spec.rb CHANGED
@@ -1,5 +1,12 @@
1
- require "tune_spec/version"
1
+ # frozen_string_literal: true
2
2
 
3
+ require 'tune_spec/configuration'
4
+ require 'tune_spec/version'
5
+
6
+ # Namespace for all TuneSpec objects
3
7
  module TuneSpec
4
- # Your code goes here...
8
+ extend Configuration
9
+ # TODO: Add method missing
5
10
  end
11
+
12
+ require 'tune_spec/instances'
data/tune_spec.gemspec CHANGED
@@ -1,24 +1,27 @@
1
- # coding: utf-8
2
- lib = File.expand_path("../lib", __FILE__)
1
+ # frozen_string_literal: true
2
+
3
+ lib = File.expand_path('../lib', __FILE__)
3
4
  $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
- require "tune_spec/version"
5
+ require 'tune_spec/version'
5
6
 
6
7
  Gem::Specification.new do |spec|
7
- spec.name = "tune_spec"
8
+ spec.name = 'tune_spec'
8
9
  spec.version = TuneSpec::VERSION
9
- spec.authors = ["Igor Starostenko"]
10
- spec.email = ["contactigorstar@gmail.com"]
10
+ spec.authors = ['Igor Starostenko']
11
+ spec.email = ['contactigorstar@gmail.com']
11
12
 
12
13
  spec.summary = "tune_spec_#{TuneSpec::VERSION}"
13
- spec.description = 'e2e Ruby tests in Page Objects'
14
- spec.homepage = "https://github.com/igor-starostenko/tune_spec"
15
- spec.license = "MIT"
14
+ spec.description = 'In Development. e2e Ruby tests in Page Objects'
15
+ spec.homepage = 'https://github.com/igor-starostenko/tune_spec'
16
+ spec.license = 'MIT'
16
17
 
17
18
  spec.files = `git ls-files -z`.split("\x0")
18
- spec.bindir = "exe"
19
+ spec.bindir = 'exe'
19
20
  spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
20
- spec.require_paths = ["lib"]
21
+ spec.require_paths = ['lib']
21
22
 
22
- spec.add_development_dependency "bundler", "~> 1.15"
23
- spec.add_development_dependency "rake", "~> 10.0"
23
+ spec.add_development_dependency 'bundler', '~> 1.15'
24
+ spec.add_development_dependency 'rubocop', '~> 0.50.0'
25
+ spec.add_development_dependency 'yard', '~> 0.9.9'
26
+ spec.add_development_dependency 'yard-doctest', '~> 0.1.10'
24
27
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: tune_spec
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Igor Starostenko
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2017-10-07 00:00:00.000000000 Z
11
+ date: 2017-10-14 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -25,20 +25,48 @@ dependencies:
25
25
  - !ruby/object:Gem::Version
26
26
  version: '1.15'
27
27
  - !ruby/object:Gem::Dependency
28
- name: rake
28
+ name: rubocop
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
31
  - - "~>"
32
32
  - !ruby/object:Gem::Version
33
- version: '10.0'
33
+ version: 0.50.0
34
34
  type: :development
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
38
  - - "~>"
39
39
  - !ruby/object:Gem::Version
40
- version: '10.0'
41
- description: e2e Ruby tests in Page Objects
40
+ version: 0.50.0
41
+ - !ruby/object:Gem::Dependency
42
+ name: yard
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: 0.9.9
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: 0.9.9
55
+ - !ruby/object:Gem::Dependency
56
+ name: yard-doctest
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: 0.1.10
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: 0.1.10
69
+ description: In Development. e2e Ruby tests in Page Objects
42
70
  email:
43
71
  - contactigorstar@gmail.com
44
72
  executables:
@@ -54,11 +82,17 @@ files:
54
82
  - Gemfile.lock
55
83
  - LICENSE
56
84
  - README.md
57
- - Rakefile
58
85
  - bin/console
59
86
  - bin/setup
87
+ - doctest_helper.rb
60
88
  - exe/tune
61
89
  - lib/tune_spec.rb
90
+ - lib/tune_spec/configuration.rb
91
+ - lib/tune_spec/instances.rb
92
+ - lib/tune_spec/instances/groups.rb
93
+ - lib/tune_spec/instances/page.rb
94
+ - lib/tune_spec/instances/steps.rb
95
+ - lib/tune_spec/instances/tuner.rb
62
96
  - lib/tune_spec/parser.rb
63
97
  - lib/tune_spec/version.rb
64
98
  - tune_spec.gemspec
@@ -85,5 +119,5 @@ rubyforge_project:
85
119
  rubygems_version: 2.6.12
86
120
  signing_key:
87
121
  specification_version: 4
88
- summary: tune_spec_0.1.0
122
+ summary: tune_spec_0.3.0
89
123
  test_files: []
data/Rakefile DELETED
@@ -1,2 +0,0 @@
1
- require "bundler/gem_tasks"
2
- task :default => :spec