ruby_raider 0.4.0 → 0.4.2
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 +4 -4
- data/.rubocop.yml +3 -6
- data/README.md +5 -1
- data/Rakefile +2 -2
- data/lib/commands/scaffolding_commands.rb +2 -2
- data/lib/generators/automation_generator.rb +14 -10
- data/lib/generators/cucumber_generator.rb +10 -2
- data/lib/generators/menu_generator.rb +10 -6
- data/lib/generators/rspec_generator.rb +9 -1
- data/lib/generators/templates/automation/abstract_component.tt +2 -0
- data/lib/generators/templates/automation/abstract_page.tt +0 -1
- data/lib/generators/templates/automation/appium_settings.tt +5 -8
- data/lib/generators/templates/automation/component.tt +1 -1
- data/lib/generators/templates/automation/home_page.tt +9 -5
- data/lib/generators/templates/automation/login_page.tt +0 -2
- data/lib/generators/templates/automation/partials/android_settings.tt +8 -0
- data/lib/generators/templates/automation/partials/element.tt +3 -3
- data/lib/generators/templates/automation/partials/initialize_selector.tt +4 -0
- data/lib/generators/templates/automation/partials/ios_settings.tt +8 -0
- data/lib/generators/templates/automation/partials/selenium_login.tt +3 -3
- data/lib/generators/templates/automation/partials/watir_login.tt +3 -3
- data/lib/generators/templates/automation/pdp_page.tt +22 -0
- data/lib/generators/templates/cucumber/feature.tt +9 -0
- data/lib/generators/templates/cucumber/partials/appium_env.tt +7 -5
- data/lib/generators/templates/cucumber/partials/driver_world.tt +1 -0
- data/lib/generators/templates/cucumber/partials/mobile_steps.tt +8 -11
- data/lib/generators/templates/cucumber/partials/watir_world.tt +1 -0
- data/lib/generators/templates/cucumber/partials/web_steps.tt +1 -1
- data/lib/generators/templates/cucumber/world.tt +5 -0
- data/lib/generators/templates/helpers/driver_helper.tt +0 -1
- data/lib/generators/templates/helpers/partials/select_driver.tt +5 -4
- data/lib/generators/templates/rspec/spec.tt +8 -13
- data/ruby_raider.gemspec +2 -1
- data/spec/automation_generator_spec.rb +36 -154
- data/spec/common_generator_spec.rb +27 -112
- data/spec/cucumber_generator_spec.rb +15 -54
- data/spec/helpers_generator_spec.rb +57 -94
- data/spec/rspec_generator_spec.rb +13 -44
- data/spec/scaffolding_commands_spec.rb +162 -0
- data/spec/spec_helper.rb +20 -0
- metadata +23 -5
- data/lib/generators/templates/automation/confirmation_page.tt +0 -19
- data/lib/generators/templates/automation/partials/appium_login.tt +0 -28
- data/spec/scaffolding_spec.rb +0 -234
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 6a92cf556575579c0fd4b96bde582b6f19d0715224467dae8276a7b5a367d611
|
4
|
+
data.tar.gz: c4327f646e1f7dc87657da33e7cf2a075103fe605a953cb9e0a2c4f0a8bef24f
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: cd2a91f76d5f338b7cd2e79ae0c3af2012a4ff4a46802c3f90b8d1e79724c30fb9127790a89ceac5592ac74e039863993f62c7205e732fa714b3a3ae4309c4e3
|
7
|
+
data.tar.gz: d61169f5255b2f0e12a9cd62cb312c81dabc696ad9285d0863c62d46cdaaa4e9cea152e68985ff063450fc0c9c5d55cf752f5d06ae4cf245647c0ce924906ec9
|
data/.rubocop.yml
CHANGED
@@ -1,8 +1,5 @@
|
|
1
|
-
require:
|
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:
|
86
|
+
Enabled: true
|
90
87
|
|
91
88
|
Style/SingleLineBlockParams:
|
92
89
|
Description: 'Enforces the names of some block params.'
|
data/README.md
CHANGED
@@ -43,7 +43,11 @@ Ruby Raider is a generator and scaffolding gem to make UI test automation easier
|
|
43
43
|
|
44
44
|
* Generating a framework with Cucumber and Appium for IOS
|
45
45
|
|
46
|
-
|
46
|
+
* Generating a framework with Rspec and Appium for Android
|
47
|
+
|
48
|
+
* Generating a framework with Cucumber and Appium for Android
|
49
|
+
|
50
|
+
***In order to run the Appium tests, download the example [app](https://github.com/saucelabs/my-demo-app-rn).***
|
47
51
|
|
48
52
|
This works in all the platforms (Tested on Mac OS, Linux and Windows).
|
49
53
|
|
data/Rakefile
CHANGED
@@ -4,8 +4,8 @@ require_relative 'lib/ruby_raider'
|
|
4
4
|
require_relative 'lib/commands/scaffolding_commands'
|
5
5
|
|
6
6
|
desc 'Creates a new test project'
|
7
|
-
task :new do
|
8
|
-
|
7
|
+
task :new, [:name] do |_t, args|
|
8
|
+
system "bin/raider -n #{args.name}"
|
9
9
|
end
|
10
10
|
|
11
11
|
desc 'Creates a page'
|
@@ -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
|
-
|
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
|
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
|
@@ -4,6 +4,8 @@ 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?
|
8
|
+
|
7
9
|
template('automation/login_page.tt', "#{name}/page_objects/pages/login_page.rb")
|
8
10
|
end
|
9
11
|
|
@@ -12,30 +14,32 @@ class AutomationGenerator < Generator
|
|
12
14
|
end
|
13
15
|
|
14
16
|
def generate_home_page
|
15
|
-
return
|
17
|
+
return if (@_initializer.first & %w[android ios]).empty?
|
16
18
|
|
17
19
|
template('automation/home_page.tt', "#{name}/page_objects/pages/home_page.rb")
|
18
20
|
end
|
19
21
|
|
22
|
+
def generate_pdp_page
|
23
|
+
return if (@_initializer.first & %w[android ios]).empty?
|
24
|
+
|
25
|
+
template('automation/pdp_page.tt', "#{name}/page_objects/pages/pdp_page.rb")
|
26
|
+
end
|
27
|
+
|
20
28
|
def generate_header_component
|
21
|
-
return
|
29
|
+
return unless (@_initializer.first & %w[android ios]).empty?
|
22
30
|
|
23
31
|
template('automation/component.tt', "#{name}/page_objects/components/header_component.rb")
|
24
32
|
end
|
25
33
|
|
26
34
|
def generate_abstract_component
|
27
|
-
return
|
35
|
+
return unless (@_initializer.first & %w[android ios]).empty?
|
28
36
|
|
29
37
|
template('automation/abstract_component.tt', "#{name}/page_objects/abstract/abstract_component.rb")
|
30
38
|
end
|
31
39
|
|
32
|
-
def generate_confirmation_page
|
33
|
-
return unless @_initializer.first.include?('appium_ios')
|
34
|
-
|
35
|
-
template('automation/confirmation_page.tt', "#{name}/page_objects/pages/confirmation_page.rb")
|
36
|
-
end
|
37
|
-
|
38
40
|
def generate_appium_settings
|
39
|
-
|
41
|
+
return if (@_initializer.first & %w[android ios]).empty?
|
42
|
+
|
43
|
+
template('automation/appium_settings.tt', "#{name}/appium.txt")
|
40
44
|
end
|
41
45
|
end
|
@@ -4,14 +4,22 @@ require_relative 'generator'
|
|
4
4
|
|
5
5
|
class CucumberGenerator < Generator
|
6
6
|
def generate_feature
|
7
|
-
template('cucumber/feature.tt', "#{name}/features
|
7
|
+
template('cucumber/feature.tt', "#{name}/features/#{template_name}.feature")
|
8
8
|
end
|
9
9
|
|
10
10
|
def generate_steps
|
11
|
-
template('cucumber/steps.tt', "#{name}/features/step_definitions
|
11
|
+
template('cucumber/steps.tt', "#{name}/features/step_definitions/#{template_name}_steps.rb")
|
12
12
|
end
|
13
13
|
|
14
14
|
def generate_env_file
|
15
15
|
template('cucumber/env.tt', "#{name}/features/support/env.rb")
|
16
16
|
end
|
17
|
+
|
18
|
+
def generate_world
|
19
|
+
template('cucumber/world.tt', "#{name}/world.rb")
|
20
|
+
end
|
21
|
+
|
22
|
+
def template_name
|
23
|
+
@template_name ||= (@_initializer.first & %w[android ios]).empty? ? 'login' : 'home'
|
24
|
+
end
|
17
25
|
end
|
@@ -31,21 +31,25 @@ class MenuGenerator
|
|
31
31
|
select_test_framework(automation)
|
32
32
|
end
|
33
33
|
|
34
|
-
def
|
35
|
-
|
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
|
|
40
39
|
def choose_mobile_platform
|
41
40
|
prompt.select('Please select your mobile platform') do |menu|
|
42
|
-
menu.choice :iOS, -> { choose_test_framework '
|
43
|
-
menu.choice :Android, -> {
|
41
|
+
menu.choice :iOS, -> { choose_test_framework 'ios' }
|
42
|
+
menu.choice :Android, -> { choose_test_framework 'android' }
|
44
43
|
menu.choice :Cross_Platform, -> { error_handling('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
|
-
|
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
|
|
@@ -3,10 +3,18 @@
|
|
3
3
|
require_relative 'generator'
|
4
4
|
|
5
5
|
class RspecGenerator < Generator
|
6
|
-
def
|
6
|
+
def generate_login_spec
|
7
|
+
return unless (@_initializer.first & %w[android ios]).empty?
|
8
|
+
|
7
9
|
template('rspec/spec.tt', "#{name}/spec/login_page_spec.rb")
|
8
10
|
end
|
9
11
|
|
12
|
+
def generate_pdp_spec
|
13
|
+
return if (@_initializer.first & %w[android ios]).empty?
|
14
|
+
|
15
|
+
template('rspec/spec.tt', "#{name}/spec/pdp_page_spec.rb")
|
16
|
+
end
|
17
|
+
|
10
18
|
def generate_base_spec
|
11
19
|
template('rspec/base_spec.tt', "#{name}/spec/base_spec.rb")
|
12
20
|
end
|
@@ -1,8 +1,5 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
[appium_lib]
|
8
|
-
server_url = "http://127.0.0.1:4723/wd/hub"
|
1
|
+
<% if automation == 'ios' %>
|
2
|
+
<%= ERB.new(File.read(File.expand_path('./partials/ios_settings.tt', __dir__))).result(binding) -%>
|
3
|
+
<% else %>
|
4
|
+
<%= ERB.new(File.read(File.expand_path('./partials/android_settings.tt', __dir__))).result(binding) -%>
|
5
|
+
<% end %>
|
@@ -4,17 +4,21 @@ require_relative '../abstract/abstract_page'
|
|
4
4
|
|
5
5
|
class HomePage < AbstractPage
|
6
6
|
|
7
|
-
#Actions
|
7
|
+
# Actions
|
8
8
|
|
9
|
-
def
|
10
|
-
|
9
|
+
def go_to_backpack_pdp
|
10
|
+
driver.wait { backpack_image }.click
|
11
11
|
end
|
12
12
|
|
13
13
|
private
|
14
14
|
|
15
15
|
# Elements
|
16
16
|
|
17
|
-
def
|
18
|
-
|
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 %>
|
19
23
|
end
|
20
24
|
end
|
@@ -3,6 +3,4 @@
|
|
3
3
|
<%= ERB.new(File.read(File.expand_path('./partials/selenium_login.tt', __dir__))).result(binding) %>
|
4
4
|
<% when 'watir' -%>
|
5
5
|
<%= ERB.new(File.read(File.expand_path('./partials/watir_login.tt', __dir__))).result(binding) %>
|
6
|
-
<% else -%>
|
7
|
-
<%= ERB.new(File.read(File.expand_path('./partials/appium_login.tt', __dir__))).result(binding) %>
|
8
6
|
<% end -%>
|
@@ -27,14 +27,14 @@ class LoginPage < AbstractPage
|
|
27
27
|
# Elements
|
28
28
|
|
29
29
|
def username_field
|
30
|
-
|
30
|
+
driver.find_element(id: 'loginFrm_loginname')
|
31
31
|
end
|
32
32
|
|
33
33
|
def password_field
|
34
|
-
|
34
|
+
driver.find_element(id: 'loginFrm_password')
|
35
35
|
end
|
36
36
|
|
37
37
|
def login_button
|
38
|
-
|
38
|
+
driver.find_element(xpath: "//button[@title='Login']")
|
39
39
|
end
|
40
40
|
end
|
@@ -26,14 +26,14 @@ class LoginPage < AbstractPage
|
|
26
26
|
# Elements
|
27
27
|
|
28
28
|
def username_field
|
29
|
-
|
29
|
+
browser.text_field(id: 'loginFrm_loginname')
|
30
30
|
end
|
31
31
|
|
32
32
|
def password_field
|
33
|
-
|
33
|
+
browser.text_field(id: 'loginFrm_password')
|
34
34
|
end
|
35
35
|
|
36
36
|
def login_button
|
37
|
-
|
37
|
+
browser.button(xpath: "//button[@title='Login']")
|
38
38
|
end
|
39
39
|
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
require_relative '../abstract/abstract_page'
|
2
|
+
|
3
|
+
class PdpPage < AbstractPage
|
4
|
+
|
5
|
+
# Actions
|
6
|
+
|
7
|
+
def add_to_cart_text
|
8
|
+
driver.wait { add_to_cart_button }.text
|
9
|
+
end
|
10
|
+
|
11
|
+
private
|
12
|
+
|
13
|
+
# Elements
|
14
|
+
|
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 %>
|
21
|
+
end
|
22
|
+
end
|
@@ -1,6 +1,15 @@
|
|
1
|
+
<% if %w[selenium watir].include? automation -%>
|
1
2
|
Feature: Login Page
|
2
3
|
|
3
4
|
Scenario: A user can login
|
4
5
|
Given I'm a registered user on the login page
|
5
6
|
When I login with my credentials
|
6
7
|
Then I can see the main page
|
8
|
+
<% else -%>
|
9
|
+
Feature: Home Page
|
10
|
+
|
11
|
+
Scenario: A user can go to the product details page
|
12
|
+
Given I'm an anonymous user on the home page
|
13
|
+
When I select one of the products
|
14
|
+
Then I'm redirected to the product details page
|
15
|
+
<% end %>
|
@@ -1,13 +1,15 @@
|
|
1
1
|
require_relative '../../helpers/driver_helper'
|
2
2
|
|
3
|
+
include Raider::DriverHelper
|
4
|
+
|
3
5
|
Before do
|
4
6
|
Raider::AllureHelper.configure
|
5
|
-
|
6
|
-
|
7
|
+
new_driver
|
8
|
+
driver.start_driver
|
7
9
|
end
|
8
10
|
|
9
11
|
After do |scenario|
|
10
|
-
|
12
|
+
driver.screenshot("allure-results/screenshots/#{scenario.name}.png")
|
11
13
|
Raider::AllureHelper.add_screenshot(scenario.name)
|
12
|
-
|
13
|
-
end
|
14
|
+
driver.quit_driver
|
15
|
+
end
|
@@ -0,0 +1 @@
|
|
1
|
+
World(DriverHelper)
|
@@ -1,20 +1,17 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require_relative '../../page_objects/pages/confirmation_page'
|
4
3
|
require_relative '../../page_objects/pages/home_page'
|
5
|
-
require_relative '../../page_objects/pages/
|
4
|
+
require_relative '../../page_objects/pages/pdp_page'
|
6
5
|
|
7
|
-
Given("I'm
|
8
|
-
home_page = HomePage.new(
|
9
|
-
home_page.go_to_login
|
6
|
+
Given("I'm an anonymous user on the home page") do
|
7
|
+
@home_page = HomePage.new(driver)
|
10
8
|
end
|
11
9
|
|
12
|
-
When('I
|
13
|
-
|
14
|
-
login_page.login('alice', 'mypassword')
|
10
|
+
When('I select one of the products') do
|
11
|
+
@home_page.go_to_backpack_pdp
|
15
12
|
end
|
16
13
|
|
17
|
-
When('
|
18
|
-
|
19
|
-
expect(
|
14
|
+
When("I'm redirected to the product details page") do
|
15
|
+
pdp_page = PdpPage.new(driver)
|
16
|
+
expect(pdp_page.add_to_cart_text).to eq 'Add To Cart'
|
20
17
|
end
|
@@ -0,0 +1 @@
|
|
1
|
+
World(BrowserHelper)
|
@@ -3,7 +3,7 @@
|
|
3
3
|
require_relative '../../page_objects/pages/login_page'
|
4
4
|
|
5
5
|
Given("I'm a registered user on the login page") do
|
6
|
-
@login_page = LoginPage.new(<% if automation == 'watir'
|
6
|
+
@login_page = LoginPage.new(<% if automation == 'watir'%>browser<% else %>driver<% end %>)
|
7
7
|
@login_page.visit
|
8
8
|
end
|
9
9
|
|
@@ -0,0 +1,5 @@
|
|
1
|
+
<% if %w[watir].include? automation -%>
|
2
|
+
<%= ERB.new(File.read(File.expand_path('./partials/watir_world.tt', __dir__))).result(binding).strip! -%>
|
3
|
+
<% else -%>
|
4
|
+
<%= ERB.new(File.read(File.expand_path('./partials/driver_world.tt', __dir__))).result(binding).strip! -%>
|
5
|
+
<% end -%>
|
@@ -29,24 +29,19 @@ describe 'Login' do
|
|
29
29
|
end
|
30
30
|
end
|
31
31
|
<% else -%>
|
32
|
-
require_relative '../page_objects/pages/confirmation_page'
|
33
32
|
require_relative '../page_objects/pages/home_page'
|
34
33
|
require_relative 'base_spec'
|
35
|
-
require_relative '../page_objects/pages/
|
34
|
+
require_relative '../page_objects/pages/pdp_page'
|
36
35
|
|
37
|
-
class
|
38
|
-
describe '
|
36
|
+
class PdpSpec < BaseSpec
|
37
|
+
describe 'PDP page' do
|
39
38
|
|
40
|
-
let(:
|
41
|
-
let(:
|
42
|
-
let(:login_page) { LoginPage.new(@driver) }
|
43
|
-
let(:home_page) { HomePage.new(@driver) }
|
44
|
-
let(:confirmation_page) { ConfirmationPage.new(@driver) }
|
39
|
+
let(:home_page) { HomePage.new(driver) }
|
40
|
+
let(:pdp_page) { PdpPage.new(driver) }
|
45
41
|
|
46
|
-
it '
|
47
|
-
home_page.
|
48
|
-
|
49
|
-
expect(confirmation_page.login_message).to eq 'You are logged in as alice'
|
42
|
+
it 'shows add to cart button' do
|
43
|
+
home_page.go_to_backpack_pdp
|
44
|
+
expect(pdp_page.add_to_cart_text).to eq 'Add To Cart'
|
50
45
|
end
|
51
46
|
end
|
52
47
|
end
|
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.
|
5
|
+
s.version = '0.4.2'
|
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'
|