ruby_raider 0.1.5 → 0.1.9

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 (48) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +2 -1
  3. data/lib/generators/files/automation_file_generator.rb +53 -129
  4. data/lib/generators/files/common_file_generator.rb +24 -148
  5. data/lib/generators/files/cucumber_file_generator.rb +22 -70
  6. data/lib/generators/files/file_generator.rb +7 -5
  7. data/lib/generators/files/helpers_file_generator.rb +51 -225
  8. data/lib/generators/files/rspec_file_generator.rb +20 -49
  9. data/lib/generators/menu_generator.rb +44 -29
  10. data/lib/generators/projects/cucumber_project_generator.rb +25 -15
  11. data/lib/generators/projects/project_generator.rb +21 -5
  12. data/lib/generators/projects/rspec_project_generator.rb +17 -11
  13. data/lib/generators/templates/automation/abstract_component_template.rb +22 -0
  14. data/lib/generators/templates/automation/abstract_page_template.rb +82 -0
  15. data/lib/generators/templates/automation/appium_settings_template.rb +16 -0
  16. data/lib/generators/templates/automation/component_template.rb +16 -0
  17. data/lib/generators/templates/automation/confirmation_page_template.rb +26 -0
  18. data/lib/generators/templates/automation/home_page_template.rb +26 -0
  19. data/lib/generators/templates/automation/login_page_template.rb +113 -0
  20. data/lib/generators/templates/common/config_template.rb +9 -0
  21. data/lib/generators/templates/common/gemfile_template.rb +52 -0
  22. data/lib/generators/templates/common/rake_file_template.rb +16 -0
  23. data/lib/generators/templates/common/read_me_template.rb +104 -0
  24. data/lib/generators/templates/cucumber/env_template.rb +38 -0
  25. data/lib/generators/templates/cucumber/example_feature_template.rb +15 -0
  26. data/lib/generators/templates/cucumber/example_steps_template.rb +21 -0
  27. data/lib/generators/templates/helpers/allure_helper_template.rb +47 -0
  28. data/lib/generators/templates/helpers/browser_helper_template.rb +26 -0
  29. data/lib/generators/templates/helpers/driver_helper_template.rb +54 -0
  30. data/lib/generators/templates/helpers/pom_helper_template.rb +25 -0
  31. data/lib/generators/templates/helpers/raider_helper_template.rb +27 -0
  32. data/lib/generators/templates/helpers/selenium_helper_template.rb +42 -0
  33. data/lib/generators/templates/helpers/spec_helper_template.rb +74 -0
  34. data/lib/generators/templates/helpers/watir_helper_template.rb +24 -0
  35. data/lib/generators/templates/rspec/base_spec_template.rb +13 -0
  36. data/lib/generators/templates/rspec/example_spec_template.rb +56 -0
  37. data/lib/generators/templates/template.rb +14 -0
  38. data/ruby_raider.gemspec +1 -1
  39. data/spec/automation_file_generator_spec.rb +48 -14
  40. data/spec/common_file_generator_spec.rb +12 -3
  41. data/spec/cucumber_file_generator_spec.rb +26 -0
  42. data/spec/cucumber_project_generator_spec.rb +60 -0
  43. data/spec/helpers_file_generator_spec.rb +58 -16
  44. data/spec/rspec_file_generator_spec.rb +11 -2
  45. data/spec/rspec_project_generator_spec.rb +55 -25
  46. data/spec/spec_helper.rb +2 -12
  47. metadata +30 -4
  48. data/spec/menu_generator_spec.rb +0 -8
