ruby_raider 0.4.1 → 0.4.3

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.
Files changed (42) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +3 -6
  3. data/README.md +6 -0
  4. data/lib/commands/scaffolding_commands.rb +2 -2
  5. data/lib/commands/utility_commands.rb +8 -0
  6. data/lib/generators/automation_generator.rb +7 -7
  7. data/lib/generators/common_generator.rb +2 -0
  8. data/lib/generators/cucumber_generator.rb +1 -1
  9. data/lib/generators/helper_generator.rb +6 -0
  10. data/lib/generators/menu_generator.rb +9 -5
  11. data/lib/generators/rspec_generator.rb +2 -2
  12. data/lib/generators/templates/automation/abstract_page.tt +4 -0
  13. data/lib/generators/templates/automation/appium_caps.tt +7 -0
  14. data/lib/generators/templates/automation/home_page.tt +1 -5
  15. data/lib/generators/templates/automation/partials/android_caps.tt +5 -0
  16. data/lib/generators/templates/automation/partials/cross_platform_caps.tt +14 -0
  17. data/lib/generators/templates/automation/partials/home_page_selector.tt +8 -0
  18. data/lib/generators/templates/automation/partials/ios_caps.tt +6 -0
  19. data/lib/generators/templates/automation/partials/pdp_page_selector.tt +8 -0
  20. data/lib/generators/templates/automation/pdp_page.tt +1 -5
  21. data/lib/generators/templates/common/config.tt +5 -2
  22. data/lib/generators/templates/common/partials/mobile_config.tt +1 -0
  23. data/lib/generators/templates/common/partials/web_config.tt +2 -0
  24. data/lib/generators/templates/common/read_me.tt +4 -0
  25. data/lib/generators/templates/helpers/appium_helper.tt +29 -0
  26. data/lib/generators/templates/helpers/driver_helper.tt +15 -2
  27. data/lib/generators/templates/helpers/partials/driver_and_options.tt +8 -5
  28. data/lib/generators/templates/helpers/raider_helper.tt +3 -0
  29. data/lib/utilities/utilities.rb +5 -0
  30. data/ruby_raider.gemspec +2 -1
  31. data/spec/automation_generator_spec.rb +33 -150
  32. data/spec/common_generator_spec.rb +58 -105
  33. data/spec/cucumber_generator_spec.rb +18 -53
  34. data/spec/helpers_generator_spec.rb +73 -90
  35. data/spec/rspec_generator_spec.rb +15 -61
  36. data/spec/scaffolding_commands_spec.rb +162 -0
  37. data/spec/spec_helper.rb +20 -0
  38. metadata +26 -6
  39. data/lib/generators/templates/automation/appium_settings.tt +0 -5
  40. data/lib/generators/templates/automation/partials/android_settings.tt +0 -8
  41. data/lib/generators/templates/automation/partials/ios_settings.tt +0 -8
  42. data/spec/scaffolding_spec.rb +0 -234
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 717ea9978a9909bc5d4d78f717b8da94ebc7e76945ec638ceeb35bb9aa5a9281
4
- data.tar.gz: f6f390ee74bc484a763e4e0daf8f4cd08a5e8ed630d5284656a18efc0bffe91d
3
+ metadata.gz: 1179dcf5f2664b6adea02db8af1b33883f18d095f9c9b57acf3fa2bb56d68c49
4
+ data.tar.gz: ad8dc4b695f154191047406e882029b063c4147987adf369c018063d38b414c9
5
5
  SHA512:
