Sample files:
Features:
- xxx.feature (files containing Gherkin Scenarios)
- /config:
- base_url.yml
- /support:
- env.rb
- xxx.rb
- /step_definitions
- xxx.rb (ruby step definitions to match gherkin xxx.feature file)
config.rb sample:
#config.rb
# for environment testing
require 'yaml'
# change = 'staging' to 'qa' to change environment
# at runtime, you would type: TEST_ENV=staging or TEST_ENV=qa
ENV['TEST_ENV'] ||= 'qa'
project_root = File.expand_path('../..', __FILE__)
$BASE_URL = YAML.load_file(project_root + "/support/config/base_url.yml")[ENV['TEST_ENV']][:url]
capabilities.rb sample:
module Capabilities
#---- SAUCEENDPOINT's required for testing in QA env.
# comment/uncomment the Saucelabs Connect Tunnel you want to use
#SauceLabs Connect Tunnel
SAUCEENDPOINT ||= "http://username:123456789@ondemand.saucelabs.com:80/xx/hub"
#Sauce Connect Tunnel
#SAUCEENDPOINT ||= "http://username:123456789@ondemand.saucelabs.com:80/xx/hub"
#PC/Windows/IE
IE ||= {
:platform => "Windows 8.1",
:browserName => "Internet Explorer",
:version => "11.0",
# resizing the browser window
:screenResolution => "1280x1024"
}
#PC/Windows/FireFox
FF ||= {
:platform => "Windows 7",
:browserName => "Firefox",
:acceptSslCerts => true
}
#PC/Windows/Chrome
CH ||= {
:platform => "Windows 7",
:browserName => "Chrome",
# resizing the browser window
:screenResolution => "1280x1024"
}
#PC/MAC/Safari
SF ||= {
:platform => "Mac 10.12",
:browserName => "Safari",
:version => "10",
}
#Mobile Devices
IPHONE ||= {
:deviceName => "iPhone 6",
:browserName => "Safari"
}
IPHONE7 ||= {
:deviceName => "iPhone 7",
:browserName => "Safari"
}
ANDROID ||= {
:deviceName => "Android Emulator",
:browserName => "Chrome",
}
#PC/Windows/Chrome - Languages
CHFR ||= {
:platform => "Windows 7",
:browserName => "Chrome",
:screenResolution => "1280x1024",
chromeOptions: {
# set browser 'Fr' language
args: [ 'lang=fr-FR' ],}
}
end
base_url.yml sample:
# http://stackoverflow.com/questions/25649848/running-cucumber-tests-on-different-environments # FOR BASE_URL # NOTE: # You're probably using tab characters to indent your YAML file. # This is not permitted by the YAML spec: # To maintain portability, tab characters must not be used in indentation, since different systems treat tabs differently. #Note that most modern editors may be configured so that pressing the tab key results in the insertion of an appropriate number of spaces. ### # ALSO MAKE SURE all /config/...yml files contain the same test environments. --- qa: :url: https://www-qa-environment.com staging: :url: https://www-staging-environment.com prod: :url: http://www.production-environment.com
env.rb sample:
require 'rubygems'
require 'capybara'
require 'capybara/dsl'
require 'capybara/rspec'
require 'capybara/cucumber'
#require 'capybara/poltergeist'
require 'rspec'
require 'rspec/expectations'
require 'rspec/matchers'
# see: https://www.relishapp.com/philou/cucumber-tricks/docs/special-tables
#require 'cucumber_tricks'
#require 'cucumber/formatter'
require 'json'
require 'httparty'
require 'certified'
# require 'money'
#require "rspec/json_expectations"
require 'selenium-webdriver'
require 'xpath'
####################################
#require './common/support/selectors.rb'
####################################
include RSpec::Matchers
###################################
# Capybara.default_wait_time = 5 # this one is deprecated, use default_max_wait_time instead
Capybara.default_max_wait_time = 5
Capybara.run_server = false
#Set default driver as Selenium
Capybara.default_driver = :selenium
#Set default driver as webkit (browserless)
#Capybara.javascript_driver = :webkit
#Set default selector as css
Capybara.default_selector = :css
###################################
# TO ADD CHROME BROWSER...
# from: https://cucumber.io/docs/reference/browser-automation
# at runtime you would type: browser=chrome cucumber
Capybara.register_driver :selenium do | app |
browser = (ENV['browser'] || 'firefox').to_sym
Capybara::Selenium::Driver.new(app, :browser => browser)
end
###################################
#Syncronization related settings
module Helpers
def without_resynchronize
page.driver.options[:resynchronize] = false
yield
page.driver.options[:resynchronize] = true
end
end
World(Capybara::DSL, Helpers)
###################################
# for environment testing
require 'yaml'
#change = 'staging' to 'qa' or 'prod' to change environment
# at runtime, you would type: TEST_ENV=staging or TEST_ENV=qa
ENV['TEST_ENV'] ||= 'qa'
project_root = File.expand_path('../..', __FILE__)
$BASE_URL = YAML.load_file(project_root + "/config/base_url.yml")[ENV['TEST_ENV']][:url]
# https://cbabhusal.wordpress.com/2015/08/20/ror-tdd-bdd-with-rspec-initial-setup/
############################
### FOLLOWING RETURNS ERROR AT RUNTIME AND DOESN'T WORK!
#### from: https://watirmelon.blog/2011/08/07/keeping-the-browser-open-when-youre-writing-a-cucumber-test/
#After do |scenario|
#After do |step|
# KEEP_OPEN = true if scenario.status == :pending or scenario.status == :undefined
# KEEP_OPEN = true if step.status == :pending or step.status == :undefined or step.status == :passed
#end
#at_exit do
# browser.close if not KEEP_OPEN
#end
# FROM: http://stackoverflow.com/questions/25687261/how-to-run-a-hook-only-after-selected-cucumber-scenarios
After('@take_screenshot') do |scenario|
#After do |scenario|
if scenario.passed?
screenshot_pass = "./screenshots/#{scenario.name}.jpeg"
page.save_screenshot screenshot_pass
end
end
env.rb sample
require 'rubygems'
require 'capybara'
require 'capybara/dsl'
require 'capybara/rspec'
require 'capybara/cucumber'
require 'rspec'
require 'rspec/expectations'
require 'rspec/matchers'
require 'json'
require 'httparty'
require 'certified'
require 'selenium-webdriver'
require 'xpath'
require_relative 'capabilities'
require_relative 'baseclass'
#require 'webdrivers'
##############################
require 'show_me_the_cookies'
RSpec.configure do |config|
config.include ShowMeTheCookies, :type => :feature
config.before(:each, js: true) do
# Disabling foreseeresults js
page.driver.browser.url_blacklist = ["https://.....fs.trigger.js",
"https://.......js",
"https://gateway.answerscloud.com"]
end
end
ShowMeTheCookies.register_adapter(:Firefox_FR, ShowMeTheCookies::Selenium)
ShowMeTheCookies.register_adapter(:Firefox_IT, ShowMeTheCookies::Selenium)
ShowMeTheCookies.register_adapter(:Firefox_NL, ShowMeTheCookies::Selenium)
World(ShowMeTheCookies)
####################################
include RSpec::Matchers
###################################
Capybara.run_server = false
Capybara.default_driver = :selenium
Capybara.default_selector = :css
Capybara.default_max_wait_time = 5
project_root = File.expand_path('../../', __FILE__)
Capybara.register_driver :selenium do | app |
#commented for download functionality of PDA (currently not required)
#profile = Selenium::WebDriver::Chrome::Profile.new
#profile["download.default_directory"] = project_root+"/xxx/downloads"
#profile["browser.helperApps.neverAsk.saveToDisk"] = "text/csv"
#Capybara::Selenium::Driver.new(app, :browser => :chrome, :profile => profile)
preferences = {credentials_enable_service: false,
password_manager_enabled: false}
capabilities = Selenium::WebDriver::Remote::Capabilities.chrome
capabilities['chromeOptions'] = {'prefs' => preferences}
Capybara::Selenium::Driver.new(app, browser: :chrome,
desired_capabilities: capabilities)
Capybara::Selenium::Driver.new(app, :browser => :chrome)
# Capybara::Selenium::Driver.new(app, :browser => :firefox)
end
After do
Capybara.reset_sessions!
end
####################################################################
def self.set_browser
capabilities = Capabilities::CH
if (ENV['browser'] == 'firefox')
capabilities = Capabilities::FF
end
if (ENV['browser'] == 'IE')
capabilities = Capabilities::IE
end
if (ENV['browser'] == 'SF')
capabilities = Capabilities::SF
end
if (ENV['browser'] == 'iPhone')
capabilities = Capabilities::IPHONE
end
if (ENV['browser'] == 'android')
capabilities = Capabilities::ANDROID
end
return capabilities
end
#################################
### START testing with sauce labs
if (ENV['SAUCE_ENV'] == 'SAUCE')
capabilities = self.set_browser()
Before ('@IE') do
capabilities = Capabilities::IE
end
Before ('@FF') do
capabilities = Capabilities::FF
end
Before ('@CH') do
capabilities = Capabilities::CH
end
Before ('@SF') do
capabilities = Capabilities::SF
end
Before ('@IPHONE') do
capabilities = Capabilities::IPHONE
end
Before ('@CHFR') do
capabilities = Capabilities::CHFR
end
capabilities[:tunnelIdentifier] = ENV['TUNNEL_IDENTIFIER']
Capybara.register_driver :selenium do |app|
url = "https://#{ENV['SAUCE_USERNAME']}:#{ENV['SAUCE_ACCESS_KEY']}@ondemand.saucelabs.com:443/wd/hub".strip
Capybara::Selenium::Driver.new(app,
:browser => :remote, :url => url,
:desired_capabilities => capabilities)
end
end
if ENV['SAUCE_ENV'] == 'LOCALSAUCE'
capabilities = self.set_browser()
Before ('@IE') do
capabilities = Capabilities::IE
end
Before ('@FF') do
capabilities = Capabilities::FF
end
Before ('@CH') do
capabilities = Capabilities::CH
end
Before ('@SF') do
capabilities = Capabilities::SF
end
Before ('@ANDROID') do
capabilities = Capabilities::ANDROID
end
Before ('@IPHONE') do
capabilities = Capabilities::IPHONE
end
Before ('@CHFR') do
capabilities = Capabilities::CHFR
end
Capybara.register_driver :selenium do |app|
Capybara::Selenium::Driver.new(app, :browser => :remote, :url => Capabilities::SAUCEENDPOINT, :desired_capabilities => capabilities)
end
end
Capybara.current_driver = :selenium
if (ENV['SAUCE_ENV'] == 'SAUCE')
After do | scenario |
driver = ::Capybara.current_session.driver
session_id = driver.browser.session_id
job_name = scenario.feature.name
output = []
output << "\nSauceOnDemandSessionID=#{session_id} job-name=#{job_name}"
puts output.join(' ')
end
end
### END testing with sauce labs
#################################
#Syncronization related settings
module Helpers
def without_resynchronize
page.driver.options[:resynchronize] = false
yield
page.driver.options[:resynchronize] = true
end
end
World(Capybara::DSL, Helpers)
#################################
hooks.rb sample
INFO: https://github.com/cucumber/cucumber/wiki/Hooks
################### SECTION TO ADD BEFORE/AFTER HOOKS #########################
Before ('@MaximizeBrowser') do |scenario|
Capybara.page.driver.browser.manage.window.maximize
end
Before ('@Mobile') do |scenario|
Capybara.page.current_window.resize_to(414, 736)
end
Before ('@StorageClear') do |scenario|
visit($BASE_URL)
Capybara.page.execute_script("localStorage.clear()")
end
Before ('@SessionStorageClear') do |scenario|
visit($BASE_URL)
Capybara.page.execute_script("sessionStorage.clear()")
end
Before ('@ClearCookies') do |scenario|
visit($BASE_URL)
expire_cookies
# Capybara.reset_sessions!
end
Before ('@DeleteCookiesAddForesee') do |scenario|
visit($BASE_URL)
sleep 3
browser = Capybara.current_session.driver.browser
browser.manage.delete_all_cookies
sleep 1
browser.manage.add_cookie :name => "fsr.s", :value => "{'v2':-2,'v1':1,'rid':'d036702-53702257-2645-8fd6-921ea','to':3,'c':'.site.com','pv':1,'lc':{'d0':{'v':1,'s':true}},'cd':0,'sd':0,'l':'en','i':-1}"
browser.manage.add_cookie :name => "_4c_", :value => "{'v2':-2,'v1':1,'rid':'d036702-53702257-2645-8fd6-921ea','to':3,'c':'.site.com','pv':1,'lc':{'d0':{'v':1,'s':true}},'cd':0,'sd':0,'l':'en','i':-1}"
visit($BASE_URL)
sleep 2
el = first(:xpath, "//img[@id='_evh-ric-c']", maximum: 1)
el.click unless el.nil?
el = first(:xpath, "//a[@class='close close-pbl-overlay']", maximum: 1)
el.click unless el.nil?
end
world_extensions.rb sample
#http://stackoverflow.com/questions/918066/reuse-cucumber-steps
# from: http://www.unknownerror.org/opensource/cucumber/cucumber/q/stackoverflow/918066/reuse-cucumber-steps
# checkout: https://github.com/cucumber/cucumber/wiki/A-Whole-New-World
#########/support/world_extensions.rb ###########
#module KnowsUser
# def login
#visit('/login')
# fill_in('User name', with: user.name)
# fill_in('Password', with: user.password)
# #click_button('Log in')
# click_on('btnSubmit')
# end
# def user
# @user ||= User.create!(:name => 'user@mailinator.com', :password => 'mypassoword')
# end
#end
#World(KnowsUser)
###################################################################
# FOR /.../xx.rb
module ACME_site
def login_from_site
# within_fieldset('new_user_signin_form')
visit($BASE_URL)
click_on('signin_btn')
fill_in 'UserName', :with => 'email-address@something.com'
# fill_in("userName", :with => "email-address@something.com")
click_on('verify_user_btn')
fill_in("password", :with => "mypassword")
click_on("btnSubmit")
sleep 3
end
def login_from_site(username,password)
# within_fieldset('new_user_signin_form')
visit($BASE_URL) #--> this is url from yml file
click_on('signin_button')
account_signin(username, password)
end
# user account exists on both qa/prod
def name_of_definition
visit($BASE_URL)
click_on('signin_btn')
fill_in 'UserName', :with => 'emailaddress'
click_on('verify_user_btn')
fill_in("password", :with => "mypassword")
click_on("btnSubmit")
sleep 3
end
end
World(ACME_site)
-------
# FROM: http://drnicwilliams.com/2009/04/15/cucumber-building-a-better-world-object/
module FormSubmissionHelpers
def fill_in_account_form_for_trial_profile
# within_fieldset('new_user_signin_form')
sleep 2 # adding more buffer time to load the page
fill_in 'UserName', :with => 'myusername'
# fill_in("userName", :with => "emailaddress")
click_on('verify_user_btn')
fill_in("password", :with => "mypassword")
click_on("btnSubmit")
sleep 4
end
end
World(FormSubmissionHelpers)
###################################################################
# FOR XXX
module TrialFLow
def fill_trial_form_individual
within(:xpath,"//*[contains(@class,'user-types-box')]") do
select('An individual or business user')
end
end
def sign_in_trial
within_frame(0) do
#click_on('signin_link')
fill_in 'UserName', :with =>"user@mailinator.com"
click_on('verify_user_btn')
fill_in("password", :with => "mypassword")
click_on("btnSubmit")
sleep 3
end
end
end
World(TrialDownloadFlow)
###################################################################
module DomainUrlValidation
def host_page_validation(site, page)
sleep 5
domain = Env_Url.environment_links(site)
#puts "\n current_path --->", current_path
#current_host.should == (domain)
expect(domain).to include(current_host)
expect(current_path).to include(page)
#current_path.should == page
#puts "\n current_host --->", current_host
#puts "\n current_path --->", current_path
# sleep 5
end
def domain_page_validation_latinoamerica(page)
sleep 5
#puts "\n current_host --->", current_host
#puts "\n current_path --->", current_path
url = ($LATINOAMERICA_URL)
current_host.should == url
current_path.should == page
# sleep 4
end
end
World(DomainUrlValidation)
###################################################################
module loggedin_user
def click_my_save_button_to_save
find(:xpath, "//*[contains(@-save-content,'1234567')]").click
sleep 5
end
def click_my__save_button_to_unsave
find(:xpath, "//*[@class='icon-check']").click
sleep 5
end
end
World(COD_loggedin_user)
###################################################################
# For X account types
module FormSubmission
def name_signin(username, password)
fill_in('UserName', :with => username)
click_on('verify_user_button')
fill_in("password", :with => password)
click_on("buttonSubmit")
sleep 4
end
end
World(FormSubmissionSSO)
helpers.rb sample
https://stackoverflow.com/questions/17623075/auto-scroll-a-button-into-view-with-capybara-and-selenium
module JavascriptDriver
# other code that prepares capybara to work with selenium
def scroll_to(element)
script = <<-JS
arguments[0].scrollIntoView(true);
JS
Capybara.current_session.driver.browser.execute_script(script, element.native)
end
end
# HOW TO USE:
# Add a step definition:
# scroll_to(page.find("button.some-class", visible: false))
GEMFILE sample
source 'https://rubygems.org' gem 'package', '~> 0.0.1' gem 'rubygems-update', '~> 2.6', '>= 2.6.11' gem 'cucumber', '~> 2.4' # CAPYBARA: step definition library for Cucumber gem 'capybara', '~> 2.13' gem 'chrome', '~> 0.1.0' gem 'chromedriver-helper', '~> 1.1' #gem 'chromedriver2-helper', '~> 0.0.10' # RSPEC: step definition library for Cucumber gem 'rspec', '~> 3.5' gem 'rspec-expectations' gem 'rspec-matcher' gem 'json' gem 'httparty' gem 'certified', '~> 1.0' gem 'xpath', '~> 2.0' # Run any kind of code in parallel processes gem 'parallel', '~> 1.11', '>= 1.11.1' gem 'parallel_tests' gem 'selenium-webdriver', '~> 3.3' gem 'currencies', '~> 0.4.2' gem 'show_me_the_cookies', '~> 3.1' # To launch a Tunnel to SauceLabs gem 'sauce-connect', '~> 3.6', '>= 3.6.3' # to run tests in parallel on SauceLabs gem 'sauce_whisk', '~> 0.0.21'
sample