ruby_raider 0.4.1 → 0.4.3

Sign up to get free protection for your applications and to get access to all the features.
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'