diff --git a/features-skeleton/Gemfile b/features-skeleton/Gemfile new file mode 100644 index 0000000..8cbebd1 --- /dev/null +++ b/features-skeleton/Gemfile @@ -0,0 +1,6 @@ +# Gemfile for SICK Analytics Platform +source "https://rubygems.org" + +gem 'selenium-cucumber', '~> 2.1', '>= 2.1.4' + +ruby '2.0.0' \ No newline at end of file diff --git a/features-skeleton/Gemfile.lock b/features-skeleton/Gemfile.lock new file mode 100644 index 0000000..b89988d --- /dev/null +++ b/features-skeleton/Gemfile.lock @@ -0,0 +1,60 @@ +GEM + remote: https://rubygems.org/ + specs: + appium_lib (8.0.2) + awesome_print (~> 1.6) + json (~> 1.8) + nokogiri (~> 1.6.6) + selenium-webdriver (~> 2.49) + tomlrb (~> 1.1) + awesome_print (1.7.0) + builder (3.2.2) + childprocess (0.5.9) + ffi (~> 1.0, >= 1.0.11) + chunky_png (1.3.5) + cucumber (2.3.3) + builder (>= 2.1.2) + cucumber-core (~> 1.4.0) + cucumber-wire (~> 0.0.1) + diff-lcs (>= 1.1.3) + gherkin (~> 3.2.0) + multi_json (>= 1.7.5, < 2.0) + multi_test (>= 0.1.2) + cucumber-core (1.4.0) + gherkin (~> 3.2.0) + cucumber-wire (0.0.1) + diff-lcs (1.2.5) + ffi (1.9.10-x64-mingw32) + gherkin (3.2.0) + json (1.8.3) + mini_portile2 (2.1.0) + multi_json (1.12.1) + multi_test (0.1.2) + nokogiri (1.6.8-x64-mingw32) + mini_portile2 (~> 2.1.0) + pkg-config (~> 1.1.7) + pkg-config (1.1.7) + rubyzip (1.2.0) + selenium-cucumber (2.1.4) + appium_lib (>= 4.0.0) + chunky_png (>= 1.3.0) + cucumber (>= 1.3.18) + selenium-webdriver (>= 2.41.0) + selenium-webdriver (2.53.0) + childprocess (~> 0.5) + rubyzip (~> 1.0) + websocket (~> 1.0) + tomlrb (1.2.1) + websocket (1.2.3) + +PLATFORMS + x64-mingw32 + +DEPENDENCIES + selenium-cucumber (~> 2.1, >= 2.1.4) + +RUBY VERSION + ruby 2.0.0p648 + +BUNDLED WITH + 1.12.5 diff --git a/features-skeleton/README.md b/features-skeleton/README.md new file mode 100644 index 0000000..239ffc1 --- /dev/null +++ b/features-skeleton/README.md @@ -0,0 +1,95 @@ +ABC-Automation +====================== + +++INITIAL SETUP++ + +Requirements: + +* Ruby 2.0.0 +* Devkit for Ruby 2.0.0 +* Bundler gem + +Other requirements: + +* Notepad++ (Text Editor) – Alternative to RubyMine, which is paid +* Ansicon – to get colored output on Windows +* Chrome driver – Chrome driver for selenium. +* Internet explorer driver – Internet explorer driver for selenium. + +Step by Step guide for installation: +1. Download and install ruby using “RubyInstaller.exe” downloaded from the link mentioned above. +2. Check ruby installation by running “ruby -v” in command prompt. +3. Download development kit from the link mentioned above. +4. Extract the compressed file downloaded in step 3 and move the folder containing the files to any location, say: C:/DevKit +5. From command prompt navigate to the folder discussed in step 4, and run command “ruby dk.rb init”. +6. And then run command “ruby dk.rb install” to bind it to ruby installations in your path. In case the initialization of dev kit fails to detect the path of Ruby installation, add it manually to the ‘config.yml’ file under DevKit folder like: “- C:/Ruby200-x64”. +7. Check if gem library is install by running “gem -v”. +8. Now, install ‘Bundler’ gem by running the following command “gem install bundler” and then run command "bundle install" from root folder of the project to install all dependencies like selenium-cucumber, cucumber, gherkin, selenium-webdriver etc. +9. Run the command “gem list” to verify that all the 12 gems got installed including cucumber, gherkin & selenium-webdriver. +10. To use chrome and Internet explorer browsers, add their driver’s path in the system variable. E.g. create a directory “webdrivers” in let’s say “C:\” keep driver’s executable file downloaded from the links http://selenium-release.storage.googleapis.com/index.html?path=2.51/ & http://chromedriver.storage.googleapis.com/index.html?path=2.21/ respectively in it and set “webdrivers” directory path in system variable. +11. To set system variable, right-click on ‘Computer’ from windows menu, click on properties. Click on ‘Advance system settings’ link in left pane to open system properties window and further navigate to the ‘Advanced’ tab it. Click on ‘Environment Variables’ button to open its window. Under ‘System Variables’ look for “Path” variable and double-click to open it. Just paste the path of your webdriver directory in the end after putting a semi-colon like – ; C:\webdrivers. +12. Download Ansicon from the link - https://github.com/adoxa/ansicon/downloads. +13. Extract the compressed file downloaded in step 12 and move the files (files under x86 for 32-bit machine and x64 for 64-bit machine) to any location, say: “C:/Ansicon” and set directory path in system variable. Alternatively, open the commend window and navigate to directory path and permanently install it by running the command “ansicon -i”. This will give you a colored output in command prompt when any cucumber feature is executed. +14. Download and install Notepad++ from the link - https://notepad-plus-plus.org/download. It is recommended with a Syntax Highlighter for Notepad++ which can be downloaded from here - https://github.com/famished-tiger/gherkin-highlighting +15. Extract the syntax highlighter and the copy the folder named "gherkin-highlighting-master" under 'C:\Program Files (x86)\Notepad++'. +16. Launch Notepad++ now and select 'Language > Define your language...' and Import the "feature_udl" file from folder 'C:\Program Files (x86)\Notepad++\gherkin-highlighting-master' +17. Click on Language again and select 'Gherkin'. Restart Notepad++ and you are all set to roll. + +The project root folder contains some batch files to run the cucumber feature tests locally or on a remote host in parallel (with help of jobs scheduled in task scheduler on remote machine). Apart from that there are two major folders: + +1. reports - all result reports in html format gets saved to this folder in a sub-folder structure organized by different browsers. +2. features - this is the main folder where all the cucumber features and ruby files live. Here follows an explanation of feature skeleton: +Explaining feature skeleton: + + ./features + | + |__step_definitions (this folder contains all the ruby files where the custom steps written in cucumber feature are automated. Recommended to create separate file for each corresponding feature file for simplicity & maintenance but all steps can be automated in a single file as well) + | |_custom_steps_abc.rb + | ........ + | ........ + | ........ + | ........ + | |_custom_steps_xyz.rb + | + |__support (this folder contains the environment file in which local, mobile or browserstack execution parameters are defined and selenium webdriver is instantiated, hooks for defining before & after action (if any) and a custom error handling file for handling browserstack input parameter errors) + | |_env.rb + | |_hooks.rb + | |_browserstack_parameters_error_handling_methods.rb + | + |__properties (this folder contains all the properties file in which the web elements type and value is defined to be used in custom steps for easier maintenance) + | |_abc_properties.rb + | ........ + | ........ + | |_xyz_properties.rb + | + |__expected_images (folder for placing expected images for a image comparison test, if any) + | + |__actual_images (folder where actual images get stored for image comparison test, if any) + | + |__image_difference (folder where result images depicting difference in images get stored for image comparison test, if any) + | + |__screenshots (folder where screenshots taken during test execution get stored, if any) + | + |__abc.feature (feature files are stored under features folder directly. It is recommended to write one feature file for a particular feature/epic) + ......... + ......... + ......... + ......... + |__xyz.feature + +Running Cucumber features: + +For local execution, run the batch scripts in the root folder for each Cucumber feature. Multiple batch scripts can be executed to run parallel tests in different browsers. Remote execution will call a task in scheduler to run the feature test in all the listed browsers in parallel. User can also run manually by writing commands like: +cucumber feature/share.feature BROWSER=chrome --tags ~@fail + +For execution on mobile devices make sure Appium is running and then define PLATFORM=android BROWSER=chrome (or native) in case of android and PLATFORM=iOS Browser=native while running a particular feature instead of defining desktop browsers. Additional --tags can be defined if only certain tests cases meant for mobile should be executed + +For execution on browserstack.com define at least while running test through command or batch file: REMOTE_EXECUTION=yes (by default it is no) + +By default test will run on Firefox 44.0 on Windows 7 with 1024x768 resolution. It can be changed by defining following manually, for example: + +REMOTE_BROWSER=Chrome +BROWSER_VERSION=48.0 +OS_TYPE='OS X' +OS_VERSION='El Capitan' +RESOLUTION=1280x800 \ No newline at end of file diff --git a/features-skeleton/abc_exec-ch.bat b/features-skeleton/abc_exec-ch.bat new file mode 100644 index 0000000..f4600b3 --- /dev/null +++ b/features-skeleton/abc_exec-ch.bat @@ -0,0 +1 @@ +cucumber features/conveyor_belt.feature --tags ~@fail --tags ~@Chromefail BROWSER=chrome -f html -o reports/Chrome/results_conveyor_belt_ch-%date:~10,4%%date:~7,2%%date:~4,2%_%time:~1,1%%time:~3,2%.html \ No newline at end of file diff --git a/features-skeleton/abc_exec-ff.bat b/features-skeleton/abc_exec-ff.bat new file mode 100644 index 0000000..25d5191 --- /dev/null +++ b/features-skeleton/abc_exec-ff.bat @@ -0,0 +1 @@ +cucumber features/conveyor_belt.feature --tags ~@fail --tags ~@FFfail -f html -o reports/Firefox/results_conveyor_belt_ff-%date:~10,4%%date:~7,2%%date:~4,2%_%time:~1,1%%time:~3,2%.html \ No newline at end of file diff --git a/features-skeleton/abc_exec-ie.bat b/features-skeleton/abc_exec-ie.bat new file mode 100644 index 0000000..7c0d280 --- /dev/null +++ b/features-skeleton/abc_exec-ie.bat @@ -0,0 +1 @@ +cucumber features/conveyor_belt.feature --tags ~@fail --tags ~@IE11fail BROWSER=ie -f html -o reports/IE11/results_conveyor_belt_ie-%date:~10,4%%date:~7,2%%date:~4,2%_%time:~1,1%%time:~3,2%.html \ No newline at end of file diff --git a/features-skeleton/abc_task_remotely.bat b/features-skeleton/abc_task_remotely.bat new file mode 100644 index 0000000..1f94b7c --- /dev/null +++ b/features-skeleton/abc_task_remotely.bat @@ -0,0 +1 @@ +schtasks /run /s /tn "" \ No newline at end of file diff --git a/features-skeleton/features/abc.feature b/features-skeleton/features/abc.feature new file mode 100644 index 0000000..910e67d --- /dev/null +++ b/features-skeleton/features/abc.feature @@ -0,0 +1,21 @@ +Feature: ABC + +Following user stories of Bookmarking epic have been automated in this feature file: + + * User Story - ABC-12: As a user, I want to do blah blah blah so that I can get yada yada yada. + Test Cases: ABC-111, ABC-222 + + * User Story - ABC-34: As a persona, I want to do blah blah blah so that I can get yada yada yada. + Test Cases: ABC-333, ABC-444 + +======================================================================================================================================================================================================================================================= + + Scenario: ABC should be present + Given I navigate to "http://localhost:8080" + When I launch "Letters" page + Then I should see "ABC" + + Scenario: Print test configuration & close the browser + + Then I print configuration + Then I close browser \ No newline at end of file diff --git a/features-skeleton/features/properties/abc_properties.rb b/features-skeleton/features/properties/abc_properties.rb new file mode 100644 index 0000000..1e38293 --- /dev/null +++ b/features-skeleton/features/properties/abc_properties.rb @@ -0,0 +1,39 @@ +require 'rubygems' +require 'bundler/setup' +require 'selenium-cucumber' + +# Do Not Remove This File +# Add your custom steps here +# $driver is instance of webdriver use this instance to write your custom code + + +# **-> WEB ELEMENT CLASS DEFINITION STARTS <-** +# Parent class for initializing Web Element parameters. +# A new Object of this class should be created for defining each web element. + +class WebElement + attr_reader :type, :value + def initialize(elem_type, elem_value) + validate_locator elem_type + @type=elem_type + @value=elem_value + end +end + +# Method to validate locator type of web element object +def valid_locator_type? type + %w(id class css name xpath).include? type +end + +def validate_locator type + raise "Invalid locator type - #{type}" unless valid_locator_type? type +end + +# **-> WEB ELEMENT CLASS DEFINITION ENDS <-** + + +# **-> Locators for Global Web Elements of ABC <-** + +# EXAMPLE below +# Welcome message in the header +$welcome = WebElement.new("css", "div.welcome-txt.pull-left") \ No newline at end of file diff --git a/features-skeleton/features/step_definitions/abc_custom_steps.rb b/features-skeleton/features/step_definitions/abc_custom_steps.rb new file mode 100644 index 0000000..b11895d --- /dev/null +++ b/features-skeleton/features/step_definitions/abc_custom_steps.rb @@ -0,0 +1,15 @@ +require 'rubygems' +require 'bundler/setup' +require 'selenium-cucumber' + +# Do Not Remove This File +# Add your custom steps here +# $driver is instance of webdriver use this instance to write your custom code + +When(/^I launch "([^"]*)" page$/) do |arg1| + pending # Write code here that turns the phrase above into concrete actions +end + +Then(/^I should see "([^"]*)"$/) do |arg1| + pending # Write code here that turns the phrase above into concrete actions +end \ No newline at end of file diff --git a/features-skeleton/features/support/browserstack_parameters_error_handling_methods.rb b/features-skeleton/features/support/browserstack_parameters_error_handling_methods.rb new file mode 100644 index 0000000..3af3af1 --- /dev/null +++ b/features-skeleton/features/support/browserstack_parameters_error_handling_methods.rb @@ -0,0 +1,41 @@ +# Error handling methods for remote execution on browserstack.com + +# Method to check browser type on provided OS version +def validate_browserstack_parameters(bs_os, bs_os_version, bs_browser_type, bs_browser_version) + if bs_os == 'Windows' && bs_os_version == '7' + if !%w(Firefox IE Chrome Opera).include? bs_browser_type + print_invalid_browser_for_os + end + elsif bs_os == 'Windows' && bs_os_version == '8' + if !%w(Firefox IE Chrome Opera).include? bs_browser_type + print_invalid_browser_for_os + end + elsif bs_os == 'Windows' && bs_os_version == '10' + if !%w(Firefox Edge IE Chrome).include? bs_browser_type + print_invalid_browser_for_os + end + elsif bs_os == 'OS X' && bs_os_version == 'El Capitan' + if !%w(Firefox Safari Chrome Opera).include? bs_browser_type + print_invalid_browser_for_os + end + elsif bs_os == 'iOS' && bs_os_version == 'iPhone 6S - 9.1' + if !%w(iPhone).include? bs_browser_type + print_invalid_browser_for_os + end + elsif bs_os == 'iOS' && bs_os_version == 'Galaxy S5 - 4.4' + if !%w(android).include? bs_browser_type + print_invalid_browser_for_os + end + else + puts "Provided OS and/or OS version values are either invalid or not specified in browserstack_parameters_error_handling.rb file in support folder" + end +end + +# print error for invalid browser for OS +def print_invalid_browser_for_os + puts "\nBrowser : \"#{ENV['REMOTE_BROWSER']}\" is not available on OS \"#{ENV['OS']}\" \"#{ENV['OS_VERSION']}\"" + puts "\nUsage : cucumber REMOTE_BROWSER=browser_name" + puts "\nBrowser Supported :\n" + puts "\n1.ie\n2.chrome\n3.ff\n4.safari\n5.opera" + Process.exit(0) +end \ No newline at end of file diff --git a/features-skeleton/features/support/env.rb b/features-skeleton/features/support/env.rb new file mode 100644 index 0000000..a9577f8 --- /dev/null +++ b/features-skeleton/features/support/env.rb @@ -0,0 +1,89 @@ +require 'rubygems' +require 'selenium-cucumber' + +require_relative 'browserstack_parameters_error_handling_methods' + +# Store command line arguments for local execution +$browser_type = ENV['BROWSER'] || 'ff' +$platform = ENV['PLATFORM'] || 'desktop' +#$os_version = ENV['OS_VERSION'] +$device_name = ENV['DEVICE_NAME'] +$udid = ENV['UDID'] +$app_path = ENV['APP_PATH'] + +# Store command line arguments for remote execution on Browserstack.com +$remote_execution = ENV['REMOTE_EXECUTION'] || 'no' +$browserstack_browser_type = ENV['REMOTE_BROWSER'] || 'Firefox' +$browser_version_num = ENV['BROWSER_VERSION'] || '44.0' +$os = ENV['OS_TYPE'] || 'Windows' +$os_version = ENV['OS_VERSION'] || '7' +$resolution = ENV['RESOLUTION'] || '1024x768' + +# check for valid parameters required for local execution +validate_parameters $platform, $browser_type, $app_path + +# If platform is android or ios create driver instance for mobile browser +if $platform == 'android' or $platform == 'iOS' and $remote_execution == 'no' + puts "Executing tests in local physical/simulator mobile device" + if $browser_type == 'native' + $browser_type = "Browser" + end + + if $platform == 'android' + $device_name, $os_version = get_device_info + end + + desired_caps = { + caps: { + platformName: $platform, + browserName: $browser_type, + versionNumber: $os_version, + deviceName: $device_name, + udid: $udid, + app: ".//#{$app_path}" + }, + } + + begin + $driver = Appium::Driver.new(desired_caps).start_driver + rescue Exception => e + puts e.message + Process.exit(0) + end +elsif $platform == 'desktop' and $remote_execution == 'yes' # else create driver instance for remote browser on browserstack.com +validate_browserstack_parameters $os, $os_version, $browserstack_browser_type, $browser_version_num # check for valid parameters required for remote execution on browserstack.com if remote_execution is answered yes +puts "Executing tests on remote browser via Browserstack.com" + begin + # Input capabilities + caps = Selenium::WebDriver::Remote::Capabilities.new + caps["browser"] = $browserstack_browser_type + caps["browser_version"] = $browser_version_num + caps["os"] = $os + caps["os_version"] = $os_version + caps["resolution"] = $resolution + caps["browserstack.debug"] = "true" + caps["name"] = "Executing LeadingEdge QA scripts" + + $driver = Selenium::WebDriver.for(:remote, + :url => "http://:@hub.browserstack.com/wd/hub", # enter the url from browserstack with token + :desired_capabilities => caps) + $driver.manage().window().maximize() + rescue Exception => e + puts e.message + Process.exit(0) + end +elsif $platform == 'desktop' and $remote_execution == 'no' # else create driver instance for desktop browser + puts "Executing tests in local machine" + begin + $driver = Selenium::WebDriver.for(:"#{$browser_type}") + $driver.manage().window().maximize() + rescue Exception => e + puts e.message + Process.exit(0) + end +else # else ask user to provide valid value for remote_execution + puts "\nOops... Invalid answer for REMOTE_EXECUTION" + puts "\nSupported answers are \"yes\" and \"no\"." + puts "\nTo run on browserstack.com you need to specify it as \"yes\" else no need to mention REMOTE_EXECUTION for desktop execution." + Process.exit(0) +end diff --git a/features-skeleton/features/support/hooks.rb b/features-skeleton/features/support/hooks.rb new file mode 100644 index 0000000..b45623f --- /dev/null +++ b/features-skeleton/features/support/hooks.rb @@ -0,0 +1,39 @@ +#Cucumber provides a number of hooks which allow us to run blocks at various points in the Cucumber test cycle + +Before do + # Do something before each scenario. +end + +Before do |scenario| + # The +scenario+ argument is optional, but if you use it, you can get the title, + # description, or name (title + description) of the scenario that is about to be + # executed. +end + +After do + # Do something after each scenario. +end + +After('@Ex_tag1') do |scenario| + # Do something after each scenario. + # The +scenario+ argument is optional, but + # if you use it, you can inspect status with + # the #failed?, #passed? and #exception methods. + if scenario.failed? + #Do something if scenario fails. + else + #Do something if scenario passed. + end +end + +#Tagged hooks + +Before('@Ex_tag1, @Ex_tag2') do + # This will only run before scenarios tagged + # with @Ex_tag1 OR @Ex_tag2. +end + +AfterStep('@Ex_tag1, @Ex_tag2') do + # This will only run before scenarios tagged + # with @Ex_tag1 OR @Ex_tag2. +end \ No newline at end of file diff --git a/features-skeleton/my_first.feature b/features-skeleton/my_first.feature deleted file mode 100644 index 9770b63..0000000 --- a/features-skeleton/my_first.feature +++ /dev/null @@ -1,5 +0,0 @@ -Feature: Login feature - - Scenario: As a valid user I can log into my web app - When I press "Login" - Then I see "Welcome to coolest web app ever" diff --git a/lib/selenium-cucumber/click_elements_steps.rb b/lib/selenium-cucumber/click_elements_steps.rb index 6a534bc..b2cebcc 100644 --- a/lib/selenium-cucumber/click_elements_steps.rb +++ b/lib/selenium-cucumber/click_elements_steps.rb @@ -26,6 +26,14 @@ click('partial_link_text', access_name) end +Then(/^I forcefully click on link having text "(.*?)"$/) do |access_name| + click_forcefully('link', access_name) +end + +Then(/^I forcefully click on link having partial text "(.*?)"$/) do |access_name| + click_forcefully('partial_link_text', access_name) +end + When(/^I tap on element having (.+) "(.*?)"$/) do |type, access_name| validate_locator type click(type, access_name)