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