├── .gitignore ├── CONTRIBUTING.md ├── Gemfile ├── LICENSE ├── README.md ├── Rakefile ├── bin ├── generate.rb ├── helper.rb └── selenium-cucumber ├── doc ├── canned_steps.md ├── installation.md ├── selenium-cucumber-API.md └── selenium-cucumber-help.md ├── example ├── android │ ├── android_app │ │ ├── HinduCalendar.zip │ │ ├── HinduCalendar │ │ │ ├── HinduCalendar.apk │ │ │ ├── README.md │ │ │ ├── Results.html │ │ │ └── features │ │ │ │ ├── 01_HC_homepage_menu_validation.feature │ │ │ │ ├── 02_HC_homepage_menu_navigation.feature │ │ │ │ ├── 03_HC_Create_Save_View_Delete_Kundali.feature │ │ │ │ ├── actual_images │ │ │ │ └── test.png │ │ │ │ ├── expected_images │ │ │ │ └── test.png │ │ │ │ ├── image_difference │ │ │ │ └── test.png │ │ │ │ ├── my_first.feature │ │ │ │ ├── screenshots │ │ │ │ └── test.png │ │ │ │ ├── step_definitions │ │ │ │ ├── 01_HC_homepage_menu_validation.rb │ │ │ │ ├── 02_HC_homepage_menu_navigation.rb │ │ │ │ ├── 03_HC_Create_Save_View_Delete_Kundali.rb │ │ │ │ └── custom_steps.rb │ │ │ │ └── support │ │ │ │ ├── env.rb │ │ │ │ └── hooks.rb │ │ ├── android_app_calculator.zip │ │ └── android_app_calculator │ │ │ ├── AndroidCalculator.apk │ │ │ └── features │ │ │ ├── actual_images │ │ │ └── test.png │ │ │ ├── calculator.feature │ │ │ ├── expected_images │ │ │ └── test.png │ │ │ ├── image_difference │ │ │ └── test.png │ │ │ ├── my_first.feature │ │ │ ├── screenshots │ │ │ └── test.png │ │ │ ├── step_definitions │ │ │ └── custom_steps.rb │ │ │ └── support │ │ │ ├── env.rb │ │ │ └── hooks.rb │ └── android_web │ │ ├── android_web_gmail_login.zip │ │ └── android_web_gmail_login │ │ └── features │ │ ├── actual_images │ │ └── test.png │ │ ├── expected_images │ │ └── test.png │ │ ├── gmail_login.feature │ │ ├── image_difference │ │ └── test.png │ │ ├── my_first.feature │ │ ├── screenshots │ │ └── test.png │ │ ├── step_definitions │ │ └── custom_steps.rb │ │ └── support │ │ ├── env.rb │ │ └── hooks.rb └── desktop web │ ├── desktop_web_gmail_login.zip │ └── desktop_web_gmail_login │ └── features │ ├── actual_images │ └── test.png │ ├── expected_images │ └── test.png │ ├── gmail_login.feature │ ├── gmail_multi_login.feature │ ├── image_difference │ └── test.png │ ├── my_first.feature │ ├── screenshots │ └── test.png │ ├── step_definitions │ └── custom_steps.rb │ └── support │ ├── env.rb │ └── hooks.rb ├── features-skeleton ├── actual_images │ └── test.png ├── expected_images │ └── test.png ├── image_difference │ └── test.png ├── my_first.feature ├── screenshots │ └── test.png ├── step_definitions │ └── custom_steps.rb └── support │ ├── env.rb │ └── hooks.rb ├── lib ├── selenium-cucumber.rb └── selenium-cucumber │ ├── assertion_steps.rb │ ├── click_elements_steps.rb │ ├── configuration_steps.rb │ ├── input_steps.rb │ ├── javascript_handling_steps.rb │ ├── methods │ ├── assertion_methods.rb │ ├── click_elements_methods.rb │ ├── configuration_methods.rb │ ├── error_handling_methods.rb │ ├── input_methods.rb │ ├── javascript_handling_methods.rb │ ├── misc_methods.rb │ ├── mobile_methods.rb │ ├── navigate_methods.rb │ ├── progress_methods.rb │ ├── required_files.rb │ └── screenshot_methods.rb │ ├── mobile_steps.rb │ ├── navigation_steps.rb │ ├── progress_steps.rb │ ├── screenshot_steps.rb │ └── version.rb ├── selenium-cucumber.gemspec └── tests ├── Gemfile ├── Gemfile.lock ├── features ├── actual_images │ └── test.png ├── assertion_steps_Ex.feature ├── click_steps_Ex.feature ├── configuration_step_Ex.feature ├── expected_images │ ├── logo-PNG.png │ └── original_image.jpg ├── image_difference │ └── test.png ├── input_steps_Ex.feature ├── javascript_steps_Ex.feature ├── navigation_steps_Ex.feature ├── progress_step_Ex.feature ├── screenshot_step_Ex.feature ├── screenshots │ └── test.png ├── step_definitions │ └── custom_steps.rb └── support │ ├── env.rb │ └── hooks.rb ├── iFrame1.html ├── iFrame2.html ├── run_features.rb └── test_page.html /.gitignore: -------------------------------------------------------------------------------- 1 | 2 | # Created by https://www.gitignore.io/api/ruby 3 | 4 | ### Ruby ### 5 | *.gem 6 | *.rbc 7 | /.config 8 | /coverage/ 9 | /InstalledFiles 10 | /pkg/ 11 | /spec/reports/ 12 | /spec/examples.txt 13 | /test/tmp/ 14 | /test/version_tmp/ 15 | /tmp/ 16 | 17 | # Used by dotenv library to load environment variables. 18 | # .env 19 | 20 | ## Specific to RubyMotion: 21 | .dat* 22 | .repl_history 23 | build/ 24 | *.bridgesupport 25 | build-iPhoneOS/ 26 | build-iPhoneSimulator/ 27 | 28 | ## Specific to RubyMotion (use of CocoaPods): 29 | # 30 | # We recommend against adding the Pods directory to your .gitignore. However 31 | # you should judge for yourself, the pros and cons are mentioned at: 32 | # https://guides.cocoapods.org/using/using-cocoapods.html#should-i-check-the-pods-directory-into-source-control 33 | # 34 | # vendor/Pods/ 35 | 36 | ## Documentation cache and generated files: 37 | /.yardoc/ 38 | /_yardoc/ 39 | /doc/ 40 | /rdoc/ 41 | 42 | ## Environment normalization: 43 | /.bundle/ 44 | /vendor/bundle 45 | /lib/bundler/man/ 46 | 47 | # for a library or gem, you might want to ignore these files since the code is 48 | # intended to run in multiple environments; otherwise, check them in: 49 | # Gemfile.lock 50 | # .ruby-version 51 | # .ruby-gemset 52 | 53 | # unless supporting rvm < 1.11.0 or doing something fancy, ignore this: 54 | .rvmrc 55 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing 2 | 3 | We would love to get any pull requests. Here's a quick guide. 4 | 5 | Fork, then clone the repo: 6 | 7 | git clone git@github.com:your-username/selenium-cucumber.git 8 | 9 | Run `/example` tests through your local repo: 10 | 11 | 1. cd your_repo 12 | 2. cd example 13 | 3. Open Gemfile 14 | 4. Uncomment `gem 'selenium-cucumber', path: 'your local repo path'` and 15 | replace 'your local repo path' with your local repo path 16 | 5. Comment out `gem 'selenium-cucumber'` 17 | 6. bundle install 18 | 7. Run tests as: 19 | `cucumber` (or `cucumber features/any_feature_name.feature`) 20 | 21 | Make your change. Add tests for your change in `/example`. 22 | Make sure to run all the test(or features) successfully. 23 | Commit your changes but don't forget to revert the changes of comment/uncomment 24 | in Gemfile(done to run tests through local repo). 25 | 26 | Push to your fork and [submit a pull request][pr]. 27 | 28 | [pr]: https://github.com/sameer49/selenium-cucumber-ruby/compare 29 | 30 | At this point you're waiting on us. We like to at least comment on pull requests 31 | or may suggest some changes or discuss improvements or alternatives. 32 | -------------------------------------------------------------------------------- /Gemfile: -------------------------------------------------------------------------------- 1 | source 'https://rubygems.org' 2 | gemspec 3 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | selenium-cucumber 2 | Copyright (c) Sameer Sawant. All rights reserved. 3 | You must not remove this notice, or any other, from this software. -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | Welcome to selenium-cucumber 2 | ================= 3 | 4 | [![Gem Version](https://badge.fury.io/rb/selenium-cucumber.svg)](http://badge.fury.io/rb/selenium-cucumber) 5 | 6 | selenium-cucumber : Automation Testing Using Ruby 7 | 8 | selenium-cucumber is a behavior driven development (BDD) approach to write automation test script to test Web and Android Apps. 9 | It enables you to write and execute automated acceptance/unit tests. 10 | It is cross-platform, open source and free. 11 | Automate your test cases with minimal coding. 12 | [More Details](http://seleniumcucumber.info/) 13 | 14 | Documentation 15 | ------------- 16 | * [Installation](doc/installation.md) 17 | * [Predefined steps](doc/canned_steps.md) 18 | * [selenium-cucumber API's](doc/selenium-cucumber-API.md) 19 | 20 | Writing a test 21 | -------------- 22 | 23 | The cucumber features goes in the `features` library and should have the ".feature" extension. 24 | 25 | You can start out by looking at `features/my_first.feature`. You can extend this feature or make your own features using some of the [predefined steps](doc/canned_steps.md) that comes with selenium-cucumber. 26 | 27 | Generate a Cucumber skeleton 28 | ---------------------------- 29 | 30 | To get started with selenium-cucumber you need to run `selenium-cucumber gen` command. This will create a cucumber skeleton in the current folder like this: 31 | 32 | features 33 | | 34 | |__support 35 | | |__env.rb 36 | | |__hooks.rb 37 | | 38 | |__step_definitions 39 | | |__custom_steps.rb 40 | | 41 | |__actual_images 42 | | 43 | |__expected_images 44 | | 45 | |__image_difference 46 | | 47 | |__screenshots 48 | | 49 | |__my_first.feature 50 | 51 | Take a look at `my_first.feature` and change it to fit your web or android application. 52 | 53 | 54 | Predefined steps 55 | ----------------- 56 | By using predefined steps you can automate your test cases more quickly, more efficiently and without much coding. 57 | 58 | The predefined steps are located [here](doc/canned_steps.md) 59 | 60 | 61 | selenium-cucumber API's 62 | ----------------------- 63 | By using selenium-cucumber API's you can write code for your custom steps more efficiently. 64 | 65 | The selenium-cucumber API's steps are located [here](doc/selenium-cucumber-API.md) 66 | 67 | 68 | Contributing 69 | ------------------- 70 | Please see [CONTRIBUTING.md](CONTRIBUTING.md). 71 | 72 | 73 | License 74 | ------- 75 | 76 | (The MIT License) 77 | 78 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the 'Software'), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 79 | 80 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 81 | 82 | THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 83 | -------------------------------------------------------------------------------- /Rakefile: -------------------------------------------------------------------------------- 1 | require 'bundler/gem_tasks' 2 | require 'rake/testtask' 3 | project_name = 'selenium-cucumber' 4 | -------------------------------------------------------------------------------- /bin/generate.rb: -------------------------------------------------------------------------------- 1 | def selenium_cucumber_scaffold 2 | if File.exists?(@features_dir) 3 | puts "A features directory already exists. Stopping..." 4 | exit 1 5 | end 6 | msg("Question") do 7 | puts "I'm about to create a subdirectory called features." 8 | puts "features will contain all your project tests." 9 | puts "Please hit return to confirm that's what you want." 10 | end 11 | exit 2 unless STDIN.gets.chomp == '' 12 | 13 | FileUtils.cp_r(@source_dir, @features_dir) 14 | 15 | msg("Info") do 16 | puts "features subdirectory created. \n" 17 | end 18 | 19 | end 20 | -------------------------------------------------------------------------------- /bin/helper.rb: -------------------------------------------------------------------------------- 1 | require 'tempfile' 2 | require 'json' 3 | require "rubygems" 4 | 5 | def msg(title, &block) 6 | puts "\n" + "-"*10 + title + "-"*10 7 | block.call 8 | puts "-"*10 + "-------" + "-"*10 + "\n" 9 | end 10 | 11 | def print_usage 12 | puts < [parameters] [options] 15 | 16 | can be one of 17 | help 18 | prints more detailed help information. 19 | gen 20 | generate a features folder structure. 21 | version 22 | prints the gem version 23 | 24 | can be 25 | -v, --verbose Turns on verbose logging 26 | EOF 27 | end 28 | 29 | def print_help 30 | puts < [parameters] [options] 33 | 34 | can be one of 35 | help 36 | gen 37 | version 38 | 39 | Commands: 40 | help : prints more detailed help information. 41 | 42 | gen : creates a skeleton features dir. This is usually used once when 43 | setting up selenium-cucumber to ensure that the features folder contains 44 | the right step definitions and environment to run with cucumber. 45 | 46 | version : prints the gem version 47 | 48 | 49 | -v, --verbose Turns on verbose logging 50 | EOF 51 | end 52 | -------------------------------------------------------------------------------- /bin/selenium-cucumber: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | require_relative 'helper.rb' 3 | require_relative 'generate.rb' 4 | require 'selenium-cucumber/version' 5 | 6 | @features_dir = File.join(FileUtils.pwd, "features") 7 | @support_dir = File.join(@features_dir, "support") 8 | @support_dir = File.join(@features_dir, "expected_images") 9 | @support_dir = File.join(@features_dir, "actual_images") 10 | @support_dir = File.join(@features_dir, "image_difference") 11 | @support_dir = File.join(@features_dir, "screenshots") 12 | @source_dir = File.join(File.dirname(__FILE__), '..', 'features-skeleton') 13 | 14 | if (ARGV.length == 0) 15 | print_usage 16 | else 17 | cmd = ARGV.shift 18 | 19 | if cmd == "help" 20 | print_help 21 | elsif cmd == "gen" 22 | selenium_cucumber_scaffold 23 | elsif cmd == "version" 24 | puts Selenium::Cucumber::VERSION 25 | else 26 | print_usage 27 | end 28 | end 29 | 30 | -------------------------------------------------------------------------------- /doc/canned_steps.md: -------------------------------------------------------------------------------- 1 | # Canned Steps 2 | 3 | selenium-cucumber comes with the following set of predefined steps. 4 | You can add your own steps or change the ones you see here. 5 | 6 | 7 | * [Navigation Steps](https://github.com/selenium-cucumber/selenium-cucumber-ruby/blob/master/doc/canned_steps.md#navigation-steps) 8 | * [Assertion Steps](https://github.com/selenium-cucumber/selenium-cucumber-ruby/blob/master/doc/canned_steps.md#assertion-steps) 9 | * [Input Steps](https://github.com/selenium-cucumber/selenium-cucumber-ruby/blob/master/doc/canned_steps.md#input-steps) 10 | * [Click Steps](https://github.com/selenium-cucumber/selenium-cucumber-ruby/blob/master/doc/canned_steps.md#click-steps) 11 | * [Progress Steps](https://github.com/selenium-cucumber/selenium-cucumber-ruby/blob/master/doc/canned_steps.md#progress-steps) 12 | * [Screenshot Steps](https://github.com/selenium-cucumber/selenium-cucumber-ruby/blob/master/doc/canned_steps.md#screenshot-steps) 13 | * [Configuration Steps](https://github.com/selenium-cucumber/selenium-cucumber-ruby/blob/master/doc/canned_steps.md#configuration-steps) 14 | * [Mobile steps](https://github.com/selenium-cucumber/selenium-cucumber-ruby/blob/master/doc/canned_steps.md#mobile-steps) 15 | 16 | 17 | 18 | ## Navigation Steps 19 | 20 | To open/close URL and to navigate between pages use following steps : 21 | 22 | Then I navigate to "([^\"]*)" 23 | Then I navigate forward 24 | Then I navigate back 25 | Then I refresh page 26 | 27 | To switch between windows use following steps : 28 | 29 | Then I switch to new window 30 | Then I switch to previous window 31 | Then I switch to window having title "(.*?)" 32 | Then I switch to window having url "(.*?)" 33 | Then I close new window 34 | Then I switch to main window 35 | 36 | To switch between frames use following steps : 37 | 38 | Then I switch to frame "(.*?)" 39 | Then I switch to main content 40 | 41 | To interact with browser use following steps : 42 | 43 | Then I resize browser window size to width (\d+) and height (\d+) 44 | Then I maximize browser window 45 | Then I close browser 46 | 47 | To zoom in/out webpage use following steps : 48 | 49 | Then I zoom in page 50 | Then I zoom out page 51 | 52 | To zoom out webpage till necessary element displays use following steps : 53 | 54 | Then I zoom out page till I see element having id "(.*?)" 55 | Then I zoom out page till I see element having name "(.*?)" 56 | Then I zoom out page till I see element having class "(.*?)" 57 | Then I zoom out page till I see element having xpath "(.*?)" 58 | Then I zoom out page till I see element having css "(.*?)" 59 | 60 | To reset webpage view use following step : 61 | 62 | Then I reset page view 63 | 64 | To scroll webpage use following steps : 65 | 66 | Then I scroll to top of page 67 | Then I scroll to end of page 68 | 69 | To scroll webpage to specific element use following steps : 70 | 71 | Then I scroll to element having id "(.*?)" 72 | Then I scroll to element having name "(.*?)" 73 | Then I scroll to element having class "(.*?)" 74 | Then I scroll to element having xpath "(.*?)" 75 | Then I scroll to element having css "(.*?)" 76 | 77 | To hover over a element use following steps : 78 | 79 | Then I hover over element having id "(.*?)" 80 | Then I hover over element having name "(.*?)" 81 | Then I hover over element having class "(.*?)" 82 | Then I hover over element having xpath "(.*?)" 83 | Then I hover over element having css "(.*?)" 84 | 85 | 86 | Assertion Steps 87 | --------------- 88 | To assert that page title can be found use following step : 89 | 90 | Then I should see page title as "(.*?)" 91 | Then I should not see page title as "(.*?)" 92 | 93 | Then I should see page title having partial text as "(.*?)" 94 | Then I should not see page title having partial text as "(.*?)" 95 | 96 | #### Steps For Asserting Element Text 97 | 98 | To assert element text use any of the following steps : 99 | 100 | Then element having id "([^\"]*)" should have text as "(.*?)" 101 | Then element having name "([^\"]*)" should have text as "(.*?)" 102 | Then element having class "([^\"]*)" should have text as "(.*?)" 103 | Then element having xpath "([^\"]*)" should have text as "(.*?)" 104 | Then element having css "([^\"]*)" should have text as "(.*?)" 105 | 106 | Then element having id "([^\"]*)" should have partial text as "(.*?)" 107 | Then element having name "([^\"]*)" should have partial text as "(.*?)" 108 | Then element having class "([^\"]*)" should have partial text as "(.*?)" 109 | Then element having xpath "([^\"]*)" should have partial text as "(.*?)" 110 | Then element having css "([^\"]*)" should have partial text as "(.*?)" 111 | 112 | Then element having id "([^\"]*)" should not have text as "(.*?)" 113 | Then element having name "([^\"]*)" should not have text as "(.*?)" 114 | Then element having class "([^\"]*)" should not have text as "(.*?)" 115 | Then element having xpath "([^\"]*)" should not have text as "(.*?)" 116 | Then element having css "([^\"]*)" should not have text as "(.*?)" 117 | 118 | Then element having id "([^\"]*)" should not have partial text as "(.*?)" 119 | Then element having name "([^\"]*)" should not have partial text as "(.*?)" 120 | Then element having class "([^\"]*)" should not have partial text as "(.*?)" 121 | Then element having xpath "([^\"]*)" should not have partial text as "(.*?)" 122 | Then element having css "([^\"]*)" should not have partial text as "(.*?)" 123 | 124 | #### Steps For Asserting Element Attribute 125 | 126 | To assert element attribute use any of the following steps : 127 | 128 | Then element having id "([^\"]*)" should have attribute "(.*?)" with value "(.*?)" 129 | Then element having name "([^\"]*)" should have attribute "(.*?)" with value "(.*?)" 130 | Then element having class "([^\"]*)" should have attribute "(.*?)" with value "(.*?)" 131 | Then element having xpath "([^\"]*)" should have attribute "(.*?)" with value "(.*?)" 132 | Then element having css "([^\"]*)" should have attribute "(.*?)" with value "(.*?)" 133 | 134 | Then element having id "([^\"]*)" should not have attribute "(.*?)" with value "(.*?)" 135 | Then element having name "([^\"]*)" should not have attribute "(.*?)" with value "(.*?)" 136 | Then element having class "([^\"]*)" should not have attribute "(.*?)" with value "(.*?)" 137 | Then element having xpath "([^\"]*)" should not have attribute "(.*?)" with value "(.*?)" 138 | Then element having css "([^\"]*)" should not have attribute "(.*?)" with value "(.*?)" 139 | 140 | 141 | #### Steps For Asserting Element Accesibility 142 | 143 | To assert that element is enabled use any of the following steps : 144 | 145 | Then element having id "([^\"]*)" should be enabled 146 | Then element having name "([^\"]*)" should be enabled 147 | Then element having class "([^\"]*)" should be enabled 148 | Then element having xpath "([^\"]*)" should be enabled 149 | Then element having css "([^\"]*)" should be enabled 150 | 151 | To assert that element is disabled use any of the following steps : 152 | 153 | Then element having id "([^\"]*)" should be disabled 154 | Then element having name "([^\"]*)" should be disabled 155 | Then element having class "([^\"]*)" should be disabled 156 | Then element having xpath "([^\"]*)" should be disabled 157 | Then element having css "([^\"]*)" should be disabled 158 | 159 | #### Steps For Asserting Element Visibility 160 | 161 | To assert that element is present use any of the following steps : 162 | 163 | Then element having id "([^\"]*)" should be present 164 | Then element having name "([^\"]*)" should be present 165 | Then element having class "([^\"]*)" should be present 166 | Then element having xpath "([^\"]*)" should be present 167 | Then element having css "([^\"]*)" should be present 168 | 169 | To assert that element is not present use any of the following steps: 170 | 171 | Then element having id "([^\"]*)" should not be present 172 | Then element having name "([^\"]*)" should not be present 173 | Then element having class "([^\"]*)" should not be present 174 | Then element having xpath "([^\"]*)" should not be present 175 | Then element having css "([^\"]*)" should not be present 176 | 177 | #### Steps For Asserting Checkbox 178 | 179 | To assert that checkbox is checked use any of the following steps : 180 | 181 | Then checkbox having id "(.*?)" should be checked 182 | Then checkbox having name "(.*?)" should be checked 183 | Then checkbox having class "(.*?)" should be checked 184 | Then checkbox having xpath "(.*?)" should be checked 185 | Then checkbox having css "(.*?)" should be checked 186 | 187 | To assert that checkbox is unchecked use any of the following steps : 188 | 189 | Then checkbox having id "(.*?)" should be unchecked 190 | Then checkbox having name "(.*?)" should be unchecked 191 | Then checkbox having class "(.*?)" should be unchecked 192 | Then checkbox having xpath "(.*?)" should be unchecked 193 | Then checkbox having css "(.*?)" should be unchecked 194 | 195 | #### Steps For Asserting Dropdown List 196 | 197 | To assert that option by text from dropdown list selected use following steps : 198 | 199 | Then option "(.*?)" by text from dropdown having id "(.*?)" should be selected 200 | Then option "(.*?)" by text from dropdown having name "(.*?)" should be selected 201 | Then option "(.*?)" by text from dropdown having class "(.*?)" should be selected 202 | Then option "(.*?)" by text from dropdown having xpath "(.*?)" should be selected 203 | Then option "(.*?)" by text from dropdown having css "(.*?)" should be selected 204 | 205 | To assert that option by value from dropdown list selected use following steps : 206 | 207 | Then option "(.*?)" by value from dropdown having id "(.*?)" should be selected 208 | Then option "(.*?)" by value from dropdown having name "(.*?)" should be selected 209 | Then option "(.*?)" by value from dropdown having class "(.*?)" should be selected 210 | Then option "(.*?)" by value from dropdown having xpath "(.*?)" should be selected 211 | Then option "(.*?)" by value from dropdown having css "(.*?)" should be selected 212 | 213 | To assert that option by text from dropdown list unselected use following steps : 214 | 215 | Then option "(.*?)" by text from dropdown having id "(.*?)" should be unselected 216 | Then option "(.*?)" by text from dropdown having name "(.*?)" should be unselected 217 | Then option "(.*?)" by text from dropdown having class "(.*?)" should be unselected 218 | Then option "(.*?)" by text from dropdown having xpath "(.*?)" should be unselected 219 | Then option "(.*?)" by text from dropdown having css "(.*?)" should be unselected 220 | 221 | To assert that option by value from dropdown list unselected use following steps : 222 | 223 | Then option "(.*?)" by value from dropdown having id "(.*?)" should be unselected 224 | Then option "(.*?)" by value from dropdown having name "(.*?)" should be unselected 225 | Then option "(.*?)" by value from dropdown having class "(.*?)" should be unselected 226 | Then option "(.*?)" by value from dropdown having xpath "(.*?)" should be unselected 227 | Then option "(.*?)" by value from dropdown having css "(.*?)" should be unselected 228 | 229 | #### Steps For Asserting Radio Button 230 | 231 | To assert that radio button selected use any of the following steps : 232 | 233 | Then radio button having id "(.*?)" should be selected 234 | Then radio button having name "(.*?)" should be selected 235 | Then radio button having class "(.*?)" should be selected 236 | Then radio button having xpath "(.*?)" should be selected 237 | Then radio button having css "(.*?)" should be selected 238 | 239 | To assert that radio button not selected use any of the following steps : 240 | 241 | Then radio button having id "(.*?)" should be unselected 242 | Then radio button having name "(.*?)" should be unselected 243 | Then radio button having class "(.*?)" should be unselected 244 | Then radio button having xpath "(.*?)" should be unselected 245 | Then radio button having css "(.*?)" should be unselected 246 | 247 | To assert that radio button group selected by text use any of the following steps : 248 | 249 | Then option "(.*?)" by text from radio button group having id "(.*?)" should be selected 250 | Then option "(.*?)" by text from radio button group having name "(.*?)" should be selected 251 | Then option "(.*?)" by text from radio button group having class "(.*?)" should be selected 252 | Then option "(.*?)" by text from radio button group having xpath "(.*?)" should be selected 253 | Then option "(.*?)" by text from radio button group having css "(.*?)" should be selected 254 | 255 | To assert that radio button group selected by value use any of the following steps : 256 | 257 | Then option "(.*?)" by value from radio button group having id "(.*?)" should be selected 258 | Then option "(.*?)" by value from radio button group having name "(.*?)" should be selected 259 | Then option "(.*?)" by value from radio button group having class "(.*?)" should be selected 260 | Then option "(.*?)" by value from radio button group having xpath "(.*?)" should be selected 261 | Then option "(.*?)" by value from radio button group having css "(.*?)" should be selected 262 | 263 | To assert that radio button group not selected by text use any of the following steps : 264 | 265 | Then option "(.*?)" by text from radio button group having id "(.*?)" should be unselected 266 | Then option "(.*?)" by text from radio button group having name "(.*?)" should be unselected 267 | Then option "(.*?)" by text from radio button group having class "(.*?)" should be unselected 268 | Then option "(.*?)" by text from radio button group having xpath "(.*?)" should be unselected 269 | Then option "(.*?)" by text from radio button group having css "(.*?)" should be unselected 270 | 271 | To assert that radio button group not selected by value use any of the following steps : 272 | 273 | Then option "(.*?)" by value from radio button group having id "(.*?)" should be unselected 274 | Then option "(.*?)" by value from radio button group having name "(.*?)" should be unselected 275 | Then option "(.*?)" by value from radio button group having class "(.*?)" should be unselected 276 | Then option "(.*?)" by value from radio button group having xpath "(.*?)" should be unselected 277 | Then option "(.*?)" by value from radio button group having css "(.*?)" should be unselected 278 | 279 | #### Steps For Asserting Links 280 | 281 | To assert that link is present use following steps : 282 | 283 | Then link having text "(.*?)" should be present 284 | Then link having partial text "(.*?)" should be present 285 | 286 | To assert that link is not present use following steps : 287 | 288 | Then link having text "(.*?)" should not be present 289 | Then link having partial text "(.*?)" should not be present 290 | 291 | #### Steps For Asserting Javascript Pop-Up Alert 292 | 293 | To assert text on javascipt pop-up alert use following step : 294 | 295 | Then I should see alert text as "(.*?)" 296 | 297 | #### Steps For Asserting Difference in images 298 | 299 | To assert difference in actual image and expected image (from remotely hosted) use following steps : 300 | 301 | Then actual image having id "(.*?)" and expected image having url "(.*?)" should be similar 302 | Then actual image having name "(.*?)" and expected image having url "(.*?)" should be similar 303 | Then actual image having class "(.*?)" and expected image having url "(.*?)" should be similar 304 | Then actual image having xpath "(.*?)" and expected image having url "(.*?)" should be similar 305 | Then actual image having css "(.*?)" and expected image having url "(.*?)" should be similar 306 | Then actual image having url "(.*?)" and expected image having url "(.*?)" should be similar 307 | 308 | To assert difference in actual image and expected image (from local machine) use following steps : 309 | 310 | Then actual image having id "(.*?)" and expected image having image_name "(.*?)" should be similar 311 | Then actual image having name "(.*?)" and expected image having image_name "(.*?)" should be similar 312 | Then actual image having class "(.*?)" and expected image having image_name "(.*?)" should be similar 313 | Then actual image having xpath "(.*?)" and expected image having image_name "(.*?)" should be similar 314 | Then actual image having css "(.*?)" and expected image having image_name "(.*?)" should be similar 315 | Then actual image having url "(.*?)" and expected image having image_name "(.*?)" should be similar 316 | 317 | To assert difference in actual image and expected image (from same webpage) use following steps : 318 | 319 | Then actual image having id "(.*?)" and expected image having id "(.*?)" should be similar 320 | Then actual image having name "(.*?)" and expected image having name "(.*?)" should be similar 321 | Then actual image having class "(.*?)" and expected image having class "(.*?)" should be similar 322 | Then actual image having xpath "(.*?)" and expected image having xpath "(.*?)" should be similar 323 | Then actual image having css "(.*?)" and expected image having css "(.*?)" should be similar 324 | Then actual image having url "(.*?)" and expected image having url "(.*?)" should be similar 325 | 326 | 327 | Input Steps 328 | ----------- 329 | 330 | #### Steps For TextFields 331 | 332 | To enter text into input field use following steps : 333 | 334 | Then I enter "([^\"]*)" into input field having id "([^\"]*)" 335 | Then I enter "([^\"]*)" into input field having name "([^\"]*)" 336 | Then I enter "([^\"]*)" into input field having class "([^\"]*)" 337 | Then I enter "([^\"]*)" into input field having xpath "([^\"]*)" 338 | Then I enter "([^\"]*)" into input field having css "([^\"]*)" 339 | 340 | To clear input field use following steps : 341 | 342 | Then I clear input field having id "([^\"]*)" 343 | Then I clear input field having name "([^\"]*)" 344 | Then I clear input field having class "([^\"]*)" 345 | Then I clear input field having xpath "([^\"]*)" 346 | Then I clear input field having css "([^\"]*)" 347 | 348 | #### Steps For Dropdown List 349 | 350 | To select option by text from dropdown use following steps : 351 | 352 | Then I select "(.*?)" option by text from dropdown having id "(.*?)" 353 | Then I select "(.*?)" option by text from dropdown having name "(.*?)" 354 | Then I select "(.*?)" option by text from dropdown having class "(.*?)" 355 | Then I select "(.*?)" option by text from dropdown having xpath "(.*?)" 356 | Then I select "(.*?)" option by text from dropdown having css "(.*?)" 357 | 358 | To select option by index from dropdown use following steps : 359 | 360 | Then I select (\d+) option by index from dropdown having id "(.*?)" 361 | Then I select (\d+) option by index from dropdown having name "(.*?)" 362 | Then I select (\d+) option by index from dropdown having class "(.*?)" 363 | Then I select (\d+) option by index from dropdown having xpath "(.*?)" 364 | Then I select (\d+) option by index from dropdown having css "(.*?)" 365 | 366 | To select option by value from dropdown use following steps : 367 | 368 | Then I select "(.*?)" option by value from dropdown having id "(.*?)" 369 | Then I select "(.*?)" option by value from dropdown having name "(.*?)" 370 | Then I select "(.*?)" option by value from dropdown having class "(.*?)" 371 | Then I select "(.*?)" option by value from dropdown having xpath "(.*?)" 372 | Then I select "(.*?)" option by value from dropdown having css "(.*?)" 373 | 374 | #### Steps For Multiselect List 375 | 376 | To select option by text from multiselect dropdown use following steps : 377 | 378 | Then I select "(.*?)" option by text from multiselect dropdown having id "(.*?)" 379 | Then I select "(.*?)" option by text from multiselect dropdown having name "(.*?)" 380 | Then I select "(.*?)" option by text from multiselect dropdown having class "(.*?)" 381 | Then I select "(.*?)" option by text from multiselect dropdown having xpath "(.*?)" 382 | Then I select "(.*?)" option by text from multiselect dropdown having css "(.*?)" 383 | 384 | To select option by index from multiselect dropdown use following steps : 385 | 386 | Then I select (\d+) option by index from multiselect dropdown having id "(.*?)" 387 | Then I select (\d+) option by index from multiselect dropdown having name "(.*?)" 388 | Then I select (\d+) option by index from multiselect dropdown having class "(.*?)" 389 | Then I select (\d+) option by index from multiselect dropdown having xpath "(.*?)" 390 | Then I select (\d+) option by index from multiselect dropdown having css "(.*?)" 391 | 392 | To select option by value from multiselect dropdown use following steps : 393 | 394 | Then I select "(.*?)" option by value from multiselect dropdown having id "(.*?)" 395 | Then I select "(.*?)" option by value from multiselect dropdown having name "(.*?)" 396 | Then I select "(.*?)" option by value from multiselect dropdown having class "(.*?)" 397 | Then I select "(.*?)" option by value from multiselect dropdown having xpath "(.*?)" 398 | Then I select "(.*?)" option by value from multiselect dropdown having css "(.*?)" 399 | 400 | To select all options from multiselect use following steps : 401 | 402 | Then I select all options from multiselect dropdown having id "(.*?)" 403 | Then I select all options from multiselect dropdown having name "(.*?)" 404 | Then I select all options from multiselect dropdown having class "(.*?)" 405 | Then I select all options from multiselect dropdown having xpath "(.*?)" 406 | Then I select all options from multiselect dropdown having css "(.*?)" 407 | 408 | To unselect all options from multiselect use following steps : 409 | 410 | Then I unselect all options from mutliselect dropdown having id "(.*?)" 411 | Then I unselect all options from mutliselect dropdown having name "(.*?)" 412 | Then I unselect all options from mutliselect dropdown having class "(.*?)" 413 | Then I unselect all options from mutliselect dropdown having xpath "(.*?)" 414 | Then I unselect all options from mutliselect dropdown having css "(.*?)" 415 | 416 | #### Steps For Checkboxes 417 | 418 | To check the checkbox use following steps : 419 | 420 | Then I check the checkbox having id "(.*?)" 421 | Then I check the checkbox having name "(.*?)" 422 | Then I check the checkbox having class "(.*?)" 423 | Then I check the checkbox having xpath "(.*?)" 424 | Then I check the checkbox having css "(.*?)" 425 | 426 | To uncheck the checkbox use following steps : 427 | 428 | Then I uncheck the checkbox having id "(.*?)" 429 | Then I uncheck the checkbox having name "(.*?)" 430 | Then I uncheck the checkbox having class "(.*?)" 431 | Then I uncheck the checkbox having xpath "(.*?)" 432 | Then I uncheck the checkbox having css "(.*?)" 433 | 434 | To toggle checkbox use following steps 435 | 436 | Then I toggle checkbox having id "(.*?)" 437 | Then I toggle checkbox having name "(.*?)" 438 | Then I toggle checkbox having class "(.*?)" 439 | Then I toggle checkbox having xpath "(.*?)" 440 | Then I toggle checkbox having css "(.*?)" 441 | 442 | #### Steps For Radio Buttons 443 | 444 | To select radio button use following steps : 445 | 446 | Then I select radio button having id "(.*?)" 447 | Then I select radio button having name "(.*?)" 448 | Then I select radio button having class "(.*?)" 449 | Then I select radio button having xpath "(.*?)" 450 | Then I select radio button having css "(.*?)" 451 | 452 | 453 | To select one radio button by text from radio button group use following steps : 454 | 455 | Then I select "(.*?)" option by text from radio button group having id "(.*?)" 456 | Then I select "(.*?)" option by text from radio button group having name "(.*?)" 457 | Then I select "(.*?)" option by text from radio button group having class "(.*?)" 458 | Then I select "(.*?)" option by text from radio button group having xpath "(.*?)" 459 | Then I select "(.*?)" option by text from radio button group having css "(.*?)" 460 | 461 | To select one radio button by value from radio button group use following steps : 462 | 463 | Then I select "(.*?)" option by value from radio button group having id "(.*?)" 464 | Then I select "(.*?)" option by value from radio button group having name "(.*?)" 465 | Then I select "(.*?)" option by value from radio button group having class "(.*?)" 466 | Then I select "(.*?)" option by value from radio button group having xpath "(.*?)" 467 | Then I select "(.*?)" option by value from radio button group having css "(.*?)" 468 | 469 | 470 | Click Steps 471 | ----------- 472 | To click on web element use following steps : 473 | 474 | Then I click on element having id "(.*?)" 475 | Then I click on element having name "(.*?)" 476 | Then I click on element having class "(.*?)" 477 | Then I click on element having xpath "(.*?)" 478 | Then I click on element having css "(.*?)" 479 | 480 | To click on web element with a particular text use the following steps : 481 | 482 | Then I click on element having id "(.*?)" and text "(.*?)" 483 | Then I click on element having name "(.*?)" and text "(.*?)" 484 | Then I click on element having class "(.*?)" and text "(.*?)" 485 | Then I click on element having xpath "(.*?)" and text "(.*?)" 486 | Then I click on element having css "(.*?)" and text "(.*?)" 487 | 488 | To forcefully click on web element use following steps (if above steps do not work) : 489 | 490 | Then I forcefully click on element having id "(.*?)" 491 | Then I forcefully click on element having name "(.*?)" 492 | Then I forcefully click on element having class "(.*?)" 493 | Then I forcefully click on element having xpath "(.*?)" 494 | Then I forcefully click on element having css "(.*?)" 495 | 496 | To double click on web element use following steps : 497 | 498 | Then I double click on element having id "(.*?)" 499 | Then I double click on element having name "(.*?)" 500 | Then I double click on element having class "(.*?)" 501 | Then I double click on element having xpath "(.*?)" 502 | Then I double click on element having css "(.*?)" 503 | 504 | To click on links use following steps : 505 | 506 | Then I click on link having text "(.*?)" 507 | Then I click on link having partial text "(.*?)" 508 | 509 | Progress Steps 510 | -------------- 511 | To wait for specific time use following step : 512 | 513 | Then I wait for (\d+) sec 514 | 515 | To wait for specific element to display use following steps : 516 | 517 | Then I wait (\d+) seconds for element having id "(.*?)" to display 518 | Then I wait (\d+) seconds for element having name "(.*?)" to display 519 | Then I wait (\d+) seconds for element having class "(.*?)" to display 520 | Then I wait (\d+) seconds for element having xpath "(.*?)" to display 521 | Then I wait (\d+) seconds for element having css "(.*?)" to display 522 | 523 | To wait for specific element to enable use following steps : 524 | 525 | Then I wait (\d+) seconds for element having id "(.*?)" to enable 526 | Then I wait (\d+) seconds for element having name "(.*?)" to enable 527 | Then I wait (\d+) seconds for element having class "(.*?)" to enable 528 | Then I wait (\d+) seconds for element having xpath "(.*?)" to enable 529 | Then I wait (\d+) seconds for element having css "(.*?)" to enable 530 | 531 | Javascript Handling Steps 532 | ------------------------- 533 | To handle javascript pop-up use following steps : 534 | 535 | Then I accept alert 536 | Then I dismiss alert 537 | 538 | 539 | Screenshot Steps 540 | ---------------- 541 | To take screenshot use following step : 542 | 543 | Then I take screenshot 544 | 545 | 546 | Configuration Steps 547 | ------------------- 548 | To print testing configuration use following step : 549 | 550 | Then I print configuration 551 | 552 | ## Mobile Steps 553 | 554 | 555 | ### Tap Steps 556 | ----------- 557 | To tap on app element use following steps : 558 | 559 | Then I tap on element having id "(.*?)" 560 | Then I tap on element having name "(.*?)" 561 | Then I tap on element having class "(.*?)" 562 | Then I tap on element having xpath "(.*?)" 563 | Then I tap on element having css "(.*?)" 564 | 565 | To Tap on back button of device use following step : 566 | 567 | Then I tap on back button of device 568 | Then I press back button of device 569 | 570 | ### Gesture Steps 571 | ------------ 572 | To perform gesture operations on device 573 | 574 | ### Swipe steps 575 | ------------ 576 | To perform swipe using app elements use following steps : 577 | 578 | Then I swipe from element having id "(.*?)" to element having id "(.*?)" 579 | Then I swipe from element having id "(.*?)" to element having name "(.*?)" 580 | Then I swipe from element having id "(.*?)" to element having class "(.*?)" 581 | Then I swipe from element having id "(.*?)" to element having xpath "(.*?)" 582 | 583 | Then I swipe from element having name "(.*?)" to element having id "(.*?)" 584 | Then I swipe from element having name "(.*?)" to element having name "(.*?)" 585 | Then I swipe from element having name "(.*?)" to element having class "(.*?)" 586 | Then I swipe from element having name "(.*?)" to element having xpath "(.*?)" 587 | 588 | Then I swipe from element having class "(.*?)" to element having id "(.*?)" 589 | Then I swipe from element having class "(.*?)" to element having name "(.*?)" 590 | Then I swipe from element having class "(.*?)" to element having class "(.*?)" 591 | Then I swipe from element having class "(.*?)" to element having xpath "(.*?)" 592 | 593 | Then I swipe from element having xpath "(.*?)" to element having id "(.*?)" 594 | Then I swipe from element having xpath "(.*?)" to element having name "(.*?)" 595 | Then I swipe from element having xpath "(.*?)" to element having class "(.*?)" 596 | Then I swipe from element having xpath "(.*?)" to element having xpath "(.*?)" 597 | 598 | To perform swipe using co-ordinates 599 | 600 | Then I swipe from co-ordinates "(.*?)","(.*?)" to co-ordinates "(.*?)","(.*?)" 601 | 602 | To perform swipe using direction 603 | 604 | Then I swipe right 605 | Then I swipe left 606 | Then I swipe up 607 | Then I swipe down 608 | 609 | To perform swipe using app element with direction use following steps : 610 | 611 | Then I swipe element having id "(.*?)" to right 612 | Then I swipe element having name "(.*?)" to right 613 | Then I swipe element having class "(.*?)" to right 614 | Then I swipe element having xpath "(.*?)" to right 615 | 616 | Then I swipe element having id "(.*?)" to left 617 | Then I swipe element having name "(.*?)" to left 618 | Then I swipe element having class "(.*?)" to left 619 | Then I swipe element having xpath "(.*?)" to left 620 | 621 | Then I swipe element having id "(.*?)" to up 622 | Then I swipe element having name "(.*?)" to up 623 | Then I swipe element having class "(.*?)" to up 624 | Then I swipe element having xpath "(.*?)" to up 625 | 626 | Then I swipe element having id "(.*?)" to down 627 | Then I swipe element having name "(.*?)" to down 628 | Then I swipe element having class "(.*?)" to down 629 | Then I swipe element having xpath "(.*?)" to down 630 | 631 | To perform swipe using co-ordinates with direction use following steps : 632 | 633 | Then I swipe co-ordinates "(.*?)","(.*?)" to left 634 | Then I swipe co-ordinates "(.*?)","(.*?)" to right 635 | Then I swipe co-ordinates "(.*?)","(.*?)" to up 636 | Then I swipe co-ordinates "(.*?)","(.*?)" to down 637 | 638 | 639 | ### long tap steps 640 | ------------ 641 | To perform long tap with default duration of 2 seconds on app elements use following steps : 642 | 643 | Then I long tap on element having id "(.*?)" 644 | Then I long tap on element having name "(.*?)" 645 | Then I long tap on element having class "(.*?)" 646 | Then I long tap on element having xpath "(.*?)" 647 | 648 | To perform long tap with customized duration of seconds on app elements use following steps : 649 | 650 | Then I long tap on element having id "(.*?)" for "(.*?)" sec 651 | Then I long tap on element having name "(.*?)" for "(.*?)" sec 652 | Then I long tap on element having class "(.*?)" for "(.*?)" sec 653 | Then I long tap on element having xpath "(.*?)" for "(.*?)" sec 654 | 655 | To perform long tap with default duration of 2 seconds using co-ordinates use following step : 656 | 657 | Then I long tap on co\-ordinate "(.*?)","(.*?) 658 | 659 | To perform long tap with customized duration of seconds using co-ordinates use following step : 660 | 661 | Then I long tap on co\-ordinate "(.*?)","(.*?)" for "(.*?)" sec 662 | 663 | ### Close app step 664 | 665 | Then I close app 666 | -------------------------------------------------------------------------------- /doc/installation.md: -------------------------------------------------------------------------------- 1 | Installation 2 | ============ 3 | ### Prerequisites 4 | You need to have Ruby installed. 5 | Verify your installation by running ruby -v in a terminal - it should print "ruby 1.9.3" (or higher). 6 | 7 | You need to have DevKit installed. 8 | 9 | You can get Ruby and DevKit from [RubyInstaller.org](http://rubyinstaller.org/) 10 | 11 | ### Installation 12 | 13 | Install `selenium-cucumber` gem by running 14 | 15 | - `gem install selenium-cucumber` 16 | 17 | -------------------------------------------------------------------------------- /doc/selenium-cucumber-API.md: -------------------------------------------------------------------------------- 1 | Selenium-Cucumber Ruby API's 2 | ============================ 3 | 4 | If you are writing code for your custom steps you can use the following methods : 5 | 6 | Note : For some of the API paramtere values are fixed. Such values for paramaters are mentioned below. 7 | 8 | Navigation API's 9 | ---------------- 10 | 11 | navigate_to("link") 12 | 13 | navigate(direction) # direction => "back" / "forward" 14 | 15 | close_driver() 16 | 17 | 18 | Browser Interaction API's 19 | ------------------------- 20 | 21 | resize_browser(width, height) 22 | 23 | scroll_page(to) # to => "top" / "end" 24 | 25 | scroll_to_element(by, access_value) 26 | 27 | zoom_in_out(in_out) # in_out => "add" / "subtract" 28 | 29 | zoom_in_out_till_element_display(by, in_out, access_value) # in_out => "add" / "subtract" 30 | 31 | 32 | Input API's 33 | ------------ 34 | 35 | click(by, access_value) 36 | 37 | double_click(access_type,access_value) 38 | 39 | click_forcefully(access_type, access_name) 40 | 41 | submit(by, access_value) 42 | 43 | enter_text(by, text, access_value) 44 | 45 | clear_text(by, access_value) 46 | 47 | check_checkbox(by, access_value) 48 | 49 | uncheck_checkbox(by, access_value) 50 | 51 | toggle_checkbox(by, access_value) 52 | 53 | select_radio_button(by, access_value) 54 | 55 | get_page_title() 56 | 57 | get_element_text(by, access_value) 58 | 59 | get_element_attribute(by, access_value, attribute) 60 | 61 | is_element_enabled(by, access_value) 62 | 63 | is_element_displayed(by, access_value) 64 | 65 | hover_over_element(by, access_value) 66 | 67 | by => "locators type" ("id", "name", "class", "xpath", "css") 68 | 69 | access_value => "locator value" 70 | 71 | 72 | Javascript Handling API 73 | ----------------------- 74 | 75 | handle_alert(decision) # decision => "accept" / "dismiss" 76 | 77 | get_alert_text 78 | 79 | 80 | Progress API's 81 | -------------- 82 | 83 | wait(time_in_sec) 84 | 85 | wait_for_element_to_display(by, access_value, duration) 86 | 87 | wait_for_element_to_enable(by, access_value, duration) 88 | 89 | 90 | by => "locators type" ("id", "name", "class", "xpath", "css") 91 | 92 | access_value => "locator value" 93 | 94 | duration => duration in seconds. 95 | 96 | 97 | Image Comparing API 98 | ------------------- 99 | 100 | does_images_similar?(actual_img_by, actual_img_access_value, excp_img_by, excp_img_access_value) 101 | 102 | 103 | actual_img_by => "element locators" ("id", "name", "class", "xpath", "css", "url") 104 | 105 | actual_img_access_value => "locator value" 106 | 107 | 108 | excp_img_by => "image location" ("id", "url", "image_name") 109 | 110 | excp_img_access_value => "value" 111 | 112 | 113 | Screenshot API 114 | -------------- 115 | take_screenshots 116 | 117 | 118 | Configuration API 119 | ----------------- 120 | 121 | print_congifugartion -------------------------------------------------------------------------------- /doc/selenium-cucumber-help.md: -------------------------------------------------------------------------------- 1 | 2 | Usage: selenium-cucumber [parameters] [options] 3 | 4 | can be one of 5 | help 6 | gen 7 | version 8 | 9 | Commands: 10 | help : prints more detailed help information. 11 | 12 | gen : creates a skeleton features dir. This is usually used once when 13 | setting up selenium-cucumber to ensure that the features folder contains 14 | the right step definitions and environment to run with cucumber. 15 | 16 | version : prints the gem version 17 | 18 | Options: -v, --verbose Turns on verbose logging 19 | -------------------------------------------------------------------------------- /example/android/android_app/HinduCalendar.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/selenium-cucumber/selenium-cucumber-ruby/2f43c469ca80a4f262dd4223760f90177f9cb77e/example/android/android_app/HinduCalendar.zip -------------------------------------------------------------------------------- /example/android/android_app/HinduCalendar/HinduCalendar.apk: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/selenium-cucumber/selenium-cucumber-ruby/2f43c469ca80a4f262dd4223760f90177f9cb77e/example/android/android_app/HinduCalendar/HinduCalendar.apk -------------------------------------------------------------------------------- /example/android/android_app/HinduCalendar/README.md: -------------------------------------------------------------------------------- 1 | To Run this project 2 | 3 | Pre-requisites : 4 | You must have selenium-cucumber and appium setup on your machine. 5 | If you dont have required setup please make it refering "http://seleniumcucumber.info/android/" and follow below steps. 6 | 7 | - Connect test device to your machine 8 | - Open Command prompt 9 | - Hit command "adb devices" to verify device is connected 10 | - Change current directory to this project (HinduCalendar) directory 11 | - Start appium server 12 | - To get output on console hit following command on console 13 | -- cucumber PLATFORM=android APP_PATH=HinduCalendar.apk 14 | - To get output in html file hit following command on console 15 | -- cucumber PLATFORM=android APP_PATH=HinduCalendar.apk -f html -o Results.html 16 | 17 | Note: 18 | This example is tested on nexus 5, Samsung S3,S4 so if you run this example on other devices you may get failure, as native date time picker is different on different devices. 19 | You can make changes in code to make it pass. -------------------------------------------------------------------------------- /example/android/android_app/HinduCalendar/features/01_HC_homepage_menu_validation.feature: -------------------------------------------------------------------------------- 1 | Feature: Verify homepage elements 2 | 3 | Scenario: As a tester I want to verify all 10 menus with name from home page 4 | Given I am on home page of Hindu Calender 5 | Then I should see Month View option 6 | Then I should see Panchang option 7 | Then I should see Kundli option 8 | Then I should see Jyotish option 9 | Then I should see Festivals option 10 | Then I should see My Tithi option 11 | Then I should see Settings option 12 | Then I should see Info option 13 | Then I should see About option 14 | Then I should see Feedback option 15 | 16 | Scenario: Verify Header menus 17 | Then I should see Hambergur menu 18 | Then I should see Swistik image 19 | Then I should see Hindu Calender text 20 | Then I should see Settings option image 21 | 22 | Scenario: Tap on Hambergur menu and verify options 23 | When I tap on Hambergur menu 24 | Then I should see left menu overlay 25 | Then I should see Month View option 26 | Then I should see Panchang option 27 | Then I should see Kundali option 28 | Then I should see Jyotish option 29 | Then I should see Festivals option 30 | Then I should see My Tithi option 31 | Then I should see Settings option 32 | Then I should see Info option 33 | When I tap on Hambergur menu again 34 | Then I should not see left menu overlay 35 | 36 | 37 | -------------------------------------------------------------------------------- /example/android/android_app/HinduCalendar/features/02_HC_homepage_menu_navigation.feature: -------------------------------------------------------------------------------- 1 | Feature: Menu Navigation From Homepage 2 | 3 | Scenario: Tap on Month View option and verify appropriat navigation 4 | When I tap on Month View option 5 | Then I should get redirected to Month View page 6 | And I should see Feativals and Events in this month text 7 | When I press back button of device 8 | Then I should get redirected to home page 9 | 10 | Scenario: Tap on Panchang option and verify appropriat navigation 11 | When I tap on Panchang option 12 | Then I should get redirected to Panchang page 13 | And I should see date 14 | When I press back button of device 15 | Then I should get redirected to home page 16 | 17 | Scenario: Tap on Kundli option and verify appropriat navigation 18 | When I tap on Kundli option 19 | Then I should get redirected to Kundali page 20 | And I should see Info text 21 | When I press back button of device 22 | Then I should get redirected to home page 23 | 24 | Scenario: Tap on Jyotish option and verify appropriat navigation 25 | When I tap on Jyotish option 26 | Then I should get redirected to Jyotish page 27 | And I should see Muhurt text 28 | When I press back button of device 29 | Then I should get redirected to home page 30 | 31 | Scenario: Tap on Festivals option and verify appropriat navigation 32 | When I tap on Festivals option 33 | Then I should get redirected to Festivals page 34 | And I should see Gudi Padwa text 35 | When I press back button of device 36 | Then I should get redirected to home page 37 | 38 | Scenario: Tap on My Tithi option and verify appropriat navigation 39 | When I tap on My Tithi option 40 | Then I should get redirected to My Tithi page 41 | And I should see Save My Tithi button 42 | When I press back button of device 43 | Then I should get redirected to home page 44 | 45 | Scenario: Tap on Settings option and verify appropriat navigation 46 | When I tap on Settings option 47 | Then I should get redirected to Settings page 48 | And I should see Save Settings button 49 | When I press back button of device 50 | Then I should get redirected to home page 51 | 52 | Scenario: Tap on Info option and verify appropriat navigation 53 | When I tap on Info option 54 | Then I should get redirected to Info page 55 | And I should see Hindu Calendar text on Info page 56 | When I press back button of device 57 | Then I should get redirected to home page 58 | 59 | Scenario: Tap on About option and verify appropriat navigation 60 | When I tap on About option 61 | Then I should get redirected to About Overlay 62 | And I should see Hindu Calendar text and OK button 63 | When I tap on OK button of Overlay 64 | Then I should get redirected to home page 65 | 66 | Scenario: Tap on Feedback option and verify appropriat navigation 67 | When I tap on Feedback option 68 | Then I should get redirected to Feedback Overlay 69 | And I should see Feedback text and OK button 70 | When I tap on OK button of Overlay 71 | Then I should get redirected to home page -------------------------------------------------------------------------------- /example/android/android_app/HinduCalendar/features/03_HC_Create_Save_View_Delete_Kundali.feature: -------------------------------------------------------------------------------- 1 | Feature: Create Kundali 2 | 3 | Scenario: Nvigation to kundali page 4 | When I tap on Kundli option 5 | Then I should get redirected to Kundali page 6 | 7 | Scenario: Enter Date 8 | When I tap on Date button 9 | Then I should see Date picker 10 | When I select Date as "20" "May" "2020" 11 | Then I should see Date button text as "20 May 2020" 12 | 13 | Scenario: Enter Time 14 | When I tap on Time button 15 | Then I should see Time picker 16 | When I enter Time as "08":"20" "PM" 17 | Then I should see Time button text as "20:20" 18 | 19 | Scenario: Tapping on more options arrow and Saving 20 | When I tap on more options arrow 21 | Then I should see Save Kundali option 22 | When I tap on Save Kundali option 23 | Then I should see Enter name overlay 24 | Then I enter name as "SeleniumCucumber" 25 | Then I tap on Ok button 26 | 27 | Scenario: Swap Kundali to see more information 28 | When I swipe to Kundali tab 29 | Then I should see Kundali 30 | When I swipe to Kundali(South. Ind.) 31 | Then I should see South. Ind. Kundali 32 | When I swipe to dasha 33 | Then I should see mahadasha details 34 | 35 | Scenario: Go to homepage and open created Kundali 36 | When I press back button of device 37 | Then I should get redirected to home page 38 | When I tap on Kundli option 39 | Then I should get redirected to Kundali page 40 | When I tap on more options arrow 41 | Then I should see Open Kundali option 42 | When I tap on Open Kundali option 43 | Then I should get Kundali overlay with SeleniumCucumber Kundali 44 | When I tap on SeleniumCucumber Kundali 45 | Then I should see SeleniumCucumber Kundali is open 46 | 47 | Scenario: Delete Kundali 48 | When I tap on Open Kundali option 49 | Then I should get Kundali overlay with SeleniumCucumber Kundali 50 | Then I should see text as "Long Press to Delete Kundali" 51 | When I Long tap on SeleniumCucumber Kundali 52 | 53 | Scenario: Confirm Delete 54 | Then I should get pop up with text "Remove Kundali?" 55 | When I tap on Ok button 56 | Then I should get redirected to Kundali page 57 | When I tap on Open Kundali option 58 | Then I should not see SeleniumCucumber Kundali under Open Kundali overlay 59 | When I press back button of device twice 60 | Then I should get redirected to home page 61 | 62 | Scenario: Close app 63 | Then I close app -------------------------------------------------------------------------------- /example/android/android_app/HinduCalendar/features/actual_images/test.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/selenium-cucumber/selenium-cucumber-ruby/2f43c469ca80a4f262dd4223760f90177f9cb77e/example/android/android_app/HinduCalendar/features/actual_images/test.png -------------------------------------------------------------------------------- /example/android/android_app/HinduCalendar/features/expected_images/test.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/selenium-cucumber/selenium-cucumber-ruby/2f43c469ca80a4f262dd4223760f90177f9cb77e/example/android/android_app/HinduCalendar/features/expected_images/test.png -------------------------------------------------------------------------------- /example/android/android_app/HinduCalendar/features/image_difference/test.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/selenium-cucumber/selenium-cucumber-ruby/2f43c469ca80a4f262dd4223760f90177f9cb77e/example/android/android_app/HinduCalendar/features/image_difference/test.png -------------------------------------------------------------------------------- /example/android/android_app/HinduCalendar/features/my_first.feature: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /example/android/android_app/HinduCalendar/features/screenshots/test.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/selenium-cucumber/selenium-cucumber-ruby/2f43c469ca80a4f262dd4223760f90177f9cb77e/example/android/android_app/HinduCalendar/features/screenshots/test.png -------------------------------------------------------------------------------- /example/android/android_app/HinduCalendar/features/step_definitions/01_HC_homepage_menu_validation.rb: -------------------------------------------------------------------------------- 1 | require 'selenium-cucumber' 2 | 3 | Given(/^I am on home page of Hindu Calender$/) do 4 | step %[element having id "android:id/action_bar_title" should have text as "Hindu Calendar"] 5 | end 6 | 7 | Then(/^I should see Month View option$/) do 8 | step %[element having xpath "//android.widget.TextView[@text='Month View']" should have text as "Month View"] 9 | end 10 | 11 | Then(/^I should see Panchang option$/) do 12 | step %[element having xpath "//android.widget.TextView[@text='Panchang']" should have text as "Panchang"] 13 | end 14 | 15 | Then(/^I should see Kundli option$/) do 16 | step %[element having xpath "//android.widget.TextView[@text='Kundli']" should have text as "Kundli"] 17 | end 18 | 19 | Then(/^I should see Jyotish option$/) do 20 | step %[element having xpath "//android.widget.TextView[@text='Jyotish']" should have text as "Jyotish"] 21 | end 22 | 23 | Then(/^I should see Festivals option$/) do 24 | step %[element having xpath "//android.widget.TextView[@text='Festivals']" should have text as "Festivals"] 25 | end 26 | 27 | Then(/^I should see My Tithi option$/) do 28 | step %[element having xpath "//android.widget.TextView[@text='My Tithi']" should have text as "My Tithi"] 29 | end 30 | 31 | Then(/^I should see Settings option$/) do 32 | step %[element having xpath "//android.widget.TextView[@text='Settings']" should have text as "Settings"] 33 | end 34 | 35 | Then(/^I should see Info option$/) do 36 | step %[element having xpath "//android.widget.TextView[@text='Info']" should have text as "Info"] 37 | end 38 | 39 | Then(/^I should see About option$/) do 40 | step %[element having xpath "//android.widget.TextView[@text='About']" should have text as "About"] 41 | end 42 | 43 | Then(/^I should see Feedback option$/) do 44 | step %[element having xpath "//android.widget.TextView[@text='Feedback']" should have text as "Feedback"] 45 | end 46 | 47 | Then(/^I should see Hambergur menu$/) do 48 | step %[element having id "android:id/up" should be present] 49 | end 50 | 51 | Then(/^I should see Swistik image$/) do 52 | step %[element having id "android:id/home" should be present] 53 | end 54 | 55 | Then(/^I should see Hindu Calender text$/) do 56 | step %[element having id "android:id/action_bar_title" should have text as "Hindu Calendar"] 57 | end 58 | 59 | Then(/^I should see Settings option image$/) do 60 | step %[element having id "com.alokmandavgane.hinducalendar:id/menu_settings" should be present] 61 | end 62 | 63 | When(/^I tap on Hambergur menu$/) do 64 | step %[I click on element having id "android:id/up"] 65 | end 66 | 67 | Then(/^I should see left menu overlay$/) do 68 | step %[element having id "com.alokmandavgane.hinducalendar:id/left_drawer" should be present] 69 | end 70 | 71 | Then(/^I should see Kundali option$/) do 72 | step %[element having xpath "//android.widget.TextView[@text='Kundali']" should have text as "Kundali"] 73 | end 74 | 75 | When(/^I tap on Hambergur menu again$/) do 76 | step %[I click on element having id "android:id/up"] 77 | end 78 | 79 | Then(/^I should not see left menu overlay$/) do 80 | step %[element having id "com.alokmandavgane.hinducalendar:id/left_drawer" should not be present] 81 | end -------------------------------------------------------------------------------- /example/android/android_app/HinduCalendar/features/step_definitions/02_HC_homepage_menu_navigation.rb: -------------------------------------------------------------------------------- 1 | require 'selenium-cucumber' 2 | 3 | When(/^I tap on Month View option$/) do 4 | step %[I click on element having xpath "//android.widget.TextView[@text='Month View']"] 5 | end 6 | 7 | Then(/^I should get redirected to Month View page$/) do 8 | step %[element having id "android:id/action_bar_title" should have text as "Month View"] 9 | end 10 | 11 | Then(/^I should see Feativals and Events in this month text$/) do 12 | step %[element having xpath "//android.widget.TextView[@index=4]" should have text as "Festivals and Events in this month"] 13 | end 14 | 15 | Then(/^I should get redirected to home page$/) do 16 | step %[I wait for 3 sec] 17 | step %[element having id "android:id/action_bar_title" should have text as "Hindu Calendar"] 18 | end 19 | 20 | When(/^I tap on Panchang option$/) do 21 | step %[I click on element having xpath "//android.widget.TextView[@text='Panchang']"] 22 | end 23 | 24 | Then(/^I should get redirected to Panchang page$/) do 25 | step %[element having id "android:id/action_bar_title" should have text as "Panchang"] 26 | end 27 | 28 | Then(/^I should see date$/) do 29 | step %[element having id "com.alokmandavgane.hinducalendar:id/date" should be present] 30 | end 31 | 32 | When(/^I tap on Kundli option$/) do 33 | step %[I click on element having xpath "//android.widget.TextView[@text='Kundli']"] 34 | end 35 | 36 | Then(/^I should get redirected to Kundali page$/) do 37 | step %[element having id "android:id/action_bar_title" should have text as "Kundali"] 38 | end 39 | 40 | Then(/^I should see Info text$/) do 41 | step %[element having xpath "//android.widget.TextView[@text='Info']" should have text as "Info"] 42 | end 43 | 44 | When(/^I tap on Jyotish option$/) do 45 | step %[I click on element having xpath "//android.widget.TextView[@text='Jyotish']"] 46 | end 47 | 48 | Then(/^I should get redirected to Jyotish page$/) do 49 | step %[element having id "android:id/action_bar_title" should have text as "Jyotish"] 50 | end 51 | 52 | Then(/^I should see Muhurt text$/) do 53 | step %[element having xpath "//android.widget.TextView[@text='Muhurt']" should have text as "Muhurt"] 54 | end 55 | 56 | When(/^I tap on Festivals option$/) do 57 | step %[I click on element having xpath "//android.widget.TextView[@text='Festivals']"] 58 | end 59 | 60 | Then(/^I should get redirected to Festivals page$/) do 61 | step %[element having id "android:id/action_bar_title" should have text as "Festivals"] 62 | end 63 | 64 | Then(/^I should see Gudi Padwa text$/) do 65 | step %[element having xpath "//android.widget.TextView[@text='Gudi Padwa']" should have text as "Gudi Padwa"] 66 | end 67 | 68 | When(/^I tap on My Tithi option$/) do 69 | step %[I click on element having xpath "//android.widget.TextView[@text='My Tithi']"] 70 | end 71 | 72 | Then(/^I should get redirected to My Tithi page$/) do 73 | step %[element having id "android:id/action_bar_title" should have text as "My Tithi"] 74 | end 75 | 76 | Then(/^I should see Save My Tithi button$/) do 77 | step %[element having id "com.alokmandavgane.hinducalendar:id/save_mytithi" should be present] 78 | end 79 | 80 | When(/^I tap on Settings option$/) do 81 | step %[I click on element having xpath "//android.widget.TextView[@text='Settings']"] 82 | end 83 | 84 | Then(/^I should get redirected to Settings page$/) do 85 | step %[element having id "android:id/action_bar_title" should have text as "Settings"] 86 | end 87 | 88 | Then(/^I should see Save Settings button$/) do 89 | step %[element having id "com.alokmandavgane.hinducalendar:id/save_settings1" should be present] 90 | end 91 | 92 | When(/^I tap on Info option$/) do 93 | step %[I click on element having xpath "//android.widget.TextView[@text='Info']"] 94 | end 95 | 96 | Then(/^I should get redirected to Info page$/) do 97 | step %[element having id "android:id/action_bar_title" should have text as "Info"] 98 | end 99 | 100 | Then(/^I should see Hindu Calendar text on Info page$/) do 101 | step %[element having xpath "//android.view.View[@content-desc='Hindu Calendar Heading']" should be present] 102 | end 103 | 104 | When(/^I tap on About option$/) do 105 | step %[I click on element having xpath "//android.widget.TextView[@text='About']"] 106 | end 107 | 108 | Then(/^I should get redirected to About Overlay$/) do 109 | step %[element having id "android:id/content" should be present] 110 | end 111 | 112 | Then(/^I should see Hindu Calendar text and OK button$/) do 113 | step %[element having id "android:id/alertTitle" should have text as "Hindu Calendar"] 114 | step %[element having id "android:id/button1" should be present] 115 | end 116 | 117 | When(/^I tap on OK button of Overlay$/) do 118 | step %[I click on element having id "android:id/button1"] 119 | end 120 | 121 | When(/^I tap on Feedback option$/) do 122 | step %[I click on element having xpath "//android.widget.TextView[@text='Feedback']"] 123 | end 124 | 125 | Then(/^I should get redirected to Feedback Overlay$/) do 126 | step %[element having id "android:id/content" should be present] 127 | end 128 | 129 | Then(/^I should see Feedback text and OK button$/) do 130 | step %[element having id "android:id/alertTitle" should have text as "Feedback"] 131 | step %[element having id "android:id/button1" should be present] 132 | end 133 | -------------------------------------------------------------------------------- /example/android/android_app/HinduCalendar/features/step_definitions/03_HC_Create_Save_View_Delete_Kundali.rb: -------------------------------------------------------------------------------- 1 | require 'selenium-cucumber' 2 | 3 | When(/^I tap on Date button$/) do 4 | step %[I click on element having id "com.alokmandavgane.hinducalendar:id/datePicker1"] 5 | end 6 | 7 | Then(/^I should see Date picker$/) do 8 | step %[element having id "android:id/content" should be present] 9 | end 10 | 11 | When(/^I select Date as "(.*?)" "(.*?)" "(.*?)"$/) do |date, month, year| 12 | set_date(date) 13 | set_month(month) 14 | set_year(year) 15 | end 16 | 17 | Then(/^I should see Date button text as "(.*?)"$/) do |date| 18 | step %[element having id "com.alokmandavgane.hinducalendar:id/datePicker1" should have text as "#{date}"] 19 | 20 | end 21 | 22 | When(/^I tap on Time button$/) do 23 | step %[I click on element having id "com.alokmandavgane.hinducalendar:id/timePicker1"] 24 | end 25 | 26 | Then(/^I should see Time picker$/) do 27 | step %[element having id "android:id/content" should be present] 28 | end 29 | 30 | When(/^I enter Time as "(.*?)":"(.*?)" "(.*?)"$/) do |hour, min, am_pm| 31 | set_min(min) 32 | set_hour(hour) 33 | set_am_pm(am_pm) 34 | end 35 | 36 | Then(/^I should see Time button text as "(.*?)"$/) do |time_text| 37 | step %[element having id "com.alokmandavgane.hinducalendar:id/timePicker1" should have text as "#{time_text}"] 38 | end 39 | 40 | When(/^I tap on more options arrow$/) do 41 | step %[I click on element having id "com.alokmandavgane.hinducalendar:id/more_options"] 42 | end 43 | 44 | Then(/^I should see Save Kundali option$/) do 45 | step %[element having id "com.alokmandavgane.hinducalendar:id/save_kundali" should be present] 46 | end 47 | 48 | When(/^I tap on Save Kundali option$/) do 49 | step %[I click on element having id "com.alokmandavgane.hinducalendar:id/save_kundali"] 50 | end 51 | 52 | Then(/^I should see Enter name overlay$/) do 53 | step %[element having id "android:id/content" should be present] 54 | end 55 | 56 | Then(/^I enter name as "(.*?)"$/) do |name| 57 | step %[I enter "#{name}" into input field having xpath "//android.widget.EditText[@index=0]"] 58 | end 59 | 60 | When(/^I tap on Ok button$/) do 61 | step %[I click on element having id "android:id/button1"] 62 | end 63 | 64 | Then(/^I should see Name on info page as "(.*?)"$/) do |arg1| 65 | step %[I wait for 3 sec] 66 | end 67 | 68 | When(/^I swipe to Kundali tab$/) do 69 | #step %[I swipe from element having xpath "//android.widget.TextView[@text='Info']" to element having xpath "//android.widget.TextView[@text='Kundali']"] 70 | #step %[I swipe from co-ordinates "1053","1325" to co-ordinates "24","1238"] 71 | step %[I swipe from element having xpath "//android.view.View[@index=1]" to element having xpath "//android.view.View[@index=0]"] 72 | #step %[I swipe from co-ordinates "800","630" to co-ordinates "24","695"] 73 | step %[I wait for 3 sec] 74 | end 75 | 76 | Then(/^I should see Kundali$/) do 77 | step %[element having xpath "//android.view.View[@index=2]" should be present] 78 | step %[I wait for 3 sec] 79 | end 80 | 81 | When(/^I swipe to Kundali\(South\. Ind\.\)$/) do 82 | 83 | step %[I swipe from co-ordinates "800","630" to co-ordinates "24","695"] 84 | end 85 | 86 | Then(/^I should see South\. Ind\. Kundali$/) do 87 | step %[element having xpath "//android.view.View[@index=2]" should be present] 88 | step %[I wait for 3 sec] 89 | end 90 | 91 | When(/^I swipe to dasha$/) do 92 | step %[I swipe from co-ordinates "800","630" to co-ordinates "24","695"] 93 | step %[I wait for 3 sec] 94 | end 95 | 96 | Then(/^I should see mahadasha details$/) do 97 | step %[element having xpath "//android.view.View[@index=0]" should be present] 98 | end 99 | 100 | Then(/^I should see Open Kundali option$/) do 101 | step %[element having id "com.alokmandavgane.hinducalendar:id/history_kundali" should be present] 102 | end 103 | 104 | When(/^I tap on Open Kundali option$/) do 105 | step %[I click on element having id "com.alokmandavgane.hinducalendar:id/history_kundali"] 106 | end 107 | 108 | Then(/^I should get Kundali overlay with SeleniumCucumber Kundali$/) do 109 | #step %[element having xpath "android.widget.FrameLayout[@index=0]" should be present] 110 | step %[element having id "com.alokmandavgane.hinducalendar:id/name" should have text as "SeleniumCucumber"] 111 | end 112 | 113 | When(/^I tap on SeleniumCucumber Kundali$/) do 114 | step %[I click on element having id "com.alokmandavgane.hinducalendar:id/name"] 115 | end 116 | 117 | Then(/^I should see text as "(.*?)"$/) do |longpress_delete| 118 | step %[element having id "com.alokmandavgane.hinducalendar:id/textView" should have text as "#{longpress_delete}"] 119 | end 120 | 121 | Then(/^I should see SeleniumCucumber Kundali is open$/) do 122 | step %[I should see Date button text as "20 May 2020"] 123 | end 124 | 125 | When(/^I Long tap on SeleniumCucumber Kundali$/) do 126 | step %[I long tap on element having id "com.alokmandavgane.hinducalendar:id/name" for "3" sec] 127 | end 128 | 129 | Then(/^I should get pop up with text "(.*?)"$/) do |message| 130 | step %[element having id "android:id/message" should have text as "#{message}"] 131 | end 132 | 133 | Then(/^I should not see SeleniumCucumber Kundali under Open Kundali overlay$/) do 134 | step %[element having id "com.alokmandavgane.hinducalendar:id/name" should not be present] 135 | end 136 | 137 | When(/^I press back button of device twice$/) do 138 | step %[I navigate back] 139 | step %[I navigate back] 140 | step %[I wait for 2 sec] 141 | end 142 | 143 | 144 | def set_date(date) 145 | date = date.to_i 146 | if $device_name != 'GOOGLE NEXUS 5' 147 | sleep 2 148 | ele_day = $driver.find_elements(:xpath, "//android.widget.EditText[@index=1]") 149 | #puts ele_day 150 | ele_day = ele_day[0] 151 | #puts ele_day 152 | if ele_day.text.to_i == date 153 | #puts "equal" 154 | else 155 | if ele_day.text.to_i < date 156 | begin 157 | increase_date_by_one 158 | end while ele_day.text.to_i != date 159 | else 160 | begin 161 | decrease_date_by_one 162 | end while ele_day.text.to_i != date 163 | end 164 | end 165 | else 166 | #puts "In NEXUS 5" 167 | ele_day = $driver.find_elements(:xpath, "//android.widget.EditText[@index=1]") 168 | #puts ele_day 169 | ele_day = ele_day[1] 170 | #puts ele_day 171 | #puts ele_day.text.to_i 172 | #puts date 173 | if ele_day.text.to_i == date 174 | #step %[I click on element having id "android:id/button1"] 175 | else 176 | if ele_day.text.to_i < date 177 | begin 178 | increase_date_by_one 179 | end while ele_day.text.to_i != date 180 | #step %[I click on element having id "android:id/button1"] 181 | else 182 | begin 183 | decrease_date_by_one 184 | end while ele_day.text.to_i != date 185 | #step %[I click on element having id "android:id/button1"] 186 | end 187 | end 188 | end 189 | end 190 | 191 | def set_month(month) 192 | if $device_name != 'GOOGLE NEXUS 5' 193 | ele_cur_month = $driver.find_elements(:xpath, "//android.widget.EditText[@index=1]") 194 | ele_cur_month = ele_cur_month[1] 195 | #puts ele_cur_month.text 196 | if ele_cur_month.text != "#{month}" 197 | begin 198 | increase_month_by_one 199 | end while ele_cur_month.text != "#{month}" 200 | end 201 | else 202 | ele_cur_month = $driver.find_elements(:xpath, "//android.widget.EditText[@index=1]") 203 | ele_cur_month = ele_cur_month[0] 204 | if ele_cur_month.text != "#{month}" 205 | begin 206 | increase_month_by_one 207 | end while ele_cur_month.text != "#{month}" 208 | end 209 | end 210 | end 211 | 212 | def set_hour(hour) 213 | #puts "in set_hour" 214 | hour = hour.to_i 215 | #puts hour 216 | cur_hour = $driver.find_elements(:xpath, "//android.widget.EditText[@index=1]") 217 | cur_hour = cur_hour[0] 218 | if cur_hour.text.to_i == hour 219 | puts "" 220 | else 221 | if cur_hour.text.to_i < hour 222 | begin 223 | increase_hour_by_one 224 | end while cur_hour.text.to_i != hour 225 | else 226 | begin 227 | decrease_hour_by_one 228 | end while cur_hour.text.to_i != hour 229 | end 230 | end 231 | end 232 | 233 | def set_min(min) 234 | #puts "in set_min" 235 | min = min.to_i 236 | #puts min 237 | cur_min = $driver.find_elements(:xpath, "//android.widget.EditText[@index=1]") 238 | cur_min = cur_min[1] 239 | if cur_min.text.to_i == min 240 | puts "" 241 | else 242 | if cur_min.text.to_i < min 243 | begin 244 | increase_min_by_one 245 | end while cur_min.text.to_i != min 246 | else 247 | begin 248 | decrease_min_by_one 249 | end while cur_min.text.to_i != min 250 | end 251 | end 252 | end 253 | 254 | def increase_date_by_one 255 | if $device_name != 'GOOGLE NEXUS 5' 256 | sleep 2 257 | ele_day = $driver.find_elements(:xpath, "//android.widget.Button[@index=2]") 258 | ele_day = ele_day[0] 259 | 260 | if ele_day.text == "01" 261 | ele_day.click 262 | ele_month = $driver.find_elements(:xpath, "//android.widget.Button[@index=2]") 263 | ele_month = ele_month[1] 264 | ele_month.click 265 | else 266 | ele_day.click 267 | end 268 | else 269 | ele_day = $driver.find_elements(:xpath, "//android.widget.Button[@index=2]") 270 | ele_day = ele_day[1] 271 | if ele_day.text == "01" 272 | ele_day.click 273 | ele_month = $driver.find_elements(:xpath, "//android.widget.Button[@index=2]") 274 | ele_month = ele_month[0] 275 | ele_month.click 276 | else 277 | ele_day.click 278 | end 279 | end 280 | end 281 | 282 | def decrease_date_by_one 283 | if $device_name != 'GOOGLE NEXUS 5' 284 | cur_date = $driver.find_elements(:xpath, "//android.widget.EditText[@index=1]") 285 | cur_date = cur_date[0] 286 | cur_date = cur_date.text 287 | if cur_date == "01" 288 | cur_month = $driver.find_elements(:xpath, "//android.widget.Button[@index=0]") 289 | cur_month = cur_month[1] 290 | cur_month.click 291 | dec_date = $driver.find_elements(:xpath, "//android.widget.Button[@index=0]") 292 | dec_date = dec_date[0] 293 | dec_date.click 294 | else 295 | dec_date = $driver.find_elements(:xpath, "//android.widget.Button[@index=0]") 296 | dec_date = dec_date[0] 297 | dec_date.click 298 | end 299 | else 300 | dec_date = $driver.find_elements(:xpath, "//android.widget.Button[@index=0]") 301 | dec_date = dec_date[1] 302 | cur_date = $driver.find_elements(:xpath, "//android.widget.EditText[@index=1]") 303 | cur_date = cur_date[1] 304 | cur_date = cur_date.text 305 | if cur_date == "01" 306 | cur_month = $driver.find_elements(:xpath, "//android.widget.Button[@index=0]") 307 | cur_month = cur_month[0] 308 | cur_month.click 309 | dec_date = $driver.find_elements(:xpath, "//android.widget.Button[@index=0]") 310 | dec_date = dec_date[1] 311 | dec_date.click 312 | else 313 | dec_date = $driver.find_elements(:xpath, "//android.widget.Button[@index=0]") 314 | dec_date = dec_date[1] 315 | dec_date.click 316 | end 317 | end 318 | end 319 | 320 | def increase_month_by_one 321 | if $device_name != 'GOOGLE NEXUS 5' 322 | sleep 2 323 | ele_month = $driver.find_elements(:xpath, "//android.widget.Button[@index=2]") 324 | ele_month = ele_month[1] 325 | ele_month.click 326 | else 327 | ele_month = $driver.find_elements(:xpath, "//android.widget.Button[@index=2]") 328 | ele_month = ele_month[0] 329 | ele_month.click 330 | end 331 | end 332 | 333 | def increase_year_by_one 334 | ele_year = $driver.find_elements(:xpath, "//android.widget.Button[@index=2]") 335 | ele_year = ele_year[2] 336 | ele_year.click 337 | end 338 | 339 | def decrease_year_by_one 340 | ele_year = $driver.find_elements(:xpath, "//android.widget.Button[@index=0]") 341 | ele_year = ele_year[2] 342 | ele_year.click 343 | end 344 | 345 | def set_year(year) 346 | year = year.to_i 347 | ele_year = $driver.find_elements(:xpath, "//android.widget.EditText[@index=1]") 348 | ele_year = ele_year[2] 349 | #puts ele_year 350 | if ele_year.text.to_i == year 351 | #puts "equal" 352 | step %[I click on element having id "android:id/button1"] 353 | else 354 | if ele_year.text.to_i < year 355 | begin 356 | increase_year_by_one 357 | end while ele_year.text.to_i != year 358 | step %[I click on element having id "android:id/button1"] 359 | else 360 | begin 361 | decrease_year_by_one 362 | end while ele_year.text.to_i != year 363 | step %[I click on element having id "android:id/button1"] 364 | end 365 | end 366 | end 367 | 368 | def increase_hour_by_one 369 | ele_hour = $driver.find_elements(:xpath, "//android.widget.Button[@index=2]") 370 | ele_hour = ele_hour[0] 371 | ele_hour.click 372 | end 373 | 374 | def decrease_hour_by_one 375 | ele_hour = $driver.find_elements(:xpath, "//android.widget.Button[@index=0]") 376 | ele_hour = ele_hour[0] 377 | ele_hour.click 378 | end 379 | 380 | def increase_min_by_one 381 | ele_min = $driver.find_elements(:xpath, "//android.widget.Button[@index=2]") 382 | ele_min = ele_min[1] 383 | ele_min.click 384 | end 385 | 386 | def decrease_min_by_one 387 | ele_min = $driver.find_elements(:xpath, "//android.widget.Button[@index=0]") 388 | ele_min = ele_min[1] 389 | ele_min.click 390 | end 391 | 392 | def set_am_pm(am_pm) 393 | #puts "In AM+PM" 394 | if am_pm == 'AM' 395 | begin 396 | $driver.find_element(:xpath, "//android.widget.EditText[@text='AM']").displayed? 397 | step %[I click on element having id "android:id/button1"] 398 | rescue 399 | $driver.find_element(:xpath, "//android.widget.Button[@index=0]").click 400 | step %[I click on element having id "android:id/button1"] 401 | end 402 | else 403 | begin 404 | $driver.find_element(:xpath, "//android.widget.EditText[@text='PM']").displayed? 405 | step %[I click on element having id "android:id/button1"] 406 | rescue 407 | $driver.find_element(:xpath, "//android.widget.Button[@index=1]").click 408 | step %[I click on element having id "android:id/button1"] 409 | end 410 | end 411 | end 412 | 413 | 414 | -------------------------------------------------------------------------------- /example/android/android_app/HinduCalendar/features/step_definitions/custom_steps.rb: -------------------------------------------------------------------------------- 1 | require 'selenium-cucumber' 2 | 3 | # Do Not Remove This File 4 | # Add your custom steps here 5 | # $driver is instance of webdriver use this instance to write your custom code -------------------------------------------------------------------------------- /example/android/android_app/HinduCalendar/features/support/env.rb: -------------------------------------------------------------------------------- 1 | require 'rubygems' 2 | require 'selenium-cucumber' 3 | 4 | # Store command line arguments 5 | $browser_type = ENV['BROWSER'] || 'ff' 6 | $platform = ENV['PLATFORM'] || 'desktop' 7 | $os_version = ENV['OS_VERSION'] 8 | $device_name = ENV['DEVICE_NAME'] 9 | $udid = ENV['UDID'] 10 | $app_path = ENV['APP_PATH'] 11 | 12 | # check for valid parameters 13 | validate_parameters $platform, $browser_type, $app_path 14 | 15 | # If platform is android or ios create driver instance for mobile browser 16 | if $platform == 'android' or $platform == 'iOS' 17 | 18 | if $browser_type == 'native' 19 | $browser_type = "Browser" 20 | end 21 | 22 | if $platform == 'android' 23 | $device_name, $os_version = get_device_info 24 | end 25 | 26 | desired_caps = { 27 | caps: { 28 | platformName: $platform, 29 | browserName: $browser_type, 30 | versionNumber: $os_version, 31 | deviceName: $device_name, 32 | udid: $udid, 33 | app: ".//#{$app_path}" 34 | }, 35 | } 36 | 37 | begin 38 | $driver = Appium::Driver.new(desired_caps).start_driver 39 | rescue Exception => e 40 | puts e.message 41 | Process.exit(0) 42 | end 43 | else # else create driver instance for desktop browser 44 | begin 45 | $driver = Selenium::WebDriver.for(:"#{$browser_type}") 46 | $driver.manage().window().maximize() 47 | rescue Exception => e 48 | puts e.message 49 | Process.exit(0) 50 | end 51 | end 52 | -------------------------------------------------------------------------------- /example/android/android_app/HinduCalendar/features/support/hooks.rb: -------------------------------------------------------------------------------- 1 | #Cucumber provides a number of hooks which allow us to run blocks at various points in the Cucumber test cycle 2 | 3 | Before do 4 | # Do something before each scenario. 5 | end 6 | 7 | Before do |scenario| 8 | # The +scenario+ argument is optional, but if you use it, you can get the title, 9 | # description, or name (title + description) of the scenario that is about to be 10 | # executed. 11 | end 12 | 13 | After do 14 | # Do something after each scenario. 15 | end 16 | 17 | After do |scenario| 18 | # Do something after each scenario. 19 | # The +scenario+ argument is optional, but 20 | # if you use it, you can inspect status with 21 | # the #failed?, #passed? and #exception methods. 22 | 23 | if(scenario.failed?) 24 | #Do something if scenario fails. 25 | end 26 | end 27 | 28 | #Tagged hooks 29 | 30 | Before('@Ex_tag1, @Ex_tag2') do 31 | # This will only run before scenarios tagged 32 | # with @cucumis OR @sativus. 33 | end 34 | 35 | AfterStep('@Ex_tag1, @Ex_tag2') do 36 | # This will only run after steps within scenarios tagged 37 | # with @cucumis AND @sativus. 38 | end -------------------------------------------------------------------------------- /example/android/android_app/android_app_calculator.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/selenium-cucumber/selenium-cucumber-ruby/2f43c469ca80a4f262dd4223760f90177f9cb77e/example/android/android_app/android_app_calculator.zip -------------------------------------------------------------------------------- /example/android/android_app/android_app_calculator/AndroidCalculator.apk: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/selenium-cucumber/selenium-cucumber-ruby/2f43c469ca80a4f262dd4223760f90177f9cb77e/example/android/android_app/android_app_calculator/AndroidCalculator.apk -------------------------------------------------------------------------------- /example/android/android_app/android_app_calculator/features/actual_images/test.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/selenium-cucumber/selenium-cucumber-ruby/2f43c469ca80a4f262dd4223760f90177f9cb77e/example/android/android_app/android_app_calculator/features/actual_images/test.png -------------------------------------------------------------------------------- /example/android/android_app/android_app_calculator/features/calculator.feature: -------------------------------------------------------------------------------- 1 | Feature: Verify Calculator functionalities 2 | 3 | Scenario: Click on OK button 4 | Then I click on element having id "com.android2.calculator3:id/cling_dismiss" 5 | 6 | Scenario: Addirion 7 | Then I click on element having id "com.android2.calculator3:id/digit5" 8 | Then I click on element having id "com.android2.calculator3:id/plus" 9 | Then I click on element having id "com.android2.calculator3:id/digit9" 10 | When I click on element having id "com.android2.calculator3:id/equal" 11 | Then element having xpath "//android.widget.EditText[@index=0]" should have text as "14" 12 | 13 | 14 | Scenario: Substraction 15 | Then I click on element having id "com.android2.calculator3:id/digit9" 16 | Then I click on element having id "com.android2.calculator3:id/minus" 17 | Then I click on element having id "com.android2.calculator3:id/digit5" 18 | When I click on element having id "com.android2.calculator3:id/equal" 19 | Then element having xpath "//android.widget.EditText[@index=0]" should have text as "4" 20 | 21 | Scenario: Multiplication 22 | Then I click on element having id "com.android2.calculator3:id/digit9" 23 | Then I click on element having id "com.android2.calculator3:id/mul" 24 | Then I click on element having id "com.android2.calculator3:id/digit5" 25 | When I click on element having id "com.android2.calculator3:id/equal" 26 | Then element having xpath "//android.widget.EditText[@index=0]" should have text as "45" 27 | 28 | Scenario: Division 29 | Then I click on element having id "com.android2.calculator3:id/digit8" 30 | Then I click on element having id "com.android2.calculator3:id/div" 31 | Then I click on element having id "com.android2.calculator3:id/digit2" 32 | When I click on element having id "com.android2.calculator3:id/equal" 33 | Then element having xpath "//android.widget.EditText[@index=0]" should have text as "4" 34 | 35 | Scenario: Clear output 36 | Then I click on element having id "com.android2.calculator3:id/clear" -------------------------------------------------------------------------------- /example/android/android_app/android_app_calculator/features/expected_images/test.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/selenium-cucumber/selenium-cucumber-ruby/2f43c469ca80a4f262dd4223760f90177f9cb77e/example/android/android_app/android_app_calculator/features/expected_images/test.png -------------------------------------------------------------------------------- /example/android/android_app/android_app_calculator/features/image_difference/test.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/selenium-cucumber/selenium-cucumber-ruby/2f43c469ca80a4f262dd4223760f90177f9cb77e/example/android/android_app/android_app_calculator/features/image_difference/test.png -------------------------------------------------------------------------------- /example/android/android_app/android_app_calculator/features/my_first.feature: -------------------------------------------------------------------------------- 1 | #Scenario: Division 2 | # Then I click on element having id "com.android2.calculator3:id/digit8" 3 | # Then I click on element having id "com.android2.calculator3:id/div" 4 | # Then I click on element having id "com.android2.calculator3:id/digit4" 5 | # When I click on element having id "com.android2.calculator3:id/equal" 6 | # Then element having xpath "//android.widget.EditText[@index=0]" should have text as "2" 7 | 8 | # Scenario: Multiplication 9 | # Then I click on element having id "com.android2.calculator3:id/digit6" 10 | # Then I click on element having id "com.android2.calculator3:id/mul" 11 | # Then I click on element having id "com.android2.calculator3:id/digit5" 12 | # When I click on element having id "com.android2.calculator3:id/equal" 13 | # Then element having xpath "//android.widget.EditText[@index=0]" should have text as "30" -------------------------------------------------------------------------------- /example/android/android_app/android_app_calculator/features/screenshots/test.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/selenium-cucumber/selenium-cucumber-ruby/2f43c469ca80a4f262dd4223760f90177f9cb77e/example/android/android_app/android_app_calculator/features/screenshots/test.png -------------------------------------------------------------------------------- /example/android/android_app/android_app_calculator/features/step_definitions/custom_steps.rb: -------------------------------------------------------------------------------- 1 | require 'selenium-cucumber' 2 | 3 | # Do Not Remove This File 4 | # Add your custom steps here 5 | # $driver is instance of webdriver use this instance to write your custom code -------------------------------------------------------------------------------- /example/android/android_app/android_app_calculator/features/support/env.rb: -------------------------------------------------------------------------------- 1 | require 'rubygems' 2 | require 'selenium-cucumber' 3 | 4 | # Store command line arguments 5 | $browser_type = ENV['BROWSER'] || 'ff' 6 | $platform = ENV['PLATFORM'] || 'desktop' 7 | $os_version = ENV['OS_VERSION'] 8 | $device_name = ENV['DEVICE_NAME'] 9 | $udid = ENV['UDID'] 10 | $app_path = ENV['APP_PATH'] 11 | 12 | # check for valid parameters 13 | validate_parameters $platform, $browser_type, $app_path 14 | 15 | # If platform is android or ios create driver instance for mobile browser 16 | if $platform == 'android' or $platform == 'iOS' 17 | 18 | if $browser_type == 'native' 19 | $browser_type = "Browser" 20 | end 21 | 22 | if $platform == 'android' 23 | $device_name, $os_version = get_device_info 24 | end 25 | 26 | desired_caps = { 27 | caps: { 28 | platformName: $platform, 29 | browserName: $browser_type, 30 | versionNumber: $os_version, 31 | deviceName: $device_name, 32 | udid: $udid, 33 | app: ".//#{$app_path}" 34 | }, 35 | } 36 | 37 | begin 38 | $driver = Appium::Driver.new(desired_caps).start_driver 39 | rescue Exception => e 40 | puts e.message 41 | Process.exit(0) 42 | end 43 | else # else create driver instance for desktop browser 44 | begin 45 | $driver = Selenium::WebDriver.for(:"#{$browser_type}") 46 | $driver.manage().window().maximize() 47 | rescue Exception => e 48 | puts e.message 49 | Process.exit(0) 50 | end 51 | end 52 | -------------------------------------------------------------------------------- /example/android/android_app/android_app_calculator/features/support/hooks.rb: -------------------------------------------------------------------------------- 1 | #Cucumber provides a number of hooks which allow us to run blocks at various points in the Cucumber test cycle 2 | 3 | Before do 4 | # Do something before each scenario. 5 | end 6 | 7 | Before do |scenario| 8 | # The +scenario+ argument is optional, but if you use it, you can get the title, 9 | # description, or name (title + description) of the scenario that is about to be 10 | # executed. 11 | end 12 | 13 | After do 14 | # Do something after each scenario. 15 | end 16 | 17 | After do |scenario| 18 | # Do something after each scenario. 19 | # The +scenario+ argument is optional, but 20 | # if you use it, you can inspect status with 21 | # the #failed?, #passed? and #exception methods. 22 | 23 | if(scenario.failed?) 24 | #Do something if scenario fails. 25 | end 26 | end 27 | 28 | #Tagged hooks 29 | 30 | Before('@Ex_tag1, @Ex_tag2') do 31 | # This will only run before scenarios tagged 32 | # with @cucumis OR @sativus. 33 | end 34 | 35 | AfterStep('@Ex_tag1, @Ex_tag2') do 36 | # This will only run after steps within scenarios tagged 37 | # with @cucumis AND @sativus. 38 | end -------------------------------------------------------------------------------- /example/android/android_web/android_web_gmail_login.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/selenium-cucumber/selenium-cucumber-ruby/2f43c469ca80a4f262dd4223760f90177f9cb77e/example/android/android_web/android_web_gmail_login.zip -------------------------------------------------------------------------------- /example/android/android_web/android_web_gmail_login/features/actual_images/test.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/selenium-cucumber/selenium-cucumber-ruby/2f43c469ca80a4f262dd4223760f90177f9cb77e/example/android/android_web/android_web_gmail_login/features/actual_images/test.png -------------------------------------------------------------------------------- /example/android/android_web/android_web_gmail_login/features/expected_images/test.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/selenium-cucumber/selenium-cucumber-ruby/2f43c469ca80a4f262dd4223760f90177f9cb77e/example/android/android_web/android_web_gmail_login/features/expected_images/test.png -------------------------------------------------------------------------------- /example/android/android_web/android_web_gmail_login/features/gmail_login.feature: -------------------------------------------------------------------------------- 1 | Feature: Gmail Login mobile web 2 | 3 | Scenario: valid credentials login 4 | Given I navigate to "http://www.gmail.com" 5 | Then I wait for 5 sec 6 | Then I enter "your_email" into input field having id "Email" 7 | Then I enter "your_password" into input field having id "Passwd" 8 | When I click on element having id "signIn" 9 | And I wait for 10 sec 10 | Then element having xpath "//*[@id='tltbt']/div[3]/div/div" should be present 11 | And I wait for 5 sec 12 | Then I close browser 13 | -------------------------------------------------------------------------------- /example/android/android_web/android_web_gmail_login/features/image_difference/test.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/selenium-cucumber/selenium-cucumber-ruby/2f43c469ca80a4f262dd4223760f90177f9cb77e/example/android/android_web/android_web_gmail_login/features/image_difference/test.png -------------------------------------------------------------------------------- /example/android/android_web/android_web_gmail_login/features/my_first.feature: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /example/android/android_web/android_web_gmail_login/features/screenshots/test.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/selenium-cucumber/selenium-cucumber-ruby/2f43c469ca80a4f262dd4223760f90177f9cb77e/example/android/android_web/android_web_gmail_login/features/screenshots/test.png -------------------------------------------------------------------------------- /example/android/android_web/android_web_gmail_login/features/step_definitions/custom_steps.rb: -------------------------------------------------------------------------------- 1 | require 'selenium-cucumber' 2 | 3 | # Do Not Remove This File 4 | # Add your custom steps here 5 | # $driver is instance of webdriver use this instance to write your custom code -------------------------------------------------------------------------------- /example/android/android_web/android_web_gmail_login/features/support/env.rb: -------------------------------------------------------------------------------- 1 | require 'rubygems' 2 | require 'selenium-cucumber' 3 | 4 | # Store command line arguments 5 | $browser_type = ENV['BROWSER'] || 'ff' 6 | $platform = ENV['PLATFORM'] || 'desktop' 7 | $os_version = ENV['OS_VERSION'] 8 | $device_name = ENV['DEVICE_NAME'] 9 | $udid = ENV['UDID'] 10 | $app_path = ENV['APP_PATH'] 11 | 12 | # check for valid parameters 13 | validate_parameters $platform, $browser_type, $app_path 14 | 15 | # If platform is android or ios create driver instance for mobile browser 16 | if $platform == 'android' or $platform == 'iOS' 17 | 18 | if $browser_type == 'native' 19 | $browser_type = "Browser" 20 | end 21 | 22 | if $platform == 'android' 23 | $device_name, $os_version = get_device_info 24 | end 25 | 26 | desired_caps = { 27 | caps: { 28 | platformName: $platform, 29 | browserName: $browser_type, 30 | versionNumber: $os_version, 31 | deviceName: $device_name, 32 | udid: $udid, 33 | app: ".//#{$app_path}" 34 | }, 35 | } 36 | 37 | begin 38 | $driver = Appium::Driver.new(desired_caps).start_driver 39 | rescue Exception => e 40 | puts e.message 41 | Process.exit(0) 42 | end 43 | else # else create driver instance for desktop browser 44 | begin 45 | $driver = Selenium::WebDriver.for(:"#{$browser_type}") 46 | $driver.manage().window().maximize() 47 | rescue Exception => e 48 | puts e.message 49 | Process.exit(0) 50 | end 51 | end 52 | -------------------------------------------------------------------------------- /example/android/android_web/android_web_gmail_login/features/support/hooks.rb: -------------------------------------------------------------------------------- 1 | #Cucumber provides a number of hooks which allow us to run blocks at various points in the Cucumber test cycle 2 | 3 | Before do 4 | # Do something before each scenario. 5 | end 6 | 7 | Before do |scenario| 8 | # The +scenario+ argument is optional, but if you use it, you can get the title, 9 | # description, or name (title + description) of the scenario that is about to be 10 | # executed. 11 | end 12 | 13 | After do 14 | # Do something after each scenario. 15 | end 16 | 17 | After do |scenario| 18 | # Do something after each scenario. 19 | # The +scenario+ argument is optional, but 20 | # if you use it, you can inspect status with 21 | # the #failed?, #passed? and #exception methods. 22 | 23 | if(scenario.failed?) 24 | #Do something if scenario fails. 25 | end 26 | end 27 | 28 | #Tagged hooks 29 | 30 | Before('@Ex_tag1, @Ex_tag2') do 31 | # This will only run before scenarios tagged 32 | # with @cucumis OR @sativus. 33 | end 34 | 35 | AfterStep('@Ex_tag1, @Ex_tag2') do 36 | # This will only run after steps within scenarios tagged 37 | # with @cucumis AND @sativus. 38 | end -------------------------------------------------------------------------------- /example/desktop web/desktop_web_gmail_login.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/selenium-cucumber/selenium-cucumber-ruby/2f43c469ca80a4f262dd4223760f90177f9cb77e/example/desktop web/desktop_web_gmail_login.zip -------------------------------------------------------------------------------- /example/desktop web/desktop_web_gmail_login/features/actual_images/test.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/selenium-cucumber/selenium-cucumber-ruby/2f43c469ca80a4f262dd4223760f90177f9cb77e/example/desktop web/desktop_web_gmail_login/features/actual_images/test.png -------------------------------------------------------------------------------- /example/desktop web/desktop_web_gmail_login/features/expected_images/test.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/selenium-cucumber/selenium-cucumber-ruby/2f43c469ca80a4f262dd4223760f90177f9cb77e/example/desktop web/desktop_web_gmail_login/features/expected_images/test.png -------------------------------------------------------------------------------- /example/desktop web/desktop_web_gmail_login/features/gmail_login.feature: -------------------------------------------------------------------------------- 1 | Feature: Gmail_login 2 | 3 | Scenario: Valid_gmail_login 4 | Given I navigate to "http://www.gmail.com" 5 | And I enter "test@gmail.com" into input field having id "Email" 6 | Then I click on element having id "next" 7 | And I enter "!password*" into input field having id "Passwd" 8 | When I click on element having id "signIn" 9 | And I wait for 10 sec 10 | Then I close browser 11 | -------------------------------------------------------------------------------- /example/desktop web/desktop_web_gmail_login/features/gmail_multi_login.feature: -------------------------------------------------------------------------------- 1 | Feature: Gmail_login 2 | 3 | Scenario: Open gmail 4 | Given I navigate to "http://www.gmail.com" 5 | 6 | Scenario Outline: In-valid Login 7 | Then I clear input field having id "Email" 8 | And I enter into input field having id "Email" 9 | Then I click on element having id "next" 10 | Then I clear input field having id "Passwd" 11 | And I enter into input field having id "Passwd" 12 | When I click on element having id "signIn" 13 | Then element having id "errormsg_0_Passwd" should be present 14 | 15 | Examples: 16 | | username | password | 17 | |"test1" |"password1" | 18 | |"test2" |"password2" | 19 | |"test3" |"password3" | 20 | 21 | Scenario: close gmail 22 | Then I close browser 23 | -------------------------------------------------------------------------------- /example/desktop web/desktop_web_gmail_login/features/image_difference/test.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/selenium-cucumber/selenium-cucumber-ruby/2f43c469ca80a4f262dd4223760f90177f9cb77e/example/desktop web/desktop_web_gmail_login/features/image_difference/test.png -------------------------------------------------------------------------------- /example/desktop web/desktop_web_gmail_login/features/my_first.feature: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /example/desktop web/desktop_web_gmail_login/features/screenshots/test.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/selenium-cucumber/selenium-cucumber-ruby/2f43c469ca80a4f262dd4223760f90177f9cb77e/example/desktop web/desktop_web_gmail_login/features/screenshots/test.png -------------------------------------------------------------------------------- /example/desktop web/desktop_web_gmail_login/features/step_definitions/custom_steps.rb: -------------------------------------------------------------------------------- 1 | require 'selenium-cucumber' 2 | 3 | # Do Not Remove This File 4 | # Add your custom steps here 5 | # $driver is instance of webdriver use this instance to write your custom code -------------------------------------------------------------------------------- /example/desktop web/desktop_web_gmail_login/features/support/env.rb: -------------------------------------------------------------------------------- 1 | require 'rubygems' 2 | require 'selenium-cucumber' 3 | 4 | # Store command line arguments 5 | $browser_type = ENV['BROWSER'] || 'ff' 6 | $platform = ENV['PLATFORM'] || 'desktop' 7 | $os_version = ENV['OS_VERSION'] 8 | $device_name = ENV['DEVICE_NAME'] 9 | $udid = ENV['UDID'] 10 | $app_path = ENV['APP_PATH'] 11 | 12 | # check for valid parameters 13 | validate_parameters $platform, $browser_type, $app_path 14 | 15 | # If platform is android or ios create driver instance for mobile browser 16 | if $platform == 'android' or $platform == 'iOS' 17 | 18 | if $browser_type == 'native' 19 | $browser_type = "Browser" 20 | end 21 | 22 | if $platform == 'android' 23 | $device_name, $os_version = get_device_info 24 | end 25 | 26 | desired_caps = { 27 | caps: { 28 | platformName: $platform, 29 | browserName: $browser_type, 30 | versionNumber: $os_version, 31 | deviceName: $device_name, 32 | udid: $udid, 33 | app: ".//#{$app_path}" 34 | }, 35 | } 36 | 37 | begin 38 | $driver = Appium::Driver.new(desired_caps).start_driver 39 | rescue Exception => e 40 | puts e.message 41 | Process.exit(0) 42 | end 43 | else # else create driver instance for desktop browser 44 | begin 45 | $driver = Selenium::WebDriver.for(:"#{$browser_type}") 46 | $driver.manage().window().maximize() 47 | rescue Exception => e 48 | puts e.message 49 | Process.exit(0) 50 | end 51 | end 52 | -------------------------------------------------------------------------------- /example/desktop web/desktop_web_gmail_login/features/support/hooks.rb: -------------------------------------------------------------------------------- 1 | #Cucumber provides a number of hooks which allow us to run blocks at various points in the Cucumber test cycle 2 | 3 | Before do 4 | # Do something before each scenario. 5 | end 6 | 7 | Before do |scenario| 8 | # The +scenario+ argument is optional, but if you use it, you can get the title, 9 | # description, or name (title + description) of the scenario that is about to be 10 | # executed. 11 | end 12 | 13 | After do 14 | # Do something after each scenario. 15 | end 16 | 17 | After do |scenario| 18 | # Do something after each scenario. 19 | # The +scenario+ argument is optional, but 20 | # if you use it, you can inspect status with 21 | # the #failed?, #passed? and #exception methods. 22 | 23 | if(scenario.failed?) 24 | #Do something if scenario fails. 25 | end 26 | end 27 | 28 | #Tagged hooks 29 | 30 | Before('@Ex_tag1, @Ex_tag2') do 31 | # This will only run before scenarios tagged 32 | # with @cucumis OR @sativus. 33 | end 34 | 35 | AfterStep('@Ex_tag1, @Ex_tag2') do 36 | # This will only run after steps within scenarios tagged 37 | # with @cucumis AND @sativus. 38 | end -------------------------------------------------------------------------------- /features-skeleton/actual_images/test.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/selenium-cucumber/selenium-cucumber-ruby/2f43c469ca80a4f262dd4223760f90177f9cb77e/features-skeleton/actual_images/test.png -------------------------------------------------------------------------------- /features-skeleton/expected_images/test.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/selenium-cucumber/selenium-cucumber-ruby/2f43c469ca80a4f262dd4223760f90177f9cb77e/features-skeleton/expected_images/test.png -------------------------------------------------------------------------------- /features-skeleton/image_difference/test.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/selenium-cucumber/selenium-cucumber-ruby/2f43c469ca80a4f262dd4223760f90177f9cb77e/features-skeleton/image_difference/test.png -------------------------------------------------------------------------------- /features-skeleton/my_first.feature: -------------------------------------------------------------------------------- 1 | Feature: Login feature 2 | 3 | Scenario: As a valid user I can log into my web app 4 | When I press "Login" 5 | Then I see "Welcome to coolest web app ever" 6 | -------------------------------------------------------------------------------- /features-skeleton/screenshots/test.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/selenium-cucumber/selenium-cucumber-ruby/2f43c469ca80a4f262dd4223760f90177f9cb77e/features-skeleton/screenshots/test.png -------------------------------------------------------------------------------- /features-skeleton/step_definitions/custom_steps.rb: -------------------------------------------------------------------------------- 1 | require 'selenium-cucumber' 2 | 3 | # Do Not Remove This File 4 | # Add your custom steps here 5 | # $driver is instance of webdriver use this instance to write your custom code -------------------------------------------------------------------------------- /features-skeleton/support/env.rb: -------------------------------------------------------------------------------- 1 | require 'rubygems' 2 | require 'selenium-cucumber' 3 | 4 | # Store command line arguments 5 | $browser_type = ENV['BROWSER'] || 'ff' 6 | $platform = ENV['PLATFORM'] || 'desktop' 7 | $os_version = ENV['OS_VERSION'] 8 | $device_name = ENV['DEVICE_NAME'] 9 | $udid = ENV['UDID'] 10 | $app_path = ENV['APP_PATH'] 11 | 12 | # check for valid parameters 13 | validate_parameters $platform, $browser_type, $app_path 14 | 15 | # If platform is android or ios create driver instance for mobile browser 16 | if $platform == 'android' or $platform == 'iOS' 17 | 18 | if $browser_type == 'native' 19 | $browser_type = "Browser" 20 | end 21 | 22 | if $platform == 'android' 23 | $device_name, $os_version = get_device_info 24 | end 25 | 26 | desired_caps = { 27 | caps: { 28 | platformName: $platform, 29 | browserName: $browser_type, 30 | versionNumber: $os_version, 31 | deviceName: $device_name, 32 | udid: $udid, 33 | app: ".//#{$app_path}" 34 | }, 35 | } 36 | 37 | begin 38 | $driver = Appium::Driver.new(desired_caps).start_driver 39 | rescue Exception => e 40 | puts e.message 41 | Process.exit(0) 42 | end 43 | else # else create driver instance for desktop browser 44 | begin 45 | $driver = Selenium::WebDriver.for(:"#{$browser_type}") 46 | $driver.manage().window().maximize() 47 | rescue Exception => e 48 | puts e.message 49 | Process.exit(0) 50 | end 51 | end 52 | -------------------------------------------------------------------------------- /features-skeleton/support/hooks.rb: -------------------------------------------------------------------------------- 1 | #Cucumber provides a number of hooks which allow us to run blocks at various points in the Cucumber test cycle 2 | 3 | Before do 4 | # Do something before each scenario. 5 | end 6 | 7 | Before do |scenario| 8 | # The +scenario+ argument is optional, but if you use it, you can get the title, 9 | # description, or name (title + description) of the scenario that is about to be 10 | # executed. 11 | end 12 | 13 | After do |scenario| 14 | # Do something after each scenario. 15 | # The +scenario+ argument is optional, but 16 | # if you use it, you can inspect status with 17 | # the #failed?, #passed? and #exception methods. 18 | 19 | if(scenario.failed?) 20 | #Do something if scenario fails. 21 | end 22 | end 23 | 24 | #Tagged hooks 25 | 26 | Before('@Ex_tag1, @Ex_tag2') do 27 | # This will only run before scenarios tagged 28 | # with @Ex_tag1 OR @Ex_tag2. 29 | end 30 | 31 | AfterStep('@Ex_tag1, @Ex_tag2') do |scenario| 32 | # This will only run after steps within scenarios tagged 33 | # with @Ex_tag1 AND @Ex_tag2. 34 | end 35 | 36 | Around('@Ex_tag1') do |scenario, block| 37 | # Will round around a scenario 38 | end 39 | 40 | AfterConfiguration do |config| 41 | # Will run after cucumber has been configured 42 | end 43 | 44 | # Quit the selenium driver from the example tests. 45 | at_exit do 46 | 47 | end 48 | -------------------------------------------------------------------------------- /lib/selenium-cucumber.rb: -------------------------------------------------------------------------------- 1 | Dir[File.dirname(__FILE__) + '/selenium-cucumber/*.rb'].each { |file| require file } 2 | -------------------------------------------------------------------------------- /lib/selenium-cucumber/assertion_steps.rb: -------------------------------------------------------------------------------- 1 | require_relative 'methods/assertion_methods' 2 | 3 | # page title checking 4 | Then(/^I should\s*((?:not)?)\s+see page title as "(.*?)"$/) do |present, title| 5 | check_title(title, present.empty?) 6 | end 7 | 8 | Then(/^I should\s*((?:not)?)\s+see page title having partial text as "(.*?)"$/) do |present, partial_text_title| 9 | check_partial_title(partial_text_title, present.empty?) 10 | end 11 | 12 | # step to check element text 13 | Then(/^element having (.+) "([^\"]*)" should\s*((?:not)?)\s+have text as "(.*?)"$/) do |type, access_name, present, value | 14 | validate_locator type 15 | check_element_text(type, value, access_name, present.empty?) 16 | end 17 | 18 | # step to check element partial text 19 | Then(/^element having (.+) "([^\"]*)" should\s*((?:not)?)\s+have partial text as "(.*?)"$/) do |type, access_name, present, value | 20 | validate_locator type 21 | check_element_partial_text(type, value, access_name, present.empty?) 22 | end 23 | 24 | # step to check attribute value 25 | Then(/^element having (.+) "([^\"]*)" should\s*((?:not)?)\s+have attribute "(.*?)" with value "(.*?)"$/) do |type, access_name, present, attrb, value| 26 | validate_locator type 27 | check_element_attribute(type, attrb, value, access_name, present.empty?) 28 | end 29 | 30 | # step to check element enabled or not 31 | Then(/^element having (.+) "([^\"]*)" should\s*((?:not)?)\s+be (enabled|disabled)$/) do |type, access_name, present, state| 32 | validate_locator type 33 | flag = state == 'enabled' 34 | flag = !flag unless present.empty? 35 | check_element_enable(type, access_name, flag) 36 | end 37 | 38 | # step to check element present or not 39 | Then(/^element having (.+) "(.*?)" should\s*((?:not)?)\s+be present$/) do |type, access_name, present| 40 | validate_locator type 41 | check_element_presence(type, access_name, present.empty?) 42 | end 43 | 44 | # step to assert checkbox is checked or unchecked 45 | Then(/^checkbox having (.+) "(.*?)" should be (checked|unchecked)$/) do |type, access_name, state| 46 | validate_locator type 47 | flag = state == 'checked' 48 | is_checkbox_checked(type, access_name, flag) 49 | end 50 | 51 | # steps to assert radio button checked or unchecked 52 | Then(/^radio button having (.+) "(.*?)" should be (selected|unselected)$/) do |type, access_name, state| 53 | validate_locator type 54 | flag = state == 'selected' 55 | is_radio_button_selected(type, access_name, flag) 56 | end 57 | 58 | # steps to assert option by text from radio button group selected/unselected 59 | Then(/^option "(.*?)" by (.+) from radio button group having (.+) "(.*?)" should be (selected|unselected)$/) do |option, attrb, type, access_name, state| 60 | validate_locator type 61 | flag = state == 'selected' 62 | is_option_from_radio_button_group_selected(type, attrb, option, access_name, flag) 63 | end 64 | 65 | # steps to check link presence 66 | Then(/^link having text "(.*?)" should\s*((?:not)?)\s+be present$/) do |access_name, present| 67 | check_element_presence('link', access_name, present.empty?) 68 | end 69 | 70 | Then(/^link having partial text "(.*?)" should\s*((?:not)?)\s+be present$/) do |access_name, present| 71 | check_element_presence('partial_link_text', access_name, present.empty?) 72 | end 73 | 74 | # step to assert javascript pop-up alert text 75 | Then(/^I should see alert text as "(.*?)"$/) do |actual_value| 76 | check_alert_text(actual_value) 77 | end 78 | 79 | # step to assert dropdown list 80 | Then(/^option "(.*?)" by (.+) from dropdown having (.+) "(.*?)" should be (selected|unselected)$/) do |option, by, type, access_name, state| 81 | validate_locator type 82 | flag = state == 'selected' 83 | is_option_from_dropdown_selected(type, by, option, access_name, state) 84 | end 85 | 86 | # step to assert difference in images 87 | Then(/^actual image having (.+) "(.*?)" and expected image having (.+) "(.*?)" should be similar$/) do |actual_img_access_type, actual_img_access_name, excp_img_access_type, excp_img_access_name| 88 | does_images_similar?(actual_img_access_type, actual_img_access_name, excp_img_access_type, excp_img_access_name) 89 | end 90 | -------------------------------------------------------------------------------- /lib/selenium-cucumber/click_elements_steps.rb: -------------------------------------------------------------------------------- 1 | require_relative 'methods/click_elements_methods' 2 | 3 | When(/^I click on element having (id|name|class|xpath|css) "(.*?)"(?: and text "(.*?)")?$/) do |type, access_name, text| 4 | validate_locator type 5 | if text 6 | click_by_text(type, access_name, text) 7 | else 8 | click(type, access_name) 9 | end 10 | end 11 | 12 | Then(/^I forcefully click on element having (.+) "(.*?)"$/) do |type, access_name| 13 | validate_locator type 14 | click_forcefully(type, access_name) 15 | end 16 | 17 | # double click on web element 18 | Then(/^I double click on element having (.+) "(.*?)"$/) do |type, access_value| 19 | validate_locator type 20 | double_click(type, access_value) 21 | end 22 | 23 | # steps to click on link 24 | Then(/^I click on link having text "(.*?)"$/) do |access_name| 25 | click('link', access_name) 26 | end 27 | 28 | Then(/^I click on link having partial text "(.*?)"$/) do |access_name| 29 | click('partial_link_text', access_name) 30 | end 31 | 32 | When(/^I tap on element having (.+) "(.*?)"$/) do |type, access_name| 33 | validate_locator type 34 | click(type, access_name) 35 | end 36 | 37 | 38 | 39 | 40 | -------------------------------------------------------------------------------- /lib/selenium-cucumber/configuration_steps.rb: -------------------------------------------------------------------------------- 1 | require_relative 'methods/configuration_methods' 2 | 3 | # step to print configuration 4 | Then(/^I print configuration$/) do 5 | print_congifugartion 6 | end 7 | -------------------------------------------------------------------------------- /lib/selenium-cucumber/input_steps.rb: -------------------------------------------------------------------------------- 1 | require_relative 'methods/input_methods' 2 | 3 | # enter text into input field steps 4 | Then(/^I enter "([^\"]*)" into input field having (.+) "([^\"]*)"$/) do |text, type, access_name| 5 | validate_locator type 6 | enter_text(type, text, access_name) 7 | end 8 | 9 | # clear input field steps 10 | Then(/^I clear input field having (.+) "([^\"]*)"$/) do |type, access_name| 11 | validate_locator type 12 | clear_text(type, access_name) 13 | end 14 | 15 | # select option by text/value from dropdown/multiselect 16 | Then(/^I select "(.*?)" option by (.+) from\s*((?:multiselect)?)\sdropdown having (.+) "(.*?)"$/) do |option, option_by, present, type, access_name| 17 | validate_locator type 18 | validate_option_by option_by 19 | select_option_from_dropdown(type, option_by, option, access_name) 20 | end 21 | 22 | # select option by index from dropdown/multiselect 23 | Then(/^I select (\d+) option by index from\s*((?:multiselect)?)\sdropdown having (.+) "(.*?)"$/) do |option, present, type, access_name| 24 | validate_locator type 25 | select_option_from_dropdown(type, 'index', (option.to_i) -1, access_name) 26 | end 27 | 28 | # step to select option from mutliselect dropdown list 29 | Then(/^I select all options from multiselect dropdown having (.+) "(.*?)"$/) do |type, access_name| 30 | validate_locator type 31 | select_all_option_from_multiselect_dropdown(type, access_name) 32 | end 33 | 34 | # step to unselect option from mutliselect dropdown list 35 | Then(/^I unselect all options from multiselect dropdown having (.+) "(.*?)"$/) do |type, access_name| 36 | validate_locator type 37 | unselect_all_option_from_multiselect_dropdown(type, access_name) 38 | end 39 | 40 | # check checkbox steps 41 | Then(/^I check the checkbox having (.+) "(.*?)"$/) do |type, access_name| 42 | validate_locator type 43 | check_checkbox(type, access_name) 44 | end 45 | 46 | # uncheck checkbox steps 47 | Then(/^I uncheck the checkbox having (.+) "(.*?)"$/) do |type, access_name| 48 | validate_locator type 49 | uncheck_checkbox(type, access_name) 50 | end 51 | 52 | # steps to toggle checkbox 53 | Then(/^I toggle checkbox having (.+) "(.*?)"$/) do |type, access_name| 54 | validate_locator type 55 | toggle_checkbox(type, access_name) 56 | end 57 | 58 | # step to select radio button 59 | Then(/^I select radio button having (.+) "(.*?)"$/) do |type, access_name| 60 | validate_locator type 61 | select_radio_button(type, access_name) 62 | end 63 | 64 | # steps to select option by text from radio button group 65 | Then(/^I select "(.*?)" option by (.+) from radio button group having (.+) "(.*?)"$/) do |option, option_by, type, access_name| 66 | validate_locator type 67 | validate_option_by option_by 68 | select_option_from_radio_button_group(type, option_by, option, access_name) 69 | end 70 | -------------------------------------------------------------------------------- /lib/selenium-cucumber/javascript_handling_steps.rb: -------------------------------------------------------------------------------- 1 | require_relative 'methods/javascript_handling_methods' 2 | 3 | Then(/^I accept alert$/) do 4 | handle_alert('accept') 5 | end 6 | 7 | Then(/^I dismiss alert$/) do 8 | handle_alert('dismiss') 9 | end 10 | -------------------------------------------------------------------------------- /lib/selenium-cucumber/methods/assertion_methods.rb: -------------------------------------------------------------------------------- 1 | require 'net/https' 2 | require_relative 'required_files' 3 | 4 | # This file contains assertion methods which are called from assertion_steps.rb 5 | 6 | # Method to return page title 7 | def get_page_title 8 | $driver.title 9 | end 10 | 11 | # Method to verify title 12 | # param 1 : String : expected title 13 | # param 2 : Boolean : test case [true or flase] 14 | def check_title(title, test_case) 15 | page_title = get_page_title 16 | 17 | if test_case 18 | expect(page_title).to eq title 19 | else 20 | expect(page_title).to_not eq title 21 | end 22 | end 23 | 24 | # Method to verify partial title 25 | # param 1 : String : partial title string 26 | # param 2 : Boolean : test case [true or flase] 27 | def check_partial_title(partial_text_title, test_case) 28 | page_title = get_page_title 29 | 30 | if test_case 31 | expect(page_title).to include(partial_text_title) 32 | else 33 | expect(page_title).to_not include(partial_text_title) 34 | end 35 | end 36 | 37 | # Method to get element text 38 | # param 1 : String : Locator type (id, name, class, xpath, css) 39 | # param 2 : String : Locator value 40 | def get_element_text(access_type, access_name) 41 | $driver.find_element(:"#{access_type}" => "#{access_name}").text 42 | end 43 | 44 | # Method to check element text 45 | # param 1 : String : Locator type (id, name, class, xpath, css) 46 | # param 2 : String : Expected element text 47 | # param 3 : String : Locator value 48 | # param 4 : Boolean : test case [true or flase] 49 | def check_element_text(access_type, expected_value, access_name, test_case) 50 | element_text = get_element_text(access_type, access_name) 51 | if test_case 52 | expect(element_text).to eq expected_value 53 | else 54 | expect(element_text).to_not eq expected_value 55 | end 56 | end 57 | 58 | # Method to check partial element text 59 | # param 1 : String : Locator type (id, name, class, xpath, css) 60 | # param 2 : String : Expected element partial text 61 | # param 3 : String : Locator value 62 | # param 4 : Boolean : test case [true or flase] 63 | def check_element_partial_text(access_type, expected_value, access_name, test_case) 64 | element_text = get_element_text(access_type, access_name) 65 | 66 | if test_case 67 | expect(element_text).to include(expected_value) 68 | else 69 | expect(element_text).to_not include(expected_value) 70 | end 71 | end 72 | 73 | # Method to return element status - enabled? 74 | # param 1 : String : Locator type (id, name, class, xpath, css) 75 | # param 2 : String : Locator value 76 | def is_element_enabled(access_type, access_name) 77 | $driver.find_element(:"#{access_type}" => "#{access_name}").enabled? 78 | end 79 | 80 | # Element enabled checking 81 | # param 1 : String : Locator type (id, name, class, xpath, css) 82 | # param 2 : String : Expected element text 83 | # param 4 : Boolean : test case [true or flase] 84 | def check_element_enable(access_type, access_name, test_case) 85 | result = is_element_enabled(access_type, access_name) 86 | if test_case 87 | expect(result).to be true 88 | else 89 | expect(result).to be false 90 | end 91 | end 92 | 93 | # method to get attribute value 94 | # param 1 : String : Locator type (id, name, class, xpath, css) 95 | # param 2 : String : Expected element text 96 | # param 3 : String : atrribute name 97 | def get_element_attribute(access_type, access_name, attribute_name) 98 | $driver.find_element(:"#{access_type}" => "#{access_name}").attribute("#{attribute_name}") 99 | end 100 | 101 | # method to check attribute value 102 | # param 1 : String : Locator type (id, name, class, xpath, css) 103 | # param 2 : String : atrribute name 104 | # param 3 : String : atrribute value 105 | # param 4 : String : Locator value 106 | # param 5 : Boolean : test case [true or flase] 107 | def check_element_attribute(access_type, attribute_name, attribute_value, access_name, test_case) 108 | 109 | attr_val = get_element_attribute(access_type, access_name, attribute_name) 110 | 111 | if test_case 112 | expect(attr_val).to eq(attribute_value) 113 | else 114 | expect(attr_val).to_not eq(attribute_value) 115 | end 116 | end 117 | 118 | # method to get element status - displayed? 119 | # param 1 : String : Locator type (id, name, class, xpath, css) 120 | # param 2 : String : Locator value 121 | def is_element_displayed(access_type, access_name) 122 | begin 123 | $driver.find_element(:"#{access_type}" => "#{access_name}").displayed? 124 | rescue Selenium::WebDriver::Error::NoSuchElementError 125 | # elements not found return false 126 | false 127 | end 128 | end 129 | 130 | # method to check element presence 131 | # param 1 : String : Locator type (id, name, class, xpath, css) 132 | # param 2 : String : Locator value 133 | # param 3 : Boolean : test case [true or flase] 134 | def check_element_presence(access_type, access_name, test_case) 135 | expect(is_element_displayed(access_type, access_name)).to be test_case 136 | end 137 | 138 | # method to assert checkbox check/uncheck 139 | # param 1 : String : Locator type (id, name, class, xpath, css) 140 | # param 2 : String : Locator value 141 | # param 3 : Boolean : test case [true or flase] 142 | def is_checkbox_checked(access_type, access_name, should_be_checked = true) 143 | checkbox = $driver.find_element(:"#{access_type}" => "#{access_name}") 144 | 145 | expect(checkbox.selected?).to be should_be_checked 146 | end 147 | 148 | # method to assert radio button selected/unselected 149 | # param 1 : String : Locator type (id, name, class, xpath, css) 150 | # param 2 : String : Locator value 151 | # param 3 : Boolean : test case [true or flase] 152 | def is_radio_button_selected(access_type, access_name, should_be_selected = true) 153 | radio_button = $driver.find_element(:"#{access_type}" => "#{access_name}") 154 | expect(radio_button.selected?).to be should_be_selected 155 | end 156 | 157 | # method to assert option from radio button group is selected/unselected 158 | def is_option_from_radio_button_group_selected(access_type, by, option, access_name, should_be_selected = true) 159 | radio_button_group = $driver.find_elements(:"#{access_type}" => "#{access_name}") 160 | 161 | getter = ->(rb, by) { by == 'value' ? rb.attribute('value') : rb.text } 162 | 163 | ele = radio_button_group.find { |rb| getter.call(rb, by) == option } 164 | 165 | expect(ele.selected?).to be should_be_selected 166 | end 167 | 168 | # method to get javascript pop-up alert text 169 | def get_alert_text 170 | $driver.switch_to.alert.text 171 | end 172 | 173 | # method to check javascript pop-up alert text 174 | def check_alert_text(text) 175 | expect(get_alert_text).to eq text 176 | end 177 | 178 | def is_option_from_dropdown_selected(access_type, by, option, access_name, should_be_selected=true) 179 | dropdown = $driver.find_element(:"#{access_type}" => "#{access_name}") 180 | select_list = Selenium::WebDriver::Support::Select.new(dropdown) 181 | 182 | if by == 'text' 183 | actual_value = select_list.first_selected_option.text 184 | else 185 | actual_value = select_list.first_selected_option.attribute('value') 186 | end 187 | expect(actual_value).to eq option 188 | end 189 | 190 | # Method to find difference between images 191 | def does_images_similar?(actual_img_access_type, actual_img_access_name, excp_img_access_type, excp_img_access_name) 192 | if !compare_image(actual_img_access_type, actual_img_access_name, excp_img_access_type, excp_img_access_name) 193 | raise TestCaseFailed, 'Actual image is different from expected image' 194 | end 195 | end 196 | 197 | # Method to compare two images 198 | # param 1 : String : Locator type (id, name, class, xpath, css, url) 199 | # param 2 : String : Locator value 200 | # param 3 : String : Locator type (id, name, class, xpath, css, url, image_name) 201 | # param 4 : String : Locator value 202 | def compare_image(actual_img_access_type, actual_img_access_name, excp_img_access_type, excp_img_access_name) 203 | if actual_img_access_type == 'url' 204 | actual_img_url = actual_img_access_name 205 | else 206 | actual_img_url = get_element_attribute(actual_img_access_type, actual_img_access_name, 'src') 207 | end 208 | 209 | if excp_img_access_type == 'url' 210 | expected_img_url = excp_img_access_name 211 | elsif excp_img_access_type == 'image_name' 212 | expected_img_url = './features/expected_images/' + excp_img_access_name 213 | else 214 | expected_img_url = get_element_attribute(excp_img_access_type, excp_img_access_name, 'src') 215 | end 216 | 217 | # replace 'https' with 'http' from actual image url 218 | if actual_img_url.include? 'https' 219 | actual_img_url['https'] = 'http' 220 | end 221 | 222 | # replace 'https' with 'http' from expected image url 223 | if expected_img_url.include? 'https' 224 | expected_img_url['https'] = 'http' 225 | end 226 | 227 | if expected_img_url.include? '.png' 228 | image_type = 'png' 229 | else 230 | image_type = 'jpg' 231 | end 232 | 233 | # Storing actual image locally 234 | open('./features/actual_images/actual_image.' + image_type, 'wb') do |file| 235 | file << open(actual_img_url).read 236 | end 237 | 238 | actual_img_url = './features/actual_images/actual_image.' + image_type 239 | 240 | # Storing Expected image locally 241 | if excp_img_access_type != 'image_name' 242 | open('./features/expected_images/expected_image.' + image_type, 'wb') do |file| 243 | file << open(expected_img_url).read 244 | end 245 | expected_img_url = './features/expected_images/expected_image.' + image_type 246 | end 247 | 248 | # Verify image extension and call respective compare function 249 | if image_type == 'png' 250 | return compare_png_images(expected_img_url, actual_img_url) 251 | end 252 | 253 | compare_jpeg_images(expected_img_url, actual_img_url) 254 | end 255 | 256 | # Comparing jpg images 257 | def compare_jpeg_images(expected_img_url, actual_img_url) 258 | if open(expected_img_url).read == open(actual_img_url).read 259 | return true 260 | else 261 | puts 'Difference in images' 262 | return false 263 | end 264 | end 265 | 266 | # Comparing png images 267 | def compare_png_images(expected_img_url, actual_img_url) 268 | images = [ 269 | ChunkyPNG::Image.from_file(expected_img_url), 270 | ChunkyPNG::Image.from_file(actual_img_url) 271 | ] 272 | 273 | diff = [] 274 | 275 | images.first.height.times do |y| 276 | images.first.row(y).each_with_index do |pixel, x| 277 | diff << [x, y] unless pixel == images.last[x, y] 278 | end 279 | end 280 | 281 | if diff.length != 0 282 | puts "\npixels (total): #{images.first.pixels.length}" 283 | puts "pixels changed: #{diff.length}" 284 | puts "pixels changed (%): #{(diff.length.to_f / images.first.pixels.length) * 100}%" 285 | 286 | x, y = diff.map { |xy| xy[0] }, diff.map { |xy| xy[1] } 287 | images.last.rect(x.min, y.min, x.max, y.max, ChunkyPNG::Color.rgb(0, 255, 0)) 288 | cur_time = Time.now.strftime('%Y%m%d%H%M%S%L') 289 | images.last.save("./features/image_difference/difference_#{cur_time}.png") 290 | 291 | puts "\nDifference between images saved as : difference_#{cur_time}.png\n" 292 | return false 293 | end 294 | true 295 | end 296 | -------------------------------------------------------------------------------- /lib/selenium-cucumber/methods/click_elements_methods.rb: -------------------------------------------------------------------------------- 1 | require_relative 'required_files' 2 | 3 | def click(access_type, access_name) 4 | $driver.find_element(:"#{access_type}" => "#{access_name}").click 5 | end 6 | 7 | def click_by_text(access_type, access_name, text) 8 | element_found = false 9 | text_found = false 10 | text_found = $driver.page_source.include? text 11 | raise "Text '#{text}' was not found in the page source" unless text_found 12 | # enter loop if the text is found 13 | if text_found 14 | elements = $driver.find_elements(:"#{access_type}" => "#{access_name}") 15 | elements.each do |element| 16 | if element.text == text 17 | element_found = true 18 | element.click 19 | break 20 | end 21 | end 22 | end 23 | raise "Element not found having access type #{access_type}, access name #{access_name}, and text #{text}" unless element_found 24 | end 25 | 26 | def click_forcefully(access_type, access_name) 27 | $driver.execute_script('arguments[0].click();', $driver.find_element(:"#{access_type}" => "#{access_name}")) 28 | end 29 | 30 | def double_click(access_type, access_value) 31 | element = $driver.find_element(:"#{access_type}" => "#{access_value}") 32 | $driver.action.double_click(element).perform 33 | end 34 | 35 | def submit(access_type, access_name) 36 | $driver.find_element(:"#{access_type}" => "#{access_name}").submit 37 | end 38 | 39 | 40 | 41 | 42 | -------------------------------------------------------------------------------- /lib/selenium-cucumber/methods/configuration_methods.rb: -------------------------------------------------------------------------------- 1 | require_relative 'required_files' 2 | 3 | # method to print configuration 4 | def print_congifugartion 5 | puts '' 6 | puts "Date : #{Time.now.strftime("%d-%B-%Y")}" 7 | puts "Time : #{Time.now.strftime("%I:%M:%S:%p")}" 8 | 9 | if $platform == 'android' or $platform == 'ios' 10 | print_mobile_configuration 11 | else 12 | print_desktop_configuration 13 | end 14 | end 15 | 16 | # method to print desktop configuration 17 | def print_desktop_configuration 18 | puts 'Platform : ' + $driver.capabilities.platform.to_s.upcase 19 | puts 'Browser : ' + $driver.capabilities.browser_name.to_s.upcase + " " + $driver.capabilities.version.to_s 20 | puts '' 21 | end 22 | 23 | # method to print mobile configuration 24 | def print_mobile_configuration 25 | puts "Platform : #{$platform.upcase}" 26 | puts "OS version : #{$os_version}" 27 | puts "Device : #{$device_name}" 28 | 29 | if $app_path.nil? 30 | puts 'Browser : ' + $driver.capabilities.browser_name.to_s.upcase + " " + $driver.capabilities.version.to_s 31 | else 32 | puts "App Tested : #{$app_path}" 33 | end 34 | puts '' 35 | end 36 | -------------------------------------------------------------------------------- /lib/selenium-cucumber/methods/error_handling_methods.rb: -------------------------------------------------------------------------------- 1 | # Error handling methods 2 | 3 | # Method to check browser type 4 | def validate_parameters(platform, browser_type, app_path) 5 | if platform == 'desktop' 6 | if !%w(ff ie chrome safari opera).include? browser_type 7 | print_error_desktop 8 | end 9 | elsif platform == 'android' 10 | print_error_android browser_type, app_path 11 | elsif platform == 'iOS' 12 | puts "Not Implemented..." 13 | # print_error_ios browser_type, app_path 14 | else 15 | print_invalid_platform 16 | end 17 | end 18 | 19 | # print error for desktop 20 | def print_error_desktop 21 | puts "\nInappropraite desktop browser : \"#{ENV['BROWSER']}\"" 22 | puts "\nUsage : cucumber BROWSER=browser_name" 23 | puts "\nBrowser Supported :\n" 24 | puts "\n1.ie\n2.chrome\n3.ff\n4.safari\n5.opera" 25 | Process.exit(0) 26 | end 27 | 28 | # print error for android 29 | def print_error_android(browser_type, app_path) 30 | if browser_type=='ff' and app_path==nil 31 | puts "\nOops... not mentioned \"Browser\" or \"App path\"" 32 | print_error_android_app 33 | print_error_android_web 34 | Process.exit(0) 35 | elsif browser_type!='ff' and !%w(native chrome).include? browser_type 36 | puts "\nOops... not supported browser" 37 | print_error_android_web 38 | Process.exit(0) 39 | end 40 | end 41 | 42 | # print error for android app 43 | def print_error_android_app 44 | puts "\nTo run test on android app" 45 | puts "\n Usage : cucumber PLATFORM=android APP_PATH=path/to/app" 46 | end 47 | 48 | # print error for android web 49 | def print_error_android_web 50 | puts "\nTo run test on android mobile web" 51 | puts "\n Usage : cucumber PLATFORM=android BROWSER=browser_name" 52 | puts "\n Supported browsers are \"chrome\" and \"native\"" 53 | end 54 | 55 | # print error for ios 56 | def print_error_ios 57 | if browser_type=='ff' and app_path==nil 58 | puts "\nOops... not mentioned \"Browser\" or \"App path\"" 59 | print_error_ios_app 60 | print_error_ios_web 61 | Process.exit(0) 62 | elsif browser_type!='safari' 63 | puts "\nOops... not supported browser" 64 | print_error_ios_app_web 65 | Process.exit(0) 66 | end 67 | end 68 | 69 | # print error for ios app 70 | def print_error_ios_app 71 | puts "\nTo run test on iOS App" 72 | puts "\n Usage : cucumber PLATFORM=iOS APP_PATH=path/to/app" 73 | end 74 | 75 | # print error for ios web 76 | def print_error_ios_web 77 | puts "\nTo run test on iOS mobile web" 78 | puts "\n Usage : cucumber PLATFORM=iOS BROWSER=safari" 79 | end 80 | 81 | # print error if invalid platform 82 | def print_invalid_platform 83 | puts "\nOops... Invalid Platform" 84 | puts "\nSupported platform are \"android\" and \"iOS\"." 85 | puts "\nTo run on Desktop no need to mention platform." 86 | Process.exit(0) 87 | end -------------------------------------------------------------------------------- /lib/selenium-cucumber/methods/input_methods.rb: -------------------------------------------------------------------------------- 1 | require_relative 'required_files' 2 | 3 | # method to enter text into textfield 4 | def enter_text(access_type, text, access_name) 5 | $driver.find_element(:"#{access_type}" => "#{access_name}").send_keys text 6 | end 7 | 8 | # method to clear text from textfield 9 | def clear_text(access_type, access_name) 10 | $driver.find_element(:"#{access_type}" => "#{access_name}").clear 11 | end 12 | 13 | # method to select option from dropdwon list 14 | def select_option_from_dropdown(access_type, by, option, access_name) 15 | dropdown = $driver.find_element(:"#{access_type}" => "#{access_name}") 16 | select_list = Selenium::WebDriver::Support::Select.new(dropdown) 17 | select_list.select_by(:"#{by}", "#{option}") 18 | end 19 | 20 | # method to select all option from dropdwon list 21 | def select_all_option_from_multiselect_dropdown(access_type, access_name) 22 | dropdown = $driver.find_element(:"#{access_type}" => "#{access_name}") 23 | select_list = Selenium::WebDriver::Support::Select.new(dropdown) 24 | select_list.select_all 25 | end 26 | 27 | # method to unselect all option from dropdwon list 28 | def unselect_all_option_from_multiselect_dropdown(access_type, access_name) 29 | dropdown = $driver.find_element(:"#{access_type}" => "#{access_name}") 30 | select_list = Selenium::WebDriver::Support::Select.new(dropdown) 31 | select_list.deselect_all 32 | end 33 | 34 | # method to check checkbox 35 | def check_checkbox(access_type, access_name) 36 | checkbox = $driver.find_element(:"#{access_type}" => "#{access_name}") 37 | checkbox.click unless checkbox.selected? 38 | end 39 | 40 | # method to uncheck checkbox 41 | def uncheck_checkbox(access_type, access_name) 42 | checkbox = $driver.find_element(:"#{access_type}" => "#{access_name}") 43 | 44 | if checkbox.selected? 45 | checkbox.click 46 | end 47 | end 48 | 49 | # method to select radio button 50 | def toggle_checkbox(access_type, access_name) 51 | $driver.find_element(:"#{access_type}" => "#{access_name}").click 52 | end 53 | 54 | # method to select radio button 55 | def select_radio_button(access_type, access_name) 56 | radio_button = $driver.find_element(:"#{access_type}" => "#{access_name}") 57 | radio_button.click unless radio_button.selected? 58 | end 59 | 60 | # method to select option from radio button group 61 | def select_option_from_radio_button_group(access_type, by, option, access_name) 62 | radio_button_group = $driver.find_elements(:"#{access_type}" => "#{access_name}") 63 | 64 | getter = ->(rb, by) { by == 'value' ? rb.attribute('value') : rb.text } 65 | ele = radio_button_group.find { |rb| getter.call(rb, by) == option } 66 | ele.click unless ele.selected? 67 | end 68 | -------------------------------------------------------------------------------- /lib/selenium-cucumber/methods/javascript_handling_methods.rb: -------------------------------------------------------------------------------- 1 | require_relative 'required_files' 2 | 3 | def handle_alert(decesion) 4 | if decesion == 'accept' 5 | $driver.switch_to.alert.accept 6 | else 7 | $driver.switch_to.alert.dismiss 8 | end 9 | end 10 | -------------------------------------------------------------------------------- /lib/selenium-cucumber/methods/misc_methods.rb: -------------------------------------------------------------------------------- 1 | 2 | # custome exception class 3 | class TestCaseFailed < Exception 4 | end 5 | 6 | # WAIT instance for explicit wait 7 | WAIT = Selenium::WebDriver::Wait.new(:timeout => 30) 8 | 9 | # method to validate locator 10 | def valid_locator_type? type 11 | %w(id class css name xpath accessibility_id).include? type 12 | end 13 | 14 | def validate_locator type 15 | raise "Invalid locator type - #{type}" unless valid_locator_type? type 16 | end 17 | 18 | # method to validate dropdown selector 19 | def valid_option_by? option_by 20 | %w(text value index).include? option_by 21 | end 22 | 23 | def validate_option_by option_by 24 | raise "Invalid option by - #{option_by}" unless valid_option_by? option_by 25 | end 26 | 27 | # Return android device name and android version using adb command 28 | def get_device_info 29 | IO.popen('adb shell getprop ro.product.brand') { |f| $device = f.gets.chomp.upcase} 30 | $device += ' ' 31 | IO.popen('adb shell getprop ro.product.model') { |f| $device += f.gets.chomp.upcase} 32 | IO.popen('adb shell getprop ro.build.version.release') { |f| $os_version = f.gets.chomp.upcase} 33 | return $device, $os_version 34 | end 35 | -------------------------------------------------------------------------------- /lib/selenium-cucumber/methods/mobile_methods.rb: -------------------------------------------------------------------------------- 1 | require_relative 'required_files' 2 | 3 | def swipe_using_elements(access_type1, access_name1, access_type2, access_name2) 4 | 5 | # to get start x,y co-ordinates 6 | ele_from = WAIT.until { $driver.find_element(:"#{access_type1}" => "#{access_name1}") }.location 7 | start_x = ele_from.x 8 | start_y = ele_from.y 9 | 10 | # to get end x,y co-ordinates 11 | ele_to = WAIT.until { $driver.find_element(:"#{access_type2}" => "#{access_name2}") }.location 12 | end_x = ele_to.x 13 | end_y = ele_to.y 14 | 15 | swipe(start_x, start_y, end_x, end_y) 16 | end 17 | 18 | def swipe(start_x, start_y, end_x, end_y) 19 | action = Appium::TouchAction.new.press(x: "#{start_x}", y: "#{start_y}").wait(1000).move_to(x: "#{end_x}", y: "#{end_y}").release() 20 | action.perform 21 | end 22 | 23 | def swipe_direction(direction) 24 | size = $driver.manage.window.size 25 | height = size.height.to_i - 10 26 | width = size.width.to_i - 10 27 | 28 | if direction == 'right' 29 | start_x = (width/100) * 15 # 83 30 | start_y = height/2 # 695 31 | end_x = (width/100) * 90 # 900 32 | end_y = height/2 # 630 33 | elsif direction == 'left' 34 | start_x = (width/100) * 90 35 | start_y = height/2 36 | end_x = (width/100) * 15 37 | end_y = height/2 38 | elsif direction == 'up' 39 | start_x = width/2 40 | start_y = (height/100) * 90 41 | end_x = width/2 42 | end_y = (height/100) * 15 43 | elsif direction == 'down' 44 | start_x = width/2 45 | start_y = (height/100) * 15 46 | end_x = width/2 47 | end_y = (height/100) * 90 48 | else 49 | raise "invalid direction" 50 | end 51 | 52 | swipe(start_x, start_y, end_x, end_y) 53 | end 54 | 55 | def swipe_element_with_direction(access_type, access_name, direction) 56 | ele_from = WAIT.until { $driver.find_element(:"#{access_type}" => "#{access_name}") }.location 57 | x_start = ele_from.x 58 | y_start = ele_from.y 59 | 60 | ele_size = WAIT.until { $driver.find_element(:"#{access_type}" => "#{access_name}") } 61 | ele_height = ele_size.size.height.to_i 62 | ele_width = ele_size.size.width.to_i 63 | #puts ele_size.width 64 | 65 | x_end = x_start + ele_width 66 | y_end = y_start + ele_height 67 | 68 | puts "[#{x_start},#{y_start}],[#{x_end},#{y_end}]" 69 | 70 | puts "ele_height : #{ele_height}" # 1776 71 | puts "ele_width :#{ele_width}" # 72 | 73 | size = $driver.manage.window.size 74 | height = size.height.to_i - 5 75 | puts "height : #{height}" # 1776 76 | width = size.width.to_i - 5 77 | puts "width :#{width}" # 78 | 79 | if direction == 'right' 80 | start_x = x_start + (ele_width*0.25) 81 | start_y = (y_start) + (ele_height/2) 82 | end_x = width # 900 83 | end_y = (y_start) + (ele_height/2) 84 | elsif direction == 'left' 85 | start_x = x_end - 5 86 | start_y = (y_end) - (ele_height/2) 87 | end_x = 10 88 | end_y = (y_end) - (ele_height/2) 89 | elsif direction == 'up' 90 | if ele_height > height 91 | ele_height = height 92 | end 93 | 94 | if y_end > height 95 | y_end = y_start + ele_height 96 | end 97 | 98 | puts "ele_height: #{ele_height}" 99 | puts "ele_height*).75: #{ele_height*0.75}" 100 | puts y_end 101 | start_x = x_end - (ele_width/2) 102 | 103 | start_y = (y_end) - (ele_height*0.75) 104 | 105 | if start_y < 0 106 | y_start = 0 107 | y_end = y_start + ele_height 108 | start_y = (y_end) - (ele_height*0.75) 109 | # puts y_end 110 | # puts "y_start: #{y_start}" 111 | # puts "ele_height: #{ele_height}" 112 | # puts "ele_height*0.75: #{ele_height*0.75}" 113 | end 114 | 115 | end_x = (x_end/2) 116 | end_y = 10 117 | elsif direction == 'down' 118 | start_x = x_start + (ele_width/2) 119 | if ele_height > height 120 | ele_height = height 121 | end 122 | start_y = (y_start) + (ele_height*0.25) 123 | if start_y < 0 124 | y_start = 0 125 | if ele_height > height 126 | ele_height = height 127 | end 128 | start_y = (y_start) + (ele_height*0.25) 129 | # puts y_end 130 | # puts "y_start: #{y_start}" 131 | puts "ele_height: #{ele_height}" 132 | puts "ele_height*0.25: #{ele_height*0.25}" 133 | end 134 | end_x = x_start + (ele_width/2) 135 | if ele_height > height 136 | ele_height = height 137 | end 138 | end_y = ele_height 139 | else 140 | raise "invalid direction" 141 | end 142 | 143 | puts "start_x: #{start_x}, start_y: #{start_y}" 144 | puts "end_x: #{end_x}, end_y: #{end_y}" 145 | 146 | swipe(start_x, start_y, end_x, end_y) 147 | end 148 | 149 | def swipe_coordinates_with_direction(start_x, start_y, direction) 150 | 151 | # ele_from = WAIT.until { $driver.find_element(:"#{access_type}" => "#{access_name}") }.size 152 | # height = size.height.to_i - 5 153 | # puts "height : #{height}" # 1776 154 | # width = size.width.to_i - 5 155 | # puts "width :#{width}" # 156 | 157 | size = $driver.manage.window.size 158 | height = size.height.to_i - 5 159 | puts "height : #{height}" 160 | width = size.width.to_i - 5 161 | puts "width :#{width}" 162 | 163 | if direction == 'right' 164 | start_x = start_x 165 | start_y = start_y 166 | end_x = width 167 | end_y = start_y 168 | elsif direction == 'left' 169 | start_x = start_x 170 | start_y = start_y 171 | end_x = 10 172 | end_y = start_y 173 | elsif direction == 'up' 174 | start_x = start_x 175 | start_y = start_y 176 | end_x = start_x 177 | end_y = 10 178 | elsif direction == 'down' 179 | start_x = start_x 180 | start_y = start_y 181 | end_x = start_x 182 | end_y = height 183 | else 184 | raise "invalid direction" 185 | end 186 | 187 | swipe(start_x, start_y, end_x, end_y) 188 | end 189 | 190 | 191 | def long_press_on_element_default_duration(access_type, access_name) 192 | begin 193 | ele_from = WAIT.until { $driver.find_element(:"#{access_type}" => "#{access_name}") }.location 194 | x = ele_from.x 195 | y = ele_from.y 196 | 197 | action = Appium::TouchAction.new.press(x: "#{x}", y: "#{y}").wait(2000).move_to(x: "#{x}", y: "#{y}").release() 198 | action.perform 199 | rescue Exception => e 200 | if e.to_s == 'The swipe did not complete successfully' 201 | print "" 202 | else 203 | raise e 204 | end 205 | end 206 | end 207 | 208 | def long_press_on_element_with_duration(access_type, access_name, duration) 209 | begin 210 | ele_from = WAIT.until { $driver.find_element(:"#{access_type}" => "#{access_name}") }.location 211 | x = ele_from.x 212 | y = ele_from.y 213 | 214 | duration = duration.to_i 215 | duration = duration * 1000 216 | action = Appium::TouchAction.new.press(x: "#{x}", y: "#{y}").wait("#{duration}").move_to(x: "#{x}", y: "#{y}").release() 217 | action.perform 218 | rescue Exception => e 219 | if e.to_s == 'The swipe did not complete successfully' 220 | print "" 221 | else 222 | raise e 223 | end 224 | end 225 | end 226 | 227 | def long_press_on_coordinates(x, y) 228 | action = Appium::TouchAction.new.press(x: "#{x}", y: "#{y}").wait(2000).move_to(x: "#{x}", y: "#{y}").release() 229 | action.perform 230 | end 231 | 232 | def long_press_on_coordinates_with_duration(x, y, duration) 233 | duration = duration.to_i 234 | duration = duration * 1000 235 | puts duration 236 | action = Appium::TouchAction.new.press(x: "#{x}", y: "#{y}").wait("#{duration}").move_to(x: "#{x}", y: "#{y}").release() 237 | action.perform 238 | end 239 | 240 | def close_app 241 | $driver.close_app 242 | end -------------------------------------------------------------------------------- /lib/selenium-cucumber/methods/navigate_methods.rb: -------------------------------------------------------------------------------- 1 | require_relative 'required_files' 2 | 3 | # method to open link 4 | def navigate_to(link) 5 | $driver.get link 6 | end 7 | 8 | # method to navigate back & forword 9 | def navigate(direction) 10 | if direction == 'back' 11 | $driver.navigate.back 12 | else 13 | $driver.navigate.forward 14 | end 15 | end 16 | 17 | # method to quite webdriver instance 18 | def close_driver 19 | $driver.quit 20 | end 21 | 22 | # method to return key (control/command) by os wise 23 | def get_key 24 | os = $driver.capabilities.platform.to_s.upcase 25 | if os.to_s == 'WINDOWS' || os.to_s == 'LINUX' 26 | return 'control' 27 | elsif os.to_s == 'DARWIN' 28 | return 'command' 29 | else 30 | raise 'Invalid OS' 31 | end 32 | end 33 | 34 | # Method to zoom in/out/reset page 35 | def zoom_in_out(operation) 36 | if $driver.capabilities.browser_name == 'chrome' 37 | actual_zoom = $driver.execute_script "return document.body.style.zoom" 38 | puts "actual_zoom:#{actual_zoom}" 39 | if actual_zoom == '' or actual_zoom == nil 40 | actual_zoom = 100 41 | else 42 | actual_zoom = actual_zoom.delete '%' 43 | actual_zoom = actual_zoom.to_i 44 | end 45 | 46 | if operation == 'add' 47 | actual_zoom += 15 unless actual_zoom >= 500 48 | elsif operation == 'subtract' 49 | actual_zoom -= 15 unless actual_zoom <= 25 50 | else 51 | actual_zoom = 100 52 | end 53 | puts "actual_zoom:#{actual_zoom}" 54 | $driver.execute_script "document.body.style.zoom='#{actual_zoom}%'" 55 | else 56 | html = $driver.find_element(:tag_name => "body") 57 | $driver.action.send_keys(html, :"#{get_key}", :"#{operation}" ).perform 58 | end 59 | end 60 | 61 | # Method to zoom in/out web page until web element displyas 62 | def zoom_in_out_till_element_display(access_type, operation, access_name) 63 | while true 64 | if WAIT.until { $driver.find_element(:"#{access_type}" => "#{access_name}") }.displayed? 65 | break 66 | else 67 | zoom_in_out(operation) 68 | end 69 | end 70 | end 71 | 72 | # Method to resize browser 73 | def resize_browser(width, heigth) 74 | $driver.manage.window.resize_to(width, heigth) 75 | end 76 | 77 | # Method to maximize browser 78 | def maximize_browser 79 | $driver.manage.window.maximize 80 | end 81 | 82 | # Method to hover on element 83 | def hover_over_element(access_type, access_name) 84 | element = $driver.find_element(:"#{access_type}" => "#{access_name}") 85 | $driver.action.move_to(element).perform 86 | end 87 | 88 | # Method to scroll page to perticular element 89 | def scroll_to_element(access_type, access_name) 90 | ele_scroll = $driver.find_element(:"#{access_type}" => "#{access_name}") 91 | ele_scroll.location_once_scrolled_into_view 92 | end 93 | 94 | # method to scroll page to top or end 95 | def scroll_page(to) 96 | if to == 'end' 97 | $driver.execute_script('window.scrollTo(0,Math.max(document.documentElement.scrollHeight,document.body.scrollHeight,document.documentElement.clientHeight));') 98 | elsif to == 'top' 99 | $driver.execute_script('window.scrollTo(Math.max(document.documentElement.scrollHeight,document.body.scrollHeight,document.documentElement.clientHeight),0);') 100 | else 101 | raise "Exception : Invalid Direction (only scroll \"top\" or \"end\")" 102 | end 103 | end 104 | 105 | # Method to switch to old window 106 | def switch_to_previous_window 107 | $driver.switch_to.window $previous_window 108 | end 109 | 110 | # Method to switch to new window 111 | def switch_to_new_window 112 | $previous_window = $driver.window_handle 113 | $driver.switch_to.window($driver.window_handles.last) 114 | end 115 | 116 | # Method to switch to main window 117 | def switch_to_main_window 118 | $previous_window = $driver.window_handle 119 | $driver.switch_to.window($driver.window_handles.first) 120 | end 121 | 122 | # Method to switch to window by title 123 | def switch_to_window_by_title window_title 124 | $previous_window = $driver.window_handle 125 | window_found = false 126 | $driver.window_handles.each{ |handle| 127 | $driver.switch_to.window handle 128 | if $driver.title == window_title 129 | window_found = true 130 | break 131 | end 132 | } 133 | raise "Window having title \"#{window_title}\" not found" if not window_found 134 | end 135 | 136 | def switch_to_window_by_url window_url 137 | $previous_window = $driver.window_handle 138 | window_found = false 139 | $driver.window_handles.each { |handle| 140 | $driver.switch_to.window handle 141 | # match absolute or relative 142 | if $driver.current_url.include?(window_url) 143 | window_found = true 144 | break 145 | end 146 | } 147 | raise "Window having url \"#{window_url}\" not found" if not window_found 148 | end 149 | 150 | # Method to close new window 151 | def close_new_window 152 | $driver.close 153 | end 154 | 155 | # method to switch frame 156 | def switch_frame frame 157 | $driver.switch_to.frame(frame) 158 | end 159 | 160 | # method to switch to main window 161 | def switch_to_main_content 162 | $driver.switch_to.default_content 163 | end 164 | 165 | =begin 166 | def switch_to_new_window 167 | win_handles = $driver.window_handles 168 | 169 | puts $driver.title 170 | puts win_handles.length 171 | 172 | $driver.switch_to.window($driver.window_handles[1]) 173 | puts $driver.window_handles[1] 174 | puts $driver.title 175 | 176 | $driver.switch_to.window($driver.window_handles[2]) 177 | puts $driver.window_handles[2] 178 | puts $driver.title 179 | end 180 | =end -------------------------------------------------------------------------------- /lib/selenium-cucumber/methods/progress_methods.rb: -------------------------------------------------------------------------------- 1 | require_relative 'required_files' 2 | 3 | def wait(time) 4 | sleep time.to_i 5 | end 6 | 7 | def wait_for_element_to_display(access_type, access_name, duration) 8 | wait = Selenium::WebDriver::Wait.new(:timeout => duration.to_i) # seconds 9 | wait.until { $driver.find_element(:"#{access_type}" => "#{access_name}").displayed? } 10 | end 11 | 12 | def wait_for_element_to_enable(access_type, access_name, duration) 13 | wait = Selenium::WebDriver::Wait.new(:timeout => duration.to_i) # seconds 14 | wait.until { $driver.find_element(:"#{access_type}" => "#{access_name}").enabled? } 15 | end 16 | -------------------------------------------------------------------------------- /lib/selenium-cucumber/methods/required_files.rb: -------------------------------------------------------------------------------- 1 | require 'rubygems' 2 | require 'selenium-webdriver' 3 | require 'chunky_png' 4 | require 'open-uri' 5 | require 'rbconfig' 6 | require 'appium_lib' 7 | include RbConfig 8 | 9 | require_relative 'misc_methods' 10 | require_relative 'error_handling_methods' 11 | -------------------------------------------------------------------------------- /lib/selenium-cucumber/methods/screenshot_methods.rb: -------------------------------------------------------------------------------- 1 | require_relative 'required_files' 2 | 3 | def take_screenshot 4 | cur_time = Time.now.strftime('%Y%m%d%H%M%S%L') 5 | $driver.save_screenshot('./features/screenshots/screenshot' + cur_time + '.png') 6 | end 7 | -------------------------------------------------------------------------------- /lib/selenium-cucumber/mobile_steps.rb: -------------------------------------------------------------------------------- 1 | require_relative 'methods/mobile_methods' 2 | require_relative 'methods/navigate_methods' 3 | 4 | #---------- swipe with elements 5 | Then(/^I swipe from element having (.+) "(.*?)" to element having (.+) "(.*?)"$/) do |type1,access_name1,type2,access_name2| 6 | validate_locator type1 7 | validate_locator type2 8 | swipe_using_elements(type1,access_name1,type2,access_name2) 9 | end 10 | 11 | #---------- swipe with co-ordinates 12 | Then(/^I swipe from co\-ordinates "(.*?)","(.*?)" to co\-ordinates "(.*?)","(.*?)"$/) do |start_x, start_y, end_x, end_y| 13 | swipe(start_x, start_y, end_x, end_y) 14 | end 15 | 16 | #---------- Swipe with direction 17 | Then(/^I swipe left$/) do 18 | swipe_direction("left") 19 | end 20 | 21 | Then(/^I swipe right$/) do 22 | swipe_direction("right") 23 | end 24 | 25 | Then(/^I swipe up$/) do 26 | swipe_direction("up") 27 | end 28 | 29 | Then(/^I swipe down$/) do 30 | swipe_direction("down") 31 | end 32 | 33 | #----------- Swipe element with direction 34 | Then(/^I swipe element having (.+) "(.*?)" to right$/) do |type, access_name| 35 | validate_locator type 36 | swipe_element_with_direction(type, access_name, "right") 37 | end 38 | 39 | Then(/^I swipe element having (.+) "(.*?)" to left$/) do |type, access_name| 40 | swipe_element_with_direction(type, access_name, "left") 41 | end 42 | 43 | Then(/^I swipe element having (.+) "(.*?)" to up$/) do |type, access_name| 44 | swipe_element_with_direction(type, access_name, "up") 45 | end 46 | 47 | Then(/^I swipe element having (.+) "(.*?)" to down$/) do |type, access_name| 48 | swipe_element_with_direction(type, access_name, "down") 49 | end 50 | 51 | #swipe co-ordinates with direction 52 | 53 | Then(/^I swipe co\-ordinates "(.*?)","(.*?)" to left$/) do |start_x, start_y| 54 | swipe_coordinates_with_direction(start_x, start_y, "left") 55 | end 56 | 57 | 58 | Then(/^I swipe co\-ordinates "(.*?)","(.*?)" to right$/) do |start_x, start_y| 59 | swipe_coordinates_with_direction(start_x, start_y, "right") 60 | end 61 | 62 | 63 | Then(/^I swipe co\-ordinates "(.*?)","(.*?)" to up$/) do |start_x, start_y| 64 | swipe_coordinates_with_direction(start_x, start_y, "up") 65 | end 66 | 67 | 68 | Then(/^I swipe co\-ordinates "(.*?)","(.*?)" to down$/) do |start_x, start_y| 69 | swipe_coordinates_with_direction(start_x, start_y, "down") 70 | end 71 | 72 | Then(/^I long tap on element having (.+) "(.*?)"$/) do |type, access_name| 73 | validate_locator type 74 | long_press_on_element_default_duration(type, access_name) 75 | end 76 | 77 | Then(/^I long tap on element having (.+) "(.*?)" for "(.*?)" sec$/) do |type, access_name, duration| 78 | validate_locator type 79 | long_press_on_element_with_duration(type, access_name, duration) 80 | end 81 | 82 | Then(/^I long tap on co\-ordinate "(.*?)","(.*?)"$/) do |x, y| 83 | long_press_on_coordinates(x, y) 84 | end 85 | 86 | Then(/^I long tap on co\-ordinate "(.*?)","(.*?)" for "(.*?)" sec$/) do |x, y, duration| 87 | long_press_on_coordinates_with_duration(x, y, duration) 88 | end 89 | 90 | Then(/^I close app$/) do 91 | close_app 92 | end 93 | 94 | Then(/^I tap on back button of device$/) do 95 | navigate('back') 96 | end 97 | 98 | Then(/^I press back button of device$/) do 99 | navigate('back') 100 | end -------------------------------------------------------------------------------- /lib/selenium-cucumber/navigation_steps.rb: -------------------------------------------------------------------------------- 1 | require_relative 'methods/navigate_methods' 2 | 3 | Then(/^I navigate to "([^\"]*)"$/)do |link| 4 | navigate_to(link) 5 | end 6 | 7 | Then(/^I navigate forward/) do 8 | navigate('forward') 9 | end 10 | 11 | Then(/^I navigate back/) do 12 | navigate('back') 13 | end 14 | 15 | Then(/^I close browser$/) do 16 | close_driver 17 | end 18 | 19 | # step to resize browser 20 | Then(/^I resize browser window size to width (\d+) and height (\d+)$/) do |width, heigth| 21 | resize_browser(width, heigth) 22 | end 23 | 24 | # step to maximize browser 25 | Then(/^I maximize browser window$/) do 26 | maximize_browser 27 | end 28 | 29 | # step to refresh page 30 | Then(/^I refresh page$/) do 31 | $driver.navigate.refresh 32 | end 33 | 34 | # step to switch to new window 35 | Then(/^I switch to new window$/) do 36 | switch_to_new_window 37 | end 38 | 39 | # step to switch to previous window 40 | Then(/^I switch to previous window$/) do 41 | switch_to_previous_window 42 | end 43 | 44 | # step to switch to main window 45 | Then(/^I switch to main window$/) do 46 | switch_to_main_window 47 | end 48 | 49 | Then(/^I switch to window having title "(.*?)"$/) do |window_title| 50 | switch_to_window_by_title window_title 51 | end 52 | 53 | Then(/^I switch to window having url "(.*?)"$/) do |window_url| 54 | switch_to_window_by_url window_url 55 | end 56 | 57 | # step to close new window 58 | Then(/^I close new window$/) do 59 | close_new_window 60 | end 61 | 62 | # step to switch to main content 63 | Then(/^I switch to main content$/) do 64 | switch_to_main_content 65 | end 66 | 67 | # step to switch to frame 68 | Then(/^I switch to frame "(.*?)"$/) do |frame| 69 | switch_frame frame 70 | end 71 | 72 | # steps to scroll to element 73 | Then(/^I scroll to element having (.+) "(.*?)"$/) do |type, access_name| 74 | validate_locator type 75 | scroll_to_element(type, access_name) 76 | end 77 | 78 | # steps to scroll web page to top or end 79 | Then(/^I scroll to (top|end) of page$/) do |to| 80 | scroll_page(to) 81 | end 82 | 83 | # step to hover over a element Note: Doesn't work on Windows firefox 84 | When(/^I hover over element having (.+) "(.*?)"$/) do |type, access_name| 85 | validate_locator type 86 | hover_over_element(type, access_name) 87 | end 88 | 89 | # steps to zoom in page 90 | Then(/^I zoom in page$/) do 91 | zoom_in_out('add') 92 | end 93 | 94 | # steps to zoom out page 95 | Then(/^I zoom out page$/) do 96 | zoom_in_out('subtract') 97 | end 98 | 99 | # method to reset page view 100 | Then(/^I reset page view$/) do 101 | zoom_in_out('numpad0') 102 | end 103 | 104 | # steps to zoom out till element displays 105 | Then(/^I zoom out page till I see element having (.+) "(.*?)"$/) do |type, access_name| 106 | validate_locator type 107 | zoom_in_out_till_element_display(type, 'subtract', access_name) 108 | end 109 | 110 | -------------------------------------------------------------------------------- /lib/selenium-cucumber/progress_steps.rb: -------------------------------------------------------------------------------- 1 | require_relative 'methods/progress_methods' 2 | 3 | # wait for specific period of time 4 | Then(/^I wait for (\d+) sec(?:onds?)?$/) do |time| 5 | wait(time) 6 | end 7 | 8 | # wait for specific element to display for specific period of time 9 | Then(/^I wait (\d+) seconds for element having (.+) "(.*?)" to display$/) do |duration, type, access_name| 10 | validate_locator type 11 | wait_for_element_to_display(type, access_name, duration) 12 | end 13 | 14 | # wait for specific element to enable for specific period of time 15 | Then(/^I wait (\d+) seconds for element having (.+) "(.*?)" to enable$/) do |duration, type, access_name| 16 | validate_locator type 17 | wait_for_element_to_enable(type, access_name, duration) 18 | end 19 | -------------------------------------------------------------------------------- /lib/selenium-cucumber/screenshot_steps.rb: -------------------------------------------------------------------------------- 1 | require_relative 'methods/screenshot_methods' 2 | 3 | Then(/^I take screenshot$/) do 4 | take_screenshot 5 | end 6 | -------------------------------------------------------------------------------- /lib/selenium-cucumber/version.rb: -------------------------------------------------------------------------------- 1 | module Selenium 2 | module Cucumber 3 | VERSION = '3.1.5' 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /selenium-cucumber.gemspec: -------------------------------------------------------------------------------- 1 | lib = File.expand_path('../lib', __FILE__) 2 | $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib) 3 | require 'selenium-cucumber/version' 4 | Gem::Specification.new do |s| 5 | s.name = 'selenium-cucumber' 6 | s.version = Selenium::Cucumber::VERSION 7 | s.date = Time.now 8 | s.platform = Gem::Platform::RUBY 9 | s.licenses = ['MIT'] 10 | s.summary = 'SELENIUM WEBDRIVER WITH RUBY & CUCUMBER' 11 | s.description = 'Behavior driven development (BDD) approach to write automation test script to test Web and Android applications.' 12 | s.authors = 'Sameer Sawant' 13 | s.homepage = 'http://seleniumcucumber.info/' 14 | s.email = 'sameersawant222@gmail.com' 15 | s.files = Dir['lib/**/*'] 16 | s.files += Dir['bin/*'] 17 | s.files += Dir['doc/*'] 18 | s.files += Dir['features-skeleton/**/*'] 19 | s.files += Dir['example/**/*'] 20 | s.executables = s.files.grep(%r{^bin/}) { |f| File.basename(f) } 21 | s.test_files = s.files.grep(%r{^(test|spec|features)/}) 22 | s.require_paths = ['lib'] 23 | s.post_install_message = 'Thank you for installing selenium-cucumber gem.' 24 | 25 | s.required_ruby_version = '>= 2.0.0' 26 | s.add_runtime_dependency 'cucumber', '>= 2.3.0' 27 | s.add_runtime_dependency 'selenium-webdriver', '>= 2.53.0' 28 | s.add_runtime_dependency 'chunky_png', '>= 1.3.5' 29 | s.add_runtime_dependency 'appium_lib', '>= 8.0.2' 30 | s.add_runtime_dependency 'rspec', '>= 3.4.0' 31 | s.add_development_dependency 'pry' 32 | # uncomment if you'd like runtime, development should be fine 33 | # s.add_runtime_dependency 'pry' 34 | end 35 | -------------------------------------------------------------------------------- /tests/Gemfile: -------------------------------------------------------------------------------- 1 | source 'http://rubygems.org' 2 | 3 | gem 'selenium-cucumber' 4 | # To run locally 5 | # gem 'selenium-cucumber', path: 'your local repo path' 6 | -------------------------------------------------------------------------------- /tests/Gemfile.lock: -------------------------------------------------------------------------------- 1 | GEM 2 | remote: http://rubygems.org/ 3 | specs: 4 | appium_lib (8.0.2) 5 | awesome_print (~> 1.6) 6 | json (~> 1.8) 7 | nokogiri (~> 1.6.6) 8 | selenium-webdriver (~> 2.49) 9 | tomlrb (~> 1.1) 10 | awesome_print (1.6.1) 11 | builder (3.2.2) 12 | childprocess (0.5.9) 13 | ffi (~> 1.0, >= 1.0.11) 14 | chunky_png (1.3.5) 15 | coderay (1.1.1) 16 | cucumber (2.3.3) 17 | builder (>= 2.1.2) 18 | cucumber-core (~> 1.4.0) 19 | cucumber-wire (~> 0.0.1) 20 | diff-lcs (>= 1.1.3) 21 | gherkin (~> 3.2.0) 22 | multi_json (>= 1.7.5, < 2.0) 23 | multi_test (>= 0.1.2) 24 | cucumber-core (1.4.0) 25 | gherkin (~> 3.2.0) 26 | cucumber-wire (0.0.1) 27 | diff-lcs (1.2.5) 28 | ffi (1.9.10) 29 | gherkin (3.2.0) 30 | json (1.8.3) 31 | method_source (0.8.2) 32 | mini_portile2 (2.0.0) 33 | multi_json (1.12.0) 34 | multi_test (0.1.2) 35 | nokogiri (1.6.7.2) 36 | mini_portile2 (~> 2.0.0.rc2) 37 | pry (0.10.3) 38 | coderay (~> 1.1.0) 39 | method_source (~> 0.8.1) 40 | slop (~> 3.4) 41 | rspec (3.4.0) 42 | rspec-core (~> 3.4.0) 43 | rspec-expectations (~> 3.4.0) 44 | rspec-mocks (~> 3.4.0) 45 | rspec-core (3.4.4) 46 | rspec-support (~> 3.4.0) 47 | rspec-expectations (3.4.0) 48 | diff-lcs (>= 1.2.0, < 2.0) 49 | rspec-support (~> 3.4.0) 50 | rspec-mocks (3.4.1) 51 | diff-lcs (>= 1.2.0, < 2.0) 52 | rspec-support (~> 3.4.0) 53 | rspec-support (3.4.1) 54 | rubyzip (1.2.0) 55 | selenium-webdriver (2.53.0) 56 | childprocess (~> 0.5) 57 | rubyzip (~> 1.0) 58 | websocket (~> 1.0) 59 | slop (3.6.0) 60 | tomlrb (1.2.1) 61 | websocket (1.2.3) 62 | 63 | PLATFORMS 64 | ruby 65 | 66 | DEPENDENCIES 67 | selenium-cucumber 68 | 69 | BUNDLED WITH 70 | 1.11.2 71 | -------------------------------------------------------------------------------- /tests/features/actual_images/test.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/selenium-cucumber/selenium-cucumber-ruby/2f43c469ca80a4f262dd4223760f90177f9cb77e/tests/features/actual_images/test.png -------------------------------------------------------------------------------- /tests/features/assertion_steps_Ex.feature: -------------------------------------------------------------------------------- 1 | 2 | Feature: Assertion Steps 3 | As a user I should able to verify using assert steps 4 | 5 | Background: Open test page 6 | Given I open test page 7 | 8 | Scenario: verify page title 9 | Then I should see page title as "Test Page for selenium–cucumber" 10 | Then I should not see page title as "wrong title" 11 | 12 | Scenario: verify partial page title 13 | Then I should see page title having partial text as "selenium–cucumber" 14 | Then I should not see page title having partial text as "Wrong title" 15 | 16 | @allow-rescue 17 | Scenario: verify page title - negative test 18 | Then I should not see page title as "wrong title" 19 | 20 | @allow-rescue 21 | Scenario: verify page title - negative test 22 | Then I should see page title as "Test Page for selenium–cucumber" 23 | 24 | @allow-rescue 25 | Scenario: verify partial page title - negative test 26 | Then I should not see page title having partial text as "Wrong title" 27 | 28 | @allow-rescue 29 | Scenario: verify partial page title - negative test 30 | Then I should see page title having partial text as "selenium–cucumber" 31 | 32 | Scenario: verify element text 33 | Then I scroll to end of page 34 | Then element having id "dbClick" should have text as "Double-click this paragraph to trigger a function." 35 | Then element having name "javascript_alert_msg" should have text as "Click the button to display a confirm box." 36 | Then element having class "form_name" should have text as "Simple sample form with input elements" 37 | Then element having xpath ".//*[@id='frm']/fieldset/p[1]/label" should have text as "Text input (first name)" 38 | 39 | Scenario: verify element should not text 40 | Then element having id "dbClick" should not have text as "Double-click this" 41 | Then element having name "javascript_alert_msg" should not have text as "Click the button" 42 | Then element having class "form_name" should not have text as "Simple sample" 43 | Then element having xpath ".//*[@id='frm']/fieldset/p[3]/label" should not have text as "xyz" 44 | 45 | Scenario: verify element text - negative test 1 46 | Then element having id "dbClick" should not have text as "Double-click this" 47 | 48 | Scenario: verify element text - negative test 2 49 | Then element having name "javascript_alert_msg" should not have text as "Click the button to display a confirm box" 50 | 51 | Scenario: Partial text present 52 | Then element having id "frm" should have partial text as "last" 53 | 54 | Scenario: Partial text present - negative test 55 | Then element having id "frm" should not have partial text as "selenium" 56 | 57 | Scenario: Partial text not present - negative test 58 | Then element having id "frm" should not have partial text as "sir name" 59 | 60 | Scenario: verify element accesibility 61 | Then element having id "submit" should be enabled 62 | Then element having name "btn_reset" should be enabled 63 | Then element having class "cls_pwd" should be enabled 64 | Then element having xpath ".//*[@id='try_it']" should be enabled 65 | Then element having id "disabledBt_id" should be disabled 66 | Then element having name "disabledBt_name" should be disabled 67 | Then element having class "df_class" should be disabled 68 | Then element having xpath ".//*[@id='df_id']" should be disabled 69 | 70 | Scenario: verify element accesibility - negative test 1 71 | Then element having id "submit" should not be disabled 72 | 73 | Scenario: verify element accesibility - negative test 2 74 | Then element having id "disabledBt_id" should be disabled 75 | 76 | Scenario: verify element visibility 77 | Then element having id "hiddenElement" should not be present 78 | Then element having name "he_name" should not be present 79 | Then element having class "he_class" should not be present 80 | Then element having xpath ".//*[@id='hiddenElement']" should not be present 81 | And I wait for 10 sec 82 | Then element having id "hiddenElement" should be present 83 | Then element having name "he_name" should be present 84 | Then element having class "he_class" should be present 85 | Then element having xpath ".//*[@id='hiddenElement']" should be present 86 | 87 | Scenario: verify checkbox checked or not 88 | Then checkbox having id "chk1" should be checked 89 | Then checkbox having name "chk5_name" should be checked 90 | Then checkbox having xpath ".//*[@id='chk1']" should be checked 91 | Then checkbox having class "chk5_class" should be checked 92 | Then checkbox having id "chk2" should be unchecked 93 | Then checkbox having name "chk3_name" should be unchecked 94 | Then checkbox having class "chk4_class" should be unchecked 95 | 96 | Scenario: verify checkbox checked or not - negative test 1 97 | Then checkbox having class "chk3_class" should be unchecked 98 | 99 | Scenario: verify checkbox checked or not - negative test 2 100 | Then checkbox having class "chk5_class" should be checked 101 | 102 | Scenario: verify radio button selected or not 103 | Then radio button having id "rdb1" should be selected 104 | Then radio button having id "rdb2" should be unselected 105 | 106 | Scenario: verify radio button selected or not - negative test 1 107 | Then radio button having id "rdb2" should be unselected 108 | 109 | Scenario: verify radio button selected or not - negative test 2 110 | Then radio button having id "rdb1" should be selected 111 | 112 | Scenario: verify link present or not 113 | Then link having text "selenium-cucumber gem" should be present 114 | Then link having text "xyz" should not be present 115 | 116 | Scenario: verify pop-up alert text 117 | When I click on element having id "try_it" 118 | Then I should see alert text as "Press a button!" 119 | Then I accept alert 120 | 121 | Scenario: verify image by id and id - jpg image 122 | Then actual image having id "img1" and expected image having id "img1" should be similar 123 | 124 | Scenario: verify image by id and image_name - jpg image 125 | Then actual image having id "img1" and expected image having image_name "original_image.jpg" should be similar 126 | 127 | Scenario: verify image by url and image_name - jpg image 128 | Then actual image having url "http://s27.postimg.org/xlqzpviyr/original_image.jpg" and expected image having image_name "original_image.jpg" should be similar 129 | 130 | Scenario: verify image by id and image_name - jpg image - negative test 131 | Then actual image having id "img1_incorrect" and expected image having image_name "original_image.jpg" should be similar 132 | 133 | Scenario: verify image by id and id - png image 134 | Then actual image having id "img2" and expected image having id "img2" should be similar 135 | 136 | Scenario: verify image by xpath and xpath - png image 137 | Then actual image having xpath ".//*[@id='img2']" and expected image having xpath ".//*[@id='img2']" should be similar 138 | 139 | Scenario: verify image by id and image_name - png image 140 | Then actual image having id "img2" and expected image having image_name "logo-PNG.png" should be similar 141 | 142 | Scenario: verify image by url and image_name - png image 143 | Then actual image having url "http://s26.postimg.org/itpfqlcop/logo1.png" and expected image having image_name "logo-PNG.png" should be similar 144 | 145 | Scenario: verify image by id and image_name - png image - negative test 146 | Then actual image having id "img2_incorrect" and expected image having image_name "logo-PNG.png" should be similar -------------------------------------------------------------------------------- /tests/features/click_steps_Ex.feature: -------------------------------------------------------------------------------- 1 | 2 | Feature: Click On Elements 3 | As a user I should able to click on elements 4 | 5 | Background: Open test page 6 | Given I open test page 7 | 8 | Scenario: click on elements based on their visible text 9 | Then I click on element having css "a" and text "selenium-cucumber gem" 10 | Then I should see page title as "selenium-cucumber | RubyGems.org | your community gem host" 11 | 12 | Scenario: click on elements 13 | Then I enter "selenium-cucumber" into input field having id "f_name" 14 | Then I click on element having id "reset" 15 | Then element having id "f_name" should have attribute "value" with value "" 16 | 17 | Scenario: double click on elements 18 | Then I double click on element having id "dbClick" 19 | Then element having name "demo2_name" should be present 20 | 21 | Scenario: click on links having text 22 | Then I click on link having text "selenium-cucumber gem" 23 | Then I should see page title as "selenium-cucumber | RubyGems.org | your community gem host" 24 | 25 | Scenario: click on links having partial text 26 | Then I click on link having partial text "cucumber website" 27 | Then I switch to new window 28 | Then I should see page title as "Selenium-Cucumber | Code Less… Test More…" 29 | 30 | -------------------------------------------------------------------------------- /tests/features/configuration_step_Ex.feature: -------------------------------------------------------------------------------- 1 | 2 | Feature: Configuration Printing Step 3 | As a user I should able to print configuration 4 | 5 | Scenario: Print Configuration 6 | Given I print configuration 7 | And I open test page -------------------------------------------------------------------------------- /tests/features/expected_images/logo-PNG.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/selenium-cucumber/selenium-cucumber-ruby/2f43c469ca80a4f262dd4223760f90177f9cb77e/tests/features/expected_images/logo-PNG.png -------------------------------------------------------------------------------- /tests/features/expected_images/original_image.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/selenium-cucumber/selenium-cucumber-ruby/2f43c469ca80a4f262dd4223760f90177f9cb77e/tests/features/expected_images/original_image.jpg -------------------------------------------------------------------------------- /tests/features/image_difference/test.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/selenium-cucumber/selenium-cucumber-ruby/2f43c469ca80a4f262dd4223760f90177f9cb77e/tests/features/image_difference/test.png -------------------------------------------------------------------------------- /tests/features/input_steps_Ex.feature: -------------------------------------------------------------------------------- 1 | 2 | Feature: Input Step 3 | As a user I should able to give inputs 4 | 5 | Background: Open test page 6 | Given I open test page 7 | 8 | Scenario: Enter text into textfield 9 | Then I enter "abc" into input field having id "f_name" 10 | Then element having id "f_name" should have attribute "value" with value "abc" 11 | Then I enter "xyz" into input field having name "lname_name" 12 | Then element having name "lname_name" should have attribute "value" with value "xyz" 13 | Then I enter "pqr" into input field having class "address_class" 14 | Then element having class "address_class" should have attribute "value" with value "pqr" 15 | 16 | 17 | Scenario: Clear text From textfield 18 | Then I clear input field having id "f_name" 19 | Then element having id "f_name" should have attribute "value" with value "" 20 | Then I clear input field having name "lname_name" 21 | Then element having name "lname_name" should have attribute "value" with value "" 22 | Then I clear input field having class "address_class" 23 | Then element having class "address_class" should have attribute "value" with value "" 24 | 25 | Scenario: select option from dropdown list 26 | Then I select "Select_5" option by text from dropdown having id "dropdownList1" 27 | Then option "Select_5" by text from dropdown having id "dropdownList1" should be selected 28 | Then I select 1 option by index from dropdown having id "dropdownList1" 29 | Then option "Select_1" by text from dropdown having id "dropdownList1" should be selected 30 | Then I select "s3" option by value from dropdown having id "dropdownList1" 31 | Then option "s3" by value from dropdown having id "dropdownList1" should be selected 32 | 33 | Scenario: select option from Multiselect List 34 | Then I select "Volvo" option by text from multiselect dropdown having name "cars" 35 | Then I select 4 option by index from multiselect dropdown having name "cars" 36 | Then I select "opel" option by value from multiselect dropdown having name "cars" 37 | 38 | Scenario: unselect all options from Multiselect List 39 | Then I unselect all options from multiselect dropdown having name "cars" 40 | 41 | Scenario: select all options from Multiselect List 42 | Then I select all options from multiselect dropdown having name "cars" 43 | 44 | Scenario: selecting checkbox 45 | Then I check the checkbox having id "chk3" 46 | Then checkbox having id "chk3" should be checked 47 | Then I check the checkbox having name "chk2_name" 48 | Then checkbox having name "chk2_name" should be checked 49 | 50 | Scenario: unselecting checkbox 51 | Then I uncheck the checkbox having class "chk5_class" 52 | Then checkbox having class "chk5_class" should be unchecked 53 | 54 | Scenario: toggle checkbox 55 | Then I toggle checkbox having id "chk4" 56 | Then checkbox having id "chk4" should be checked 57 | Then I toggle checkbox having id "chk4" 58 | Then checkbox having id "chk4" should be unchecked 59 | 60 | Scenario: selecting radio buttons 61 | Then I select radio button having id "rdb2" 62 | Then radio button having id "rdb2" should be selected 63 | Then I select radio button having name "rdb3_name" 64 | Then radio button having name "rdb3_name" should be selected 65 | Then I select radio button having class "rdb4_class" 66 | Then radio button having class "rdb4_class" should be selected 67 | -------------------------------------------------------------------------------- /tests/features/javascript_steps_Ex.feature: -------------------------------------------------------------------------------- 1 | 2 | Feature: Javasciprt Handling Steps 3 | As a user I should able to handle javascript pop-up 4 | 5 | Scenario: Open test page 6 | Given I open test page 7 | 8 | Scenario: accept alert 9 | Then I click on element having id "try_it" 10 | Then I accept alert 11 | Then element having id "demo" should have text as "You pressed OK!" 12 | 13 | Scenario: dismiss alert 14 | Then I click on element having id "try_it" 15 | Then I dismiss alert 16 | Then element having id "demo" should have text as "You pressed Cancel!" 17 | 18 | -------------------------------------------------------------------------------- /tests/features/navigation_steps_Ex.feature: -------------------------------------------------------------------------------- 1 | Feature: Navigation Steps 2 | As a user I should able to navigate on web page 3 | 4 | Background: Open test page 5 | Given I open test page 6 | 7 | Scenario: navigating back/forward page 8 | Then I click on link having text "selenium-cucumber gem" 9 | Then I should see page title as "selenium-cucumber | RubyGems.org | your community gem host" 10 | 11 | Then I navigate back 12 | Then I should see page title as "Test Page for selenium–cucumber" 13 | 14 | Then I navigate forward 15 | Then I should see page title as "selenium-cucumber | RubyGems.org | your community gem host" 16 | 17 | Then I navigate back 18 | Then I should see page title as "Test Page for selenium–cucumber" 19 | 20 | Scenario: refresh page 21 | Then I refresh page 22 | Then I should see page title as "Test Page for selenium–cucumber" 23 | 24 | Scenario: switch to new window 25 | Then I click on link having text "selenium-cucumber website" 26 | Then I switch to new window 27 | Then I should see page title as "Selenium-Cucumber | Code Less… Test More…" 28 | 29 | Scenario: switch to privous window 30 | Then I click on link having text "selenium-cucumber website" 31 | Then I switch to window having title "Test Page for selenium–cucumber" 32 | Then link having text "blog" should be present 33 | 34 | Scenario: switch to window by title (Main window) 35 | Then I switch to window having title "Test Page for selenium–cucumber" 36 | Then link having text "blog" should be present 37 | 38 | Scenario: switch to window by absolute url 39 | Then I click on link having text "selenium-cucumber website" 40 | Then I switch to window having url "https://seleniumcucumber.info/" 41 | Then link having text "Desktop Web Automation" should be present 42 | 43 | Scenario: switch to window by relative url 44 | Then I click on link having text "selenium-cucumber website" 45 | Then I switch to window having url "info/" 46 | Then link having text "Desktop Web Automation" should be present 47 | 48 | Scenario: switch to first frame 49 | Then I switch to frame "frame_one" 50 | Then I enter "first frame" into input field having id "frame1_fname" 51 | 52 | Scenario: switch to main content 53 | Then I switch to main content 54 | Then I enter "test" into input field having id "f_name" 55 | 56 | Scenario: switch to second frame 57 | Then I switch to frame "frame_two" 58 | Then I enter "test@gmail.com" into input field having id "frame2_email" 59 | 60 | Scenario: again switch to main content 61 | Then I switch to main content 62 | 63 | Scenario: Zoom in/out web page 64 | Then I zoom in page 65 | Then I zoom out page 66 | Then I reset page view 67 | 68 | Scenario: Scroll web page 69 | Then I scroll to element having id "demo" 70 | Then I scroll to top of page 71 | Then I scroll to end of page 72 | 73 | Scenario: Hover over elelment 74 | Then element having id "mouse_hover_demo" should have text as "Mouse Not hovered" 75 | Then I hover over element having id "hover_it" 76 | Then element having id "mouse_hover_demo" should have text as "Mouse hovered" 77 | 78 | Scenario: Interacting with browser 79 | Then I resize browser window size to width 400 and height 400 80 | Then I maximize browser window -------------------------------------------------------------------------------- /tests/features/progress_step_Ex.feature: -------------------------------------------------------------------------------- 1 | 2 | Feature: Progress Steps 3 | As a user I should able to wait 4 | 5 | Background: Open test page 6 | Given I open test page 7 | 8 | Scenario: wait for elements to display 9 | Then element having id "hiddenElement" should not be present 10 | Then I wait 15 seconds for element having id "hiddenElement" to display 11 | Then element having id "hiddenElement" should be present 12 | 13 | Scenario: wait for elements to enabled 14 | Then element having id "disabledBt" should be disabled 15 | Then I wait 30 seconds for element having id "disabledBt" to enable 16 | Then element having id "disabledBt" should be enabled -------------------------------------------------------------------------------- /tests/features/screenshot_step_Ex.feature: -------------------------------------------------------------------------------- 1 | Feature: Screenshot Step 2 | As a user I should able to take screenshot 3 | 4 | Background: Open test page 5 | Given I open test page 6 | 7 | Scenario: take screenshot 8 | Then I take screenshot 9 | 10 | Scenario: close browser 11 | Then I close browser 12 | 13 | -------------------------------------------------------------------------------- /tests/features/screenshots/test.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/selenium-cucumber/selenium-cucumber-ruby/2f43c469ca80a4f262dd4223760f90177f9cb77e/tests/features/screenshots/test.png -------------------------------------------------------------------------------- /tests/features/step_definitions/custom_steps.rb: -------------------------------------------------------------------------------- 1 | require 'selenium-cucumber' 2 | require 'appium_lib' 3 | # Do Not Remove This File 4 | # Add your custom steps here 5 | # $driver is instance of webdriver use this instance to write your custom code 6 | 7 | Given(/^I open test page$/) do 8 | link = 'file:///' 9 | link+= File.absolute_path("test_page.html") 10 | navigate_to(link) 11 | end 12 | 13 | # Then(/^I press "(.*?)" key from keyboard$/) do |key| 14 | # $driver.action.send_keys(:"#{key}").perform 15 | # end 16 | 17 | # Then(/^Then I press combination of "(.*?)" and "(.*?)" keys from keyboard$/) do |key1, key2| 18 | # $driver.action.key_down(:"#{get_key}").send_keys(:"#{in_out}").key_up(:"#{get_key}").perform 19 | # end 20 | 21 | # Then(/^I long press on element having (.+) "(.*?)"$/) do |type, access_name| 22 | # validate_locator type 23 | # long_press_1(type, access_name, 5) 24 | # end 25 | 26 | # def long_press_1(type, access_name, duration) 27 | # element = WAIT.until { $driver.find_element(:"#{type}" => "#{access_name}") } 28 | # #parameters = { "element" => "#{element}", "duration" => "#{duration}" } 29 | # #args = parameters.select { |k, v| [:element, :duration].include? k } 30 | # #args = args_with_ele_ref(args) 31 | # #chain_method(:longPress, args) 32 | # #Appium::TouchAction.new.tap(element: "#{element}", count: "#{duration}").perform 33 | # Appium::TouchAction.new.long_press(element:element, x:10, y:10, duration:duration).perform() 34 | # end 35 | -------------------------------------------------------------------------------- /tests/features/support/env.rb: -------------------------------------------------------------------------------- 1 | require 'rubygems' 2 | require 'selenium-cucumber' 3 | 4 | # Store command line arguments 5 | $browser_type = ENV['BROWSER'] || 'ff' 6 | $platform = ENV['PLATFORM'] || 'desktop' 7 | $os_version = ENV['OS_VERSION'] 8 | $device_name = ENV['DEVICE_NAME'] 9 | $udid = ENV['UDID'] 10 | $app_path = ENV['APP_PATH'] 11 | 12 | # check for valid parameters 13 | validate_parameters $platform, $browser_type, $app_path 14 | 15 | # If platform is android or ios create driver instance for mobile browser 16 | if $platform == 'android' or $platform == 'iOS' 17 | 18 | if $browser_type == 'native' 19 | $browser_type = "Browser" 20 | end 21 | 22 | if $platform == 'android' 23 | $device_name, $os_version = get_device_info 24 | end 25 | 26 | desired_caps = { 27 | caps: { 28 | platformName: $platform, 29 | browserName: $browser_type, 30 | versionNumber: $os_version, 31 | deviceName: $device_name, 32 | udid: $udid, 33 | app: ".//#{$app_path}" 34 | }, 35 | } 36 | 37 | begin 38 | $driver = Appium::Driver.new(desired_caps).start_driver 39 | rescue Exception => e 40 | puts e.message 41 | Process.exit(0) 42 | end 43 | else # else create driver instance for desktop browser 44 | begin 45 | $driver = Selenium::WebDriver.for(:"#{$browser_type}") 46 | $driver.manage().window().maximize() 47 | $driver.manage.timeouts.implicit_wait = 30 48 | rescue Exception => e 49 | puts e.message 50 | Process.exit(0) 51 | end 52 | end 53 | -------------------------------------------------------------------------------- /tests/features/support/hooks.rb: -------------------------------------------------------------------------------- 1 | #Cucumber provides a number of hooks which allow us to run blocks at various points in the Cucumber test cycle 2 | 3 | Before do 4 | # Do something before each scenario. 5 | end 6 | 7 | Before do |scenario| 8 | # The +scenario+ argument is optional, but if you use it, you can get the title, 9 | # description, or name (title + description) of the scenario that is about to be 10 | # executed. 11 | end 12 | 13 | After do |scenario| 14 | # Do something after each scenario. 15 | # The +scenario+ argument is optional, but 16 | # if you use it, you can inspect status with 17 | # the #failed?, #passed? and #exception methods. 18 | 19 | if(scenario.failed?) 20 | #Do something if scenario fails. 21 | end 22 | end 23 | 24 | #Tagged hooks 25 | 26 | Before('@Ex_tag1, @Ex_tag2') do 27 | # This will only run before scenarios tagged 28 | # with @Ex_tag1 OR @Ex_tag2. 29 | end 30 | 31 | AfterStep('@Ex_tag1, @Ex_tag2') do |scenario| 32 | # This will only run after steps within scenarios tagged 33 | # with @Ex_tag1 AND @Ex_tag2. 34 | end 35 | 36 | Around('@Ex_tag1') do |scenario, block| 37 | # Will round around a scenario 38 | end 39 | 40 | AfterConfiguration do |c| 41 | # Will run after cucumber has been configured 42 | end 43 | 44 | # Quit the selenium driver from the example tests. 45 | at_exit do 46 | 47 | end 48 | -------------------------------------------------------------------------------- /tests/iFrame1.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 |

