Cucumber Files

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:12*******@on******.com:80/xx/hub"

#Sauce Connect Tunnel
#SAUCEENDPOINT ||= "http://username:12*******@on******.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 => 'us**@ma********.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 => 'em***********@so*******.com'
# fill_in("userName", :with => "em***********@so*******.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 =>"us**@ma********.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