6
- metadata.gz: 61718cc0edcd9dd89d65d25e0aa80032351921495bdcb3b4f69808e93ba448c1c859f2289e8008a94d7efd5987524fc510c8e17bc3e6a19ffa7b0dfa7828aa2c
7
- data.tar.gz: ce72aba02cf4813232ba7c3e4b0f5ec8d7688b56194ab066d32c8cd6a95c76f5395b16c5fece33150408191d4c95e15e66dd929d1eab497beb0bd28ed895c87f
6
+ metadata.gz: d052c0513c67e27313cdcff208ab5ed54a6606722480ab3534b2c84976b0fffd0a8675367b278575ec1181b7a48f695ed08643cee5bf5229c317c136359fc171
7
+ data.tar.gz: 1130758fd998eecfb68f320968c3993ea5d026c362ebcc22068ae28c4b0301084e0fb9b6d116a8e2f06e14cecba91b25d37d0e4d81595a1e565cc3917c3de512
data/.rubocop.yml CHANGED
@@ -1,8 +1,5 @@
1
- require: rubocop-rspec
2
-
3
- AllCops:
4
- Exclude:
5
- - './spec/*'
1
+ require:
2
+ - rubocop-rspec
6
3
 
7
4
  # Layout
8
5
  Layout/CaseIndentation:
@@ -86,7 +83,7 @@ Style/HashTransformValues:
86
83
 
87
84
  Style/SafeNavigation:
88
85
  Description: "Use &. instead of checking if an object exists"
89
- Enabled: false
86
+ Enabled: true
90
87
 
91
88
  Style/SingleLineBlockParams:
92
89
  Description: 'Enforces the names of some block params.'
data/README.md CHANGED
@@ -47,6 +47,10 @@ Ruby Raider is a generator and scaffolding gem to make UI test automation easier
47
47
 
48
48
  * Generating a framework with Cucumber and Appium for Android
49
49
 