iFrame 1

5 | Enter First Name 6 |
7 | Enter Last Name 8 | 9 | 10 | -------------------------------------------------------------------------------- /tests/iFrame2.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 |

iFrame 2

5 | Enter Email 6 |
7 | Enter Phone Number 8 | 9 | 10 | -------------------------------------------------------------------------------- /tests/run_features.rb: -------------------------------------------------------------------------------- 1 | require 'selenium-webdriver' 2 | 3 | puts ARGV[0] 4 | 5 | OS = $driver.capabilities.platform.to_s.upcase 6 | 7 | system("bundle update") 8 | 9 | if ARGV.length == 0 10 | 11 | puts "\n\n\t###### Running all features on firefox browser ######\n\n" 12 | system('cucumber') 13 | 14 | puts "\n\n\t###### Running all features on chrome browser ###### \n\n" 15 | system('cucumber BROWSER=chrome') 16 | 17 | if OS.to_s == 'windows' 18 | puts "Running all features on internet explorer browser ###### \n\n" 19 | system('cucumber BROWSER=ie') 20 | elsif OS.to_s == 'mac' 21 | puts "Running all features on safari browser ###### \n\n" 22 | system('cucumber BROWSER=safari') 23 | end 24 | 25 | elsif ARGV.shift == 'html' 26 | 27 | puts "\n\n\t###### Running all features on firefox browser ###### \n\n" 28 | puts "Output result stored in \"result_firefox.html\"" 29 | system('cucumber -f html -o result_firefox.html') 30 | 31 | puts "\n\n\t###### Running all features on chrome browser ###### \n\n" 32 | puts "Output result stored in \"result_chrome.html\"" 33 | system('cucumber BROWSER=chrome -f html -o result_chrome.html') 34 | 35 | if OS.to_s == 'windows' 36 | puts "\n\n\t###### Running all features on internet explorer browser ###### \n\n" 37 | puts "Output result stored in \"result_ie.html\"" 38 | system('cucumber BROWSER=ie -f html -o result_ie.html') 39 | elsif OS.to_s == 'mac' 40 | puts "\n\n\t###### Running all features on safari browser ###### \n\n" 41 | puts "Output result stored in \"result_safari.html\"" 42 | system('cucumber BROWSER=safari -f html -o result_safari.html') 43 | end 44 | end 45 | -------------------------------------------------------------------------------- /tests/test_page.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Test Page for selenium–cucumber 6 | 7 | 8 | 21 | 22 | 27 | 28 | 29 | 52 |
53 |
54 | Simple sample form with input elements 55 |