@@ -0,0 +1,82 @@
1
+ require_relative '../template'
2
+
3
+ class AbstractPageTemplate < Template
4
+
5
+ def raider
6
+ if @framework == 'rspec'
7
+ "require_relative '../../helpers/raider'\n"
8
+ else
9
+ "require_relative '../../features/support/helpers/raider'\n"
10
+ end
11
+ end
12
+
13
+ def helper_selector
14
+ if @automation == 'watir'
15
+ <<~EOF
16
+
17
+ def browser
18
+ Raider::BrowserHelper.browser
19
+ end
20
+
21
+ EOF
22
+ else
23
+ <<-EOF
24
+
25
+ def driver
26
+ Raider::DriverHelper.driver
27
+ end
28
+
29
+
30
+ EOF
31
+ end
32
+ end
33
+
34
+ def visit
35
+ if %w[selenium watir].include?(@automation)
36
+ <<-EOF
37
+
38
+
39
+ def visit(*page)
40
+ #{@automation == 'selenium' ? 'driver.navigate.to full_url(page.first)' : 'browser.goto full_url(page.first)'}
41
+ end
42
+
43
+ EOF
44
+ end
45
+ end
46
+
47
+ def url_methods
48
+ methods = <<-EOF
49
+
50
+
51
+ def full_url(*page)
52
+ "#\{base_url}#\{url(*page)}"
53
+ end
54
+
55
+ def base_url
56
+ 'https://automationteststore.com/'
57
+ end
58
+
59
+ def url(_page)
60
+ raise 'Url must be defined on child pages'
61
+ end
62
+ EOF
63
+
64
+
65
+ methods if %w[selenium watir].include?(@automation)
66
+ end
67
+
68
+ def body
69
+ <<~EOF.gsub(/\n{2}\s{4}/, '')
70
+ require 'rspec'
71
+ #{raider}
72
+ class AbstractPage
73
+
74
+ include RSpec::Matchers
75
+ extend Raider::PomHelper
76
+ #{helper_selector}
77
+ #{visit}
78
+ #{url_methods}
79
+ end
80
+ EOF
81
+ end
82
+ end
@@ -0,0 +1,16 @@
1
+ require_relative '../template'
2
+
3
+ class AppiumSettingsTemplate < Template
4
+ def body
5
+ <<~EOF
6
+ [caps]
7
+ platformName = "iOS"
8
+ platformVersion = "15.4"
9
+ deviceName = "iPhone SE (3rd generation)"
10
+ app = "TheApp.app"
11
+
12
+ [appium_lib]
13
+ server_url = "http://127.0.0.1:4723/wd/hub"
14
+ EOF
15
+ end
16
+ end
@@ -0,0 +1,16 @@
1
+ require_relative '../template'
2
+
3
+ class ComponentTemplate < Template
4
+ def body
5
+ <<~EOF
6
+ require_relative '../abstract/abstract_component'
7
+
8
+ class HeaderComponent < AbstractComponent
9
+
10
+ def customer_name
11
+ @component.text
12
+ end
13
+ end
14
+ EOF
15
+ end
16
+ end
@@ -0,0 +1,26 @@
1
+ require_relative '../template'
2
+
3
+ class ConfirmationPageTemplate < Template
4
+ def body
5
+ <<~EOF
6
+ require_relative '../abstract/abstract_page'
7
+
8
+ class ConfirmationPage < AbstractPage
9
+
10
+ #Values
11
+
12
+ def login_message
13
+ driver.wait { message_element }.text
14
+ end
15
+
16
+ private
17
+
18
+ # Elements
19
+
20
+ def message_element
21
+ driver.find_element(accessibility_id: 'You are logged in as alice')
22
+ end
23
+ end
24
+ EOF
25
+ end
26
+ end
@@ -0,0 +1,26 @@
1
+ require_relative '../template'
2
+
3
+ class HomePageTemplate < Template
4
+ def body
5
+ <<~EOF
6
+ require_relative '../abstract/abstract_page'
7
+
8
+ class HomePage < AbstractPage
9
+
10
+ #Actions
11
+
12
+ def go_to_login
13
+ driver.wait { login_button_navigator }.click
14
+ end
15
+
16
+ private
17
+
18
+ # Elements
19
+
20
+ def login_button_navigator
21
+ driver.find_element(accessibility_id: 'Login Screen')
22
+ end
23
+ end
24
+ EOF
25
+ end
26
+ end
@@ -0,0 +1,113 @@
1
+ require_relative '../template'
2
+
3
+ class LoginPageTemplate < Template
4
+ def element
5
+ case @automation
6
+ when 'watir' then 'browser.element'
7
+ when 'selenium', 'appium_ios' then 'driver.find_element'
8
+ end
9
+ end
10
+
11
+ def helper
12
+ case @automation
13
+ when 'watir' then 'using Raider::WatirHelper'
14
+ when 'selenium' then 'using Raider::SeleniumHelper'
15
+ else nil
16
+ end
17
+ end
18
+
19
+ def require_header
20
+ "require_relative '../components/header_component'" if %w[selenium watir].include?(@automation)
21
+ end
22
+
23
+ def url
24
+ if %w[selenium watir].include?(@automation)
25
+ <<~EOF
26
+ def url(_page)
27
+ 'index.php?rt=account/login'
28
+ end
29
+ EOF
30
+ end
31
+ end
32
+
33
+ def header
34
+ if %w[selenium watir].include?(@automation)
35
+ <<~EOF
36
+ # Components
37
+
38
+ def header
39
+ HeaderComponent.new(#{element}(class: 'menu_text'))
40
+ end
41
+ EOF
42
+ end
43
+ end
44
+
45
+ def username_element
46
+ selector = if %w[selenium watir].include?(@automation)
47
+ "(id: 'loginFrm_loginname')"
48
+ else
49
+ "(xpath: \"//XCUIElementTypeTextField[@name=\\\"username\\\"]\")"
50
+ end
51
+ "#{element}#{selector}"
52
+ end
53
+
54
+ def password_element
55
+ selector = if %w[selenium watir].include?(@automation)
56
+ "(id: 'loginFrm_password')"
57
+ else
58
+ "(xpath: \"//XCUIElementTypeSecureTextField[@name=\\\"password\\\"]\")"
59
+ end
60
+ "#{element}#{selector}"
61
+ end
62
+
63
+ def button
64
+ if %w[selenium watir].include?(@automation)
65
+ "#{element}(xpath: \"//button[@title='Login']\")"
66
+ else
67
+ "driver.find_elements(xpath: \"//XCUIElementTypeOther[@name=\\\"loginBtn\\\"]\").last"
68
+ end
69
+ end
70
+
71
+ def click
72
+ %w[selenium watir].include?(@automation) ? 'click_when_present' : 'click'
73
+ end
74
+
75
+ def body
76
+ <<~EOF.gsub(/\n{2}\s{2}\n/, '')
77
+ require_relative '../abstract/abstract_page'
78
+ #{require_header}
79
+
80
+ class LoginPage < AbstractPage
81
+ #{helper}
82
+
83
+ #{url}
84
+
85
+ # Actions
86
+
87
+ def login(username, password)
88
+ username_field.send_keys username
89
+ password_field.send_keys password
90
+ login_button.#{click}
91
+ end
92
+
93
+ #{header}
94
+
95
+ private
96
+
97
+ # Elements
98
+
99
+ def username_field
100
+ #{username_element}
101
+ end
102
+
103
+ def password_field
104
+ #{password_element}
105
+ end
106
+
107
+ def login_button
108
+ #{button}
109
+ end
110
+ end
111
+ EOF
112
+ end
113
+ end
@@ -0,0 +1,9 @@
1
+ require_relative '../template'
2
+
3
+ class ConfigTemplate < Template
4
+ def body
5
+ <<~EOF
6
+ browser: :chrome
7
+ EOF
8
+ end
9
+ end
@@ -0,0 +1,52 @@
1
+ require_relative '../template'
2
+
3
+ class GemfileTemplate < Template
4
+ def automation_gems
5
+ case @automation
6
+ when 'watir'
7
+ <<~EOF
8
+ gem 'selenium-webdriver'
9
+ gem 'watir'
10
+ EOF
11
+ when 'selenium'
12
+ "gem 'selenium-webdriver'"
13
+ else
14
+ <<~EOF
15
+ gem 'appium_lib'
16
+ gem 'appium_console'
17
+ EOF
18
+ end
19
+ end
20
+
21
+ def webdrivers
22
+ "gem 'webdrivers'" if %w[selenium watir].include?(@automation)
23
+ end
24
+
25
+ def allure_cucumber
26
+ "gem 'allure-cucumber'" if @framework == 'cucumber'
27
+ end
28
+
29
+ def rspec_gem
30
+ "gem 'rspec'" if @framework == 'cucumber'
31
+ end
32
+
33
+ def body
34
+ <<~EOF
35
+ # frozen_string_literal: true
36
+
37
+ source 'https://rubygems.org'
38
+
39
+ gem 'activesupport'
40
+ gem 'allure-rspec'
41
+ gem 'allure-ruby-commons'
42
+ #{allure_cucumber}
43
+ gem 'parallel_split_test'
44
+ gem 'parallel_tests'
45
+ gem 'rake'
46
+ gem '#{@framework}'
47
+ #{rspec_gem}
48
+ #{automation_gems}
49
+ #{webdrivers}
50
+ EOF
51
+ end
52
+ end
@@ -0,0 +1,16 @@
1
+ require_relative '../template'
2
+
3
+ class RakeFileTemplate < Template
4
+ def body
5
+ <<~EOF
6
+ require 'yaml'
7
+
8
+ desc 'Selects browser for automation run'
9
+ task :select_browser, [:browser] do |_t, args|
10
+ config = YAML.load_file('config/config.yml')
11
+ config['browser'] = args.browser
12
+ File.write('config/config.yml', config.to_yaml)
13
+ end
14
+ EOF
15
+ end
16
+ end
@@ -0,0 +1,104 @@
1
+ require_relative '../template'
2
+
3
+ class ReadMeTemplate < Template
4
+ def body
5
+ <<~EOF
6
+ What is Raider?
7
+ ===========
8
+
9
+ Raider is a tool to make the setup and start of automation projects in ruby easier, with one command you are
10
+ ready to go
11
+
12
+ # Pre-requisites:
13
+
14
+ Install RVM:
15
+ https://rvm.io/rvm/install
16
+
17
+ # How to use the framework:
18
+
19
+ If you want to run all the tests from your terminal do:
20
+ *rspec spec/*
21
+
22
+ If you want to run all the tests in parallel do:
23
+ *parallel_rspec spec/*
24
+
25
+ # How are specs organized:
26
+
27
+ We use 'context' as the highest grouping level to indicate in which part of the application we are as an example:
28
+
29
+ *context 'On the login page'/*
30
+
31
+ We use 'describe' from the user perspective to describe an action that the user can or cannot take:
32
+
33
+ *describe 'A user can'/*
34
+
35
+ or
36
+
37
+ *describe 'A user cannot'/*
38
+
39
+ This saves us repetition and forces us into an structure
40
+
41
+ At last we use 'it' for the specific action the user can or cannot perform:
42
+
43
+ it 'login with right credentials'
44
+
45
+ If we group all of this together it will look like
46
+
47
+ ```ruby
48
+ context 'On the login page' do
49
+ describe 'A user can' do
50
+ it 'login with the right credentials' do
51
+ end
52
+ #{' '}
53
+ end
54
+ #{' '}
55
+ describe 'A user cannot' do
56
+ it 'login with the wrong credentials' do
57
+ end
58
+ end
59
+ end
60
+ ```
61
+ #{' '}
62
+ This is readed as 'On the login page a user can login with the right credentials' and 'On the login page a user cannot login with the wrong credentials'
63
+
64
+ # How pages are organized:
65
+
66
+ ```ruby#{' '}
67
+ require_relative '../abstract/base_page'
68
+
69
+ class MainPage < BasePage
70
+
71
+ using Raider::WatirHelper
72
+
73
+ def url(_page)
74
+ '/'
75
+ end
76
+
77
+ # Actions
78
+
79
+ def change_currency(currency)
80
+ currency_dropdown.select currency
81
+ end
82
+
83
+ # Validations
84
+
85
+ def validate_currency(currency)
86
+ expect(currency_dropdown.include?(currency)).to be true
87
+ end
88
+
89
+ private
90
+
91
+ # Elements
92
+
93
+ def currency_dropdown
94
+ browser.select(class: %w[dropdown-menu currency])
95
+ end
96
+ end
97
+ ```
98
+
99
+ Pages are organized in Actions (things a user can perform on the page), Validations (assertions), and Elements.
100
+ Each page has to have a url define, and each page is using the module WatirHelper to add methods on runtime to the Watir elements
101
+
102
+ EOF
103
+ end
104
+ end
@@ -0,0 +1,38 @@
1
+ require_relative '../template'
2
+
3
+ class EnvTemplate < Template
4
+ def body
5
+
6
+ if @automation == 'watir'
7
+ helper = 'helpers/browser_helper'
8
+ browser = 'Raider::BrowserHelper.new_browser'
9
+ get_browser = 'browser = Raider::BrowserHelper.new_browser'
10
+ screenshot = 'browser.screenshot.save("allure-results/screenshots/#{scenario.name}.png")'
11
+ quit = 'browser.quit'
12
+ else
13
+ helper = 'helpers/driver_helper'
14
+ browser = 'Raider::DriverHelper.new_driver'
15
+ get_browser = 'driver = Raider::DriverHelper.driver'
16
+ screenshot = 'driver.save_screenshot("allure-results/screenshots/#{scenario.name}.png")'
17
+ quit = 'driver.quit'
18
+ end
19
+
20
+ <<~EOF
21
+ require 'active_support/all'
22
+ require_relative 'helpers/allure_helper'
23
+ require_relative '#{helper}'
24
+
25
+ Before do
26
+ Raider::AllureHelper.configure
27
+ #{browser}
28
+ end
29
+
30
+ After do |scenario|
31
+ #{get_browser}
32
+ #{screenshot}
33
+ Raider::AllureHelper.add_screenshot(scenario.name)
34
+ #{quit}
35
+ end
36
+ EOF
37
+ end
38
+ end
@@ -0,0 +1,15 @@
1
+ require_relative '../template'
2
+
3
+ class ExampleFeatureTemplate < Template
4
+ def body
5
+ <<~EOF
6
+ Feature: Login Page
7
+
8
+ Scenario: A user can login
9
+ Given I'm a registered user on the login page
10
+ When I login with my credentials
11
+ Then I can see the main page
12
+
13
+ EOF
14
+ end
15
+ end
@@ -0,0 +1,21 @@
1
+ require_relative '../template'
2
+
3
+ class ExampleStepsTemplate < Template
4
+ def body
5
+ <<~EOF
6
+ require_relative '../../page_objects/pages/login_page'
7
+
8
+ Given("I'm a registered user on the login page") do
9
+ LoginPage.visit
10
+ end
11
+
12
+ When('I login with my credentials') do
13
+ LoginPage.login('aguspe', '12341234')
14
+ end
15
+
16
+ When('I can see the main page') do
17
+ expect(LoginPage.header.customer_name).to eq 'Welcome back Agustin'
18
+ end
19
+ EOF
20
+ end
21
+ end
@@ -0,0 +1,47 @@
1
+ require_relative '../template'
2
+
3
+ class AllureHelperTemplate < Template
4
+ def body
5
+ if @framework == 'cucumber'
6
+ gems = "require 'allure-cucumber'"
7
+ allure = 'AllureCucumber'
8
+ else
9
+ gems = "require 'allure-ruby-commons'
10
+ require 'allure-rspec'"
11
+ allure = 'AllureRspec'
12
+ end
13
+ <<~EOF
14
+ #{gems}
15
+
16
+ module Raider
17
+ module AllureHelper
18
+ class << self
19
+
20
+ def configure
21
+ #{allure}.configure do |config|
22
+ config.results_directory = 'allure-results'
23
+ config.clean_results_directory = true
24
+ end
25
+ end
26
+
27
+ def add_screenshot(screenshot_name)
28
+ Allure.add_attachment(
29
+ name: name,
30
+ source: "File.open(allure-results/screenshots/\#{screenshot_name}.png)",
31
+ type: Allure::ContentType::PNG,
32
+ test_case: true
33
+ )
34
+ end
35
+
36
+ #{
37
+ if @framework == 'rspec'
38
+ 'def formatter
39
+ AllureRspecFormatter
40
+ end'
41
+ end }
42
+ end
43
+ end
44
+ end
45
+ EOF
46
+ end
47
+ end
@@ -0,0 +1,26 @@
1
+ require_relative '../template'
2
+
3
+ class BrowserHelperTemplate < Template
4
+ def body
5
+ <<~EOF
6
+ require 'yaml'
7
+ require 'selenium-webdriver'
8
+ require 'watir'
9
+ require 'webdrivers'
10
+
11
+ module Raider
12
+ module BrowserHelper
13
+ class << self
14
+ attr_reader :browser
15
+
16
+ def new_browser
17
+ config = YAML.load_file('config/config.yml')
18
+ @browser = Watir::Browser.new config['browser']
19
+ end
20
+ end
21
+ end
22
+ end
23
+
24
+ EOF
25
+ end
26
+ end
@@ -0,0 +1,54 @@
1
+ require_relative '../template'
2
+
3
+ class DriverHelperTemplate < Template
4
+ def new_driver
5
+ if @automation == 'selenium'
6
+ <<-EOF.chomp
7
+ def new_driver
8
+ @driver = Selenium::WebDriver.for :chrome
9
+ end
10
+ EOF
11
+ else
12
+ <<-EOF.chomp
13
+ def new_driver
14
+ appium_file = File.join(Dir.pwd, 'appium.txt')
15
+ caps = Appium.load_appium_txt(file: appium_file)
16
+ @driver = Appium::Driver.new(caps)
17
+ end
18
+ EOF
19
+ end
20
+ end
21
+
22
+ def requirements
23
+ case @automation
24
+ when 'selenium'
25
+ <<~EOF
26
+ require 'selenium-webdriver'
27
+ require 'webdrivers'
28
+ EOF
29
+ when 'watir'
30
+ <<~EOF
31
+ require 'watir'
32
+ require 'webdrivers'
33
+ EOF
34
+ else
35
+ "require 'appium_lib'"
36
+ end
37
+ end
38
+
39
+ def body
40
+ <<~EOF
41
+ #{requirements}
42
+
43
+ module Raider
44
+ module DriverHelper
45
+ class << self
46
+ attr_reader :driver
47
+
48
+ #{new_driver}
49
+ end
50
+ end
51
+ end
52
+ EOF
53
+ end
54
+ end
@@ -0,0 +1,25 @@
1
+ require_relative '../template'
2
+
3
+ class PomHelperTemplate < Template
4
+ def body
5
+ <<~EOF
6
+ module Raider
7
+ module PomHelper
8
+ def instance
9
+ @instance ||= new
10
+ end
11
+
12
+ def method_missing(message, *args, &block)
13
+ return super unless instance.respond_to?(message)
14
+
15
+ instance.public_send(message, *args, &block)
16
+ end
17
+
18
+ def respond_to_missing?(method, *_args, &block)
19
+ instance.respond_to?(method) || super
20
+ end
21
+ end
22
+ end
23
+ EOF
24
+ end
25
+ end