ruby_raider 0.1.5 → 0.1.9

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