56 |
57 | 58 |

59 | 60 |

61 |
62 | 63 |

64 | 65 |

66 |
67 | 68 |

69 | 70 |

71 |
72 | 73 |

74 | 75 |

76 |
77 | 78 |

79 | 80 |

81 |
82 | Male 83 | Female 84 |

85 | 86 |

87 | 88 | 89 | 90 |

91 |
92 |
93 | 94 |
95 | 96 |
97 | Multiselect dropdown 98 |

99 | 105 |

106 |
107 | 108 |
109 | 110 |
111 | Dropdown lists 112 |

113 |
114 | 121 |

122 |
123 | 124 |
125 | 126 |
127 | Radio Buttons 128 |

129 | Radio one
130 | Radio two
131 | Radio three
132 | Radio four
133 | Radio five
134 |

135 |
136 | 137 |
138 | 139 |
140 | Checkbox 141 |

142 | Check one
143 | Check two
144 | Check three
145 | Check four
146 | Check five
147 |

148 |
149 | 150 |
151 | 152 |
153 | Display element after 10 sec 154 |
This showed after 10 sec
155 |
156 | 157 |
158 | 159 |
160 | Enable Button after 10 sec 161 | 162 |

163 |
164 | 165 |
166 | 167 |
168 | Images - valid 169 | JPG image Image one 170 | PNG image Image one 171 |
172 | 173 |
174 | 175 |
176 | Images - Invalid 177 | JPG image Image one 178 | PNG image Image one 179 |
180 | 181 |
182 | 183 |
184 | Links 185 |

186 | selenium-cucumber gem
187 | 188 | Predefined-steps
189 | 190 | selenium-cucumber website
191 | 192 | video tutorials
193 | 194 | blog
195 |

196 |
197 | 198 |
199 | 200 |
201 | Mous hover 202 | 203 |

Mouse Not hovered

204 |
205 | 206 |
207 | 208 |
209 | Javascript alert 210 |

Click the button to display a confirm box.

211 | 212 |

this is demo line

213 |

214 |
215 | 216 |
217 | 218 |
219 | Double click here 220 |

Double-click this paragraph to trigger a function.

221 |

222 |

223 |
224 | 225 |
226 | iFrames 227 | 228 | 229 | 230 |
231 | 232 | 233 | --------------------------------------------------------------------------------