50
+ * Generating a framework with Rspec and Appium cross platform
51
+
52
+ * Generating a framework with Cucumber and Appium cross platform
53
+
50
54
  ***In order to run the Appium tests, download the example [app](https://github.com/saucelabs/my-demo-app-rn).***
51
55
 
52
56
  This works in all the platforms (Tested on Mac OS, Linux and Windows).
@@ -92,6 +96,8 @@ Commands:
92
96
  raider page [PAGE_NAME] # Creates a new page object
93
97
 
94
98
  raider path [PATH] # Sets the default path for scaffolding
99
+
100
+ raider platform [PLATFORM] # Sets the default platform for a cross-platform project
95
101
 
96
102
  raider raid # Runs all the tests in a project
97
103
 
@@ -86,7 +86,7 @@ class ScaffoldingCommands < UtilityCommands
86
86
  def scaffold(name)
87
87
  if Pathname.new('spec').exist? && !Pathname.new('features').exist?
88
88
  Scaffolding.new([name, load_config_path('spec')]).generate_spec
89
- elsif Pathname.new('features').exist?
89
+ else
90
90
  Scaffolding.new([name, load_config_path('feature')]).generate_feature
91
91
  end
92
92
  Scaffolding.new([name, load_config_path('page')]).generate_class
@@ -110,7 +110,7 @@ class ScaffoldingCommands < UtilityCommands
110
110
 
111
111
  no_commands do
112
112
  def load_config_path(type)
113
- YAML.load_file('config/config.yml')["#{type}_path"] if YAML.load_file('config/config.yml')
113
+ YAML.load_file('config/config.yml')["#{type}_path"] if Pathname.new('config/config.yml').exist?
114
114
  end
115
115
  end
116
116
  end
@@ -72,4 +72,12 @@ class UtilityCommands < Thor
72
72
  type: :string, required: false, desc: 'The path where your config file will be created', aliases: '-p'
73
73
  option :delete,
74
74
  type: :boolean, required: false, desc: 'This will delete the selected config file', aliases: '-d'
75
+
76
+ desc 'platform [platform]', 'Sets the default platform for a cross-platform project'
77
+
78
+ def platform(platform)
79
+ Utilities.new.platform = platform
80
+ end
81
+
82
+ map '-pl' => 'platform'
75
83
  end
@@ -4,7 +4,7 @@ require_relative 'generator'
4
4
 
5
5
  class AutomationGenerator < Generator
6
6
  def generate_login_page
7
- return unless (@_initializer.first & %w[android ios]).empty?
7
+ return unless (@_initializer.first & %w[android ios cross_platform]).empty?
8
8
 
9
9
  template('automation/login_page.tt', "#{name}/page_objects/pages/login_page.rb")
10
10
  end
@@ -14,32 +14,32 @@ class AutomationGenerator < Generator
14
14
  end
15
15
 
16
16
  def generate_home_page
17
- return if (@_initializer.first & %w[android ios]).empty?
17
+ return if (@_initializer.first & %w[android ios cross_platform]).empty?
18
18
 
19
19
  template('automation/home_page.tt', "#{name}/page_objects/pages/home_page.rb")
20
20
  end
21
21
 
22
22
  def generate_pdp_page
23
- return if (@_initializer.first & %w[android ios]).empty?
23
+ return if (@_initializer.first & %w[android ios cross_platform]).empty?
24
24
 
25
25
  template('automation/pdp_page.tt', "#{name}/page_objects/pages/pdp_page.rb")
26
26
  end
27
27
 
28
28
  def generate_header_component
29
- return unless (@_initializer.first & %w[android ios]).empty?
29
+ return unless (@_initializer.first & %w[android ios cross_platform]).empty?
30
30
 
31
31
  template('automation/component.tt', "#{name}/page_objects/components/header_component.rb")
32
32
  end
33
33
 
34
34
  def generate_abstract_component
35
- return unless (@_initializer.first & %w[android ios]).empty?
35
+ return unless (@_initializer.first & %w[android ios cross_platform]).empty?
36
36
 
37
37
  template('automation/abstract_component.tt', "#{name}/page_objects/abstract/abstract_component.rb")
38
38
  end
39
39
 
40
40
  def generate_appium_settings
41
- return if (@_initializer.first & %w[android ios]).empty?
41
+ return if (@_initializer.first & %w[android ios cross_platform]).empty?
42
42
 
43
- template('automation/appium_settings.tt', "#{name}/appium.txt")
43
+ template('automation/appium_caps.tt', "#{name}/config/capabilities.yml")
44
44
  end
45
45
  end
@@ -8,6 +8,8 @@ class CommonGenerator < Generator
8
8
  end
9
9
 
10
10
  def generate_config_file
11
+ return unless (@_initializer.first & %w[android ios]).empty?
12
+
11
13
  template('common/config.tt', "#{name}/config/config.yml")
12
14
  end
13
15
 
@@ -20,6 +20,6 @@ class CucumberGenerator < Generator
20
20
  end
21
21
 
22
22
  def template_name
23
- @template_name ||= (@_initializer.first & %w[android ios]).empty? ? 'login' : 'home'
23
+ @template_name ||= (@_initializer.first & %w[android ios cross_platform]).empty? ? 'login' : 'home'
24
24
  end
25
25
  end
@@ -30,4 +30,10 @@ class HelpersGenerator < Generator
30
30
 
31
31
  template('helpers/driver_helper.tt', "#{name}/helpers/driver_helper.rb")
32
32
  end
33
+
34
+ def generate_pdp_page
35
+ return unless (@_initializer.first.include?('cross_platform'))
36
+
37
+ template('helpers/appium_helper.tt', "#{name}/helpers/appium_helper.rb")
38
+ end
33
39
  end
@@ -31,9 +31,8 @@ class MenuGenerator
31
31
  select_test_framework(automation)
32
32
  end
33
33
 
34
- def set_framework(automation, framework)
35
- add_generator framework.capitalize
36
- generators.each { |generator| invoke_generator(automation, framework, generator) }
34
+ def set_up_framework(automation, framework)
35
+ generate_framework(automation, framework)
37
36
  system "cd #{name} && gem install bundler && bundle install"
38
37
  end
39
38
 
@@ -41,11 +40,16 @@ class MenuGenerator
41
40
  prompt.select('Please select your mobile platform') do |menu|
42
41
  menu.choice :iOS, -> { choose_test_framework 'ios' }
43
42
  menu.choice :Android, -> { choose_test_framework 'android' }
44
- menu.choice :Cross_Platform, -> { error_handling('Cross Platform') }
43
+ menu.choice :Cross_Platform, -> { choose_test_framework 'cross_platform' }
45
44
  menu.choice :Quit, -> { exit }
46
45
  end
47
46
  end
48
47
 
48
+ def generate_framework(automation, framework)
49
+ add_generator framework.capitalize
50
+ generators.each { |generator| invoke_generator(automation, framework, generator) }
51
+ end
52
+
49
53
  protected
50
54
 
51
55
  def add_generator(*opts)
@@ -55,7 +59,7 @@ class MenuGenerator
55
59
  private
56
60
 
57
61
  def framework_choice(framework, automation_type)
58
- set_framework(automation_type, framework.downcase)
62
+ set_up_framework(automation_type, framework.downcase)
59
63
  prompt.say("You have chosen to use #{framework} with #{automation_type}")
60
64
  end
61
65
 
@@ -4,13 +4,13 @@ require_relative 'generator'
4
4
 
5
5
  class RspecGenerator < Generator
6
6
  def generate_login_spec
7
- return unless (@_initializer.first & %w[android ios]).empty?
7
+ return unless (@_initializer.first & %w[android ios cross_platform]).empty?
8
8
 
9
9
  template('rspec/spec.tt', "#{name}/spec/login_page_spec.rb")
10
10
  end
11
11
 
12
12
  def generate_pdp_spec
13
- return if (@_initializer.first & %w[android ios]).empty?
13
+ return if (@_initializer.first & %w[android ios cross_platform]).empty?
14
14
 
15
15
  template('rspec/spec.tt', "#{name}/spec/pdp_page_spec.rb")
16
16
  end
@@ -1,6 +1,10 @@
1
1
  <%= ERB.new(File.read(File.expand_path('./partials/require_raider.tt', __dir__)), nil, '-').result(binding) -%>
2
2
 
3
3
  class AbstractPage
4
+ <% if automation == 'cross_platform' %>
5
+ include Raider::AppiumHelper
6
+ <% end %>
7
+
4
8
  <%= ERB.new(File.read(File.expand_path('./partials/initialize_selector.tt', __dir__))).result(binding) -%>
5
9
  <%= ERB.new(File.read(File.expand_path('./partials/visit_method.tt', __dir__))).result(binding) -%>
6
10
  <%= ERB.new(File.read(File.expand_path('./partials/url_methods.tt', __dir__))).result(binding) -%>
@@ -0,0 +1,7 @@
1
+ <% if automation == 'ios' %>
2
+ <%= ERB.new(File.read(File.expand_path('./partials/ios_caps.tt', __dir__))).result(binding) -%>
3
+ <% elsif automation == 'android' %>
4
+ <%= ERB.new(File.read(File.expand_path('./partials/android_caps.tt', __dir__))).result(binding) -%>
5
+ <% else %>
6
+ <%= ERB.new(File.read(File.expand_path('./partials/cross_platform_caps.tt', __dir__))).result(binding) -%>
7
+ <% end %>
@@ -15,10 +15,6 @@ class HomePage < AbstractPage
15
15
  # Elements
16
16
 
17
17
  def backpack_image
18
- <% if automation == 'ios' %>
19
- driver.find_element(predicate: 'label == "Sauce Labs Backpack"')
20
- <% else %>
21
- driver.find_element(xpath: '(//android.view.ViewGroup[@content-desc="store item"])[1]/android.view.ViewGroup[1]')
22
- <% end %>
18
+ <%= ERB.new(File.read(File.expand_path('./partials/home_page_selector.tt', __dir__))).result(binding) %>
23
19
  end
24
20
  end
@@ -0,0 +1,5 @@
1
+ automationName: UiAutomator2
2
+ platformName: Android
3
+ deviceName: Nexus_7_API_33
4
+ app: "Android-MyDemoAppRN.1.3.0.build-244.apk"
5
+ autoGrantPermissions: true
@@ -0,0 +1,14 @@
1
+ android:
2
+ automationName: UiAutomator2
3
+ platformName: Android
4
+ deviceName: Nexus_7_API_33
5
+ app: "Android-MyDemoAppRN.1.3.0.build-244.apk"
6
+ autoGrantPermissions: true
7
+
8
+ ios:
9
+ automationName: XCUITest
10
+ platformName: iOS
11
+ platformVersion: "15.5"
12
+ deviceName: iPhone 11
13
+ app: "MyRNDemoApp.app"
14
+ autoDismissAlerts: true
@@ -0,0 +1,8 @@
1
+ <% if automation == 'ios' %>
2
+ driver.find_element(predicate: 'label == "Sauce Labs Backpack"')
3
+ <% elsif automation == 'android' %>
4
+ driver.find_element(xpath: '(//android.view.ViewGroup[@content-desc="store item"])[1]/android.view.ViewGroup[1]')
5
+ <% else %>
6
+ element(ios: { predicate: 'label == "Sauce Labs Backpack"' },
7
+ android: { xpath: '(//android.view.ViewGroup[@content-desc="store item"])[1]/android.view.ViewGroup[1]' })
8
+ <% end %>
@@ -0,0 +1,6 @@
1
+ automationName: XCUITest
2
+ platformName: iOS
3
+ platformVersion: "15.5"
4
+ deviceName: iPhone 11
5
+ app: "MyRNDemoApp.app"
6
+ autoDismissAlerts: true
@@ -0,0 +1,8 @@
1
+ <% if automation == 'ios' %>
2
+ driver.find_element(accessibility_id: 'Add To Cart button')
3
+ <% elsif automation == 'android' %>
4
+ driver.find_element(xpath: '//android.view.ViewGroup[@content-desc="Add To Cart button"]/android.widget.TextView')
5
+ <% else %>
6
+ element(ios: { accessibility_id: 'Add To Cart button' },
7
+ android: { xpath: '//android.view.ViewGroup[@content-desc="Add To Cart button"]/android.widget.TextView' })
8
+ <% end %>
@@ -13,10 +13,6 @@ class PdpPage < AbstractPage
13
13
  # Elements
14
14
 
15
15
  def add_to_cart_button
16
- <% if automation == 'ios' %>
17
- driver.find_element(accessibility_id: 'Add To Cart button')
18
- <% else %>
19
- driver.find_element(xpath: '//android.view.ViewGroup[@content-desc="Add To Cart button"]/android.widget.TextView')
20
- <% end %>
16
+ <%= ERB.new(File.read(File.expand_path('./partials/pdp_page_selector.tt', __dir__))).result(binding) %>
21
17
  end
22
18
  end
@@ -1,2 +1,5 @@
1
- browser: :chrome
2
- url: 'https://automationteststore.com/'
1
+ <% if %w[ios android cross_platform].include?(automation) -%>
2
+ <%= ERB.new(File.read(File.expand_path('./partials/mobile_config.tt', __dir__))).result(binding) %>
3
+ <% else -%>
4
+ <%= ERB.new(File.read(File.expand_path('./partials/web_config.tt', __dir__))).result(binding) %>
5
+ <% end -%>
@@ -0,0 +1 @@
1
+ platform: :ios
@@ -0,0 +1,2 @@
1
+ browser: :chrome
2
+ url: 'https://automationteststore.com/'
@@ -18,6 +18,8 @@ Currently we only support:
18
18
  * Gerating a Selenium with both Cucumber and Rspec framework
19
19
  * Gerating a Watir with both Cucumber and Rspec framework
20
20
  * Generating an Appium project with Rspec and Cucumber on IOS
21
+ * Generating an Appium project with Rspec and Cucumber on Android
22
+ * Generating an Appium project with Rspec and Cucumber cross platform
21
23
 
22
24
  In order to run the appium tests, download the example [app](https://github.com/cloudgrey-io/the-app/releases/tag/v1.10.0)
23
25
 
@@ -40,6 +42,8 @@ Commands:
40
42
 
41
43
  raider path [PATH] # Sets the default path for scaffolding
42
44
 
45
+ raider platform [PLATFORM] # Sets the default platform for a cross-platform project
46
+
43
47
  raider raid # It runs all the tests in a project
44
48
 
45
49
  raider scaffold [SCAFFOLD_NAME] # It generates everything needed to start automating
@@ -0,0 +1,29 @@
1
+ module Raider
2
+ module AppiumHelper
3
+ def element(opts = {})
4
+ return driver.find_element(strategy(opts) => selector(opts)) if opts[os]
5
+
6
+ driver.find_element(opts)
7
+ end
8
+
9
+ def elements(opts = {})
10
+ return driver.find_elements(strategy(opts) => selector(opts)) if opts[os]
11
+
12
+ driver.find_elements(opts)
13
+ end
14
+
15
+ def os
16
+ driver.appium_device
17
+ end
18
+
19
+ private
20
+
21
+ def strategy(opts)
22
+ opts[os].keys.first
23
+ end
24
+
25
+ def selector(opts)
26
+ opts[os][strategy(opts)]
27
+ end
28
+ end
29
+ end
@@ -9,8 +9,21 @@ require 'appium_lib'
9
9
 
10
10
  module Raider
11
11
  module DriverHelper
12
- attr_reader :driver
12
+ attr_reader :driver
13
13
 
14
- <%= ERB.new(File.read(File.expand_path('./partials/driver_and_options.tt', __dir__))).result(binding).strip! %>
14
+ <%= ERB.new(File.read(File.expand_path('./partials/driver_and_options.tt', __dir__))).result(binding).strip! %>
15
+
16
+ <% if automation == 'cross_platform' -%>
17
+ private
18
+
19
+ def config
20
+ YAML.load_file('config/config.yml')
21
+ end
22
+ <% end -%>
23
+ <% if automation != 'selenium' -%>
24
+ def caps
25
+ YAML.load_file('config/capabilities.yml')
26
+ end
27
+ <% end -%>
15
28
  end
16
29
  end
@@ -16,10 +16,13 @@
16
16
  opts.each {|option| caps.add_argument(option) }
17
17
  caps
18
18
  end
19
+ <% elsif automation == 'cross_platform' %>
20
+ def new_driver
21
+ platform = config['platform'].to_s
22
+ @driver = Appium::Driver.new({ caps: caps[platform] })
23
+ end
19
24
  <% else %>
20
- def new_driver
21
- appium_file = File.join(Dir.pwd, 'appium.txt')
22
- caps = Appium.load_appium_txt(file: appium_file)
23
- @driver = Appium::Driver.new(caps)
24
- end
25
+ def new_driver
26
+ @driver = Appium::Driver.new({ caps: caps })
27
+ end
25
28
  <% end %>
@@ -11,4 +11,7 @@ module Raider
11
11
  require_relative 'driver_helper'
12
12
  <% end -%>
13
13
  require_relative 'allure_helper'
14
+ <% if automation == 'cross_platform' -%>
15
+ require_relative 'appium_helper'
16
+ <% end -%>
14
17
  end
@@ -38,6 +38,11 @@ class Utilities
38
38
  overwrite_yaml
39
39
  end
40
40
 
41
+ def platform=(platform)
42
+ @config['platform'] = platform
43
+ overwrite_yaml
44
+ end
45
+
41
46
  def browser_options=(*opts)
42
47
  @config['browser_options'] = opts.flatten
43
48
  overwrite_yaml
data/ruby_raider.gemspec CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  Gem::Specification.new do |s|
4
4
  s.name = 'ruby_raider'
5
- s.version = '0.4.1'
5
+ s.version = '0.4.3'
6
6
  s.summary = 'A gem to make setup and start of UI automation projects easier'
7
7
  s.description = 'This gem has everything you need to start working with test automation'
8
8
  s.authors = ['Agustin Pequeno']
@@ -17,6 +17,7 @@ Gem::Specification.new do |s|
17
17
  s.add_development_dependency 'reek', '~> 6.1.0'
18
18
  s.add_development_dependency 'rspec', '~> 3.11.0'
19
19
  s.add_development_dependency 'rubocop', '~> 1.27'
20
+ s.add_development_dependency 'rubocop-performance', '~> 1.15.0'
20
21
  s.add_development_dependency 'rubocop-rspec', '~> 2.9.0'
21
22
 
22
23
  s.add_runtime_dependency 'thor', '~> 1.2.1'