selenium-cucumber 0.0.9 → 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (37) hide show
  1. data/Example/features/assertion_steps_Ex.feature +121 -0
  2. data/Example/features/click_steps_Ex.feature +28 -0
  3. data/Example/features/configuration_step_Ex.feature +9 -0
  4. data/Example/features/input_steps_Ex.feature +87 -0
  5. data/Example/features/javascript_steps_Ex.feature +19 -0
  6. data/Example/features/navigation_steps_Ex.feature +45 -0
  7. data/Example/features/new.feature +7 -0
  8. data/Example/features/progress_step_Ex.feature +18 -0
  9. data/Example/features/screenshot_step_Ex.feature +11 -0
  10. data/Example/features/step_definitions/custom_steps.rb +14 -0
  11. data/Example/features/support/env.rb +38 -0
  12. data/Example/features/support/hooks.rb +34 -0
  13. data/Example/run_features.rb +40 -0
  14. data/Example/test_page.html +206 -0
  15. data/bin/generate.rb +20 -20
  16. data/bin/helper.rb +50 -50
  17. data/bin/selenium-cucumber +26 -26
  18. data/doc/canned_steps.md +479 -463
  19. data/doc/installation.md +16 -16
  20. data/doc/selenium-cucumber-API.md +81 -81
  21. data/doc/selenium-cucumber-help.md +18 -18
  22. data/features-skeleton/my_first.feature +5 -5
  23. data/features-skeleton/step_definitions/custom_steps.rb +4 -4
  24. data/features-skeleton/support/env.rb +38 -38
  25. data/features-skeleton/support/hooks.rb +33 -33
  26. data/lib/selenium-cucumber.rb +2 -2
  27. data/lib/selenium-cucumber/assertion_steps.rb +7 -2
  28. data/lib/selenium-cucumber/click_elements_steps.rb +7 -0
  29. data/lib/selenium-cucumber/methods/assertion_methods.rb +74 -24
  30. data/lib/selenium-cucumber/methods/click_elements_methods.rb +7 -2
  31. data/lib/selenium-cucumber/methods/configuration_methods.rb +1 -0
  32. data/lib/selenium-cucumber/methods/navigate_methods.rb +22 -32
  33. data/lib/selenium-cucumber/methods/required_files.rb +2 -0
  34. data/lib/selenium-cucumber/navigation_steps.rb +8 -0
  35. data/lib/selenium-cucumber/progress_steps.rb +2 -2
  36. data/lib/selenium-cucumber/version.rb +1 -1
  37. metadata +27 -45
data/doc/installation.md CHANGED
@@ -1,16 +1,16 @@
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
-
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
+
@@ -1,82 +1,82 @@
1
- selenium-cucumber API
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
- submit(by,access_value)
38
-
39
- enter_text(by,text,access_value)
40
-
41
- clear_text(by,access_value)
42
-
43
- check_checkbox(by, access_value)
44
-
45
- uncheck_checkbox(by, access_value)
46
-
47
- toggle_checkbox(by, access_value)
48
-
49
- select_radio_button(by, access_value)
50
-
51
- get_page_title()
52
-
53
- get_element_text(by,access_value)
54
-
55
- get_element_attribute(by,access_value,attribute)
56
-
57
- is_element_enabled(by,access_value)
58
-
59
- is_element_displayed(by,access_value)
60
-
61
-
62
- Javascript Handling API
63
- -----------------------
64
-
65
- handle_alert(decision) # decision => "accept"/"dismiss"
66
-
67
- get_alert_text
68
-
69
-
70
- Progress API's
71
- --------------
72
-
73
- wait(time_in_sec)
74
-
75
- wait_for_element_to_display(by,access_value,duration)
76
-
77
- wait_for_element_to_enable(by,access_value,duration)
78
-
79
-
80
- Screenshot API
81
- --------------
1
+ selenium-cucumber API
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
+ submit(by,access_value)
38
+
39
+ enter_text(by,text,access_value)
40
+
41
+ clear_text(by,access_value)
42
+
43
+ check_checkbox(by, access_value)
44
+
45
+ uncheck_checkbox(by, access_value)
46
+
47
+ toggle_checkbox(by, access_value)
48
+
49
+ select_radio_button(by, access_value)
50
+
51
+ get_page_title()
52
+
53
+ get_element_text(by,access_value)
54
+
55
+ get_element_attribute(by,access_value,attribute)
56
+
57
+ is_element_enabled(by,access_value)
58
+
59
+ is_element_displayed(by,access_value)
60
+
61
+
62
+ Javascript Handling API
63
+ -----------------------
64
+
65
+ handle_alert(decision) # decision => "accept"/"dismiss"
66
+
67
+ get_alert_text
68
+
69
+
70
+ Progress API's
71
+ --------------
72
+
73
+ wait(time_in_sec)
74
+
75
+ wait_for_element_to_display(by,access_value,duration)
76
+
77
+ wait_for_element_to_enable(by,access_value,duration)
78
+
79
+
80
+ Screenshot API
81
+ --------------
82
82
  take_screenshots
@@ -1,18 +1,18 @@
1
-
2
- Usage: selenium-cucumber <command-name> [parameters] [options]
3
-
4
- <command-name> 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 selnium-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
1
+
2
+ Usage: selenium-cucumber <command-name> [parameters] [options]
3
+
4
+ <command-name> 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 selnium-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
@@ -1,5 +1,5 @@
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"
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"
@@ -1,5 +1,5 @@
1
- require 'selenium-cucumber'
2
-
3
- # Do Not Remove This File
4
- # Add your custom steps here
1
+ require 'selenium-cucumber'
2
+
3
+ # Do Not Remove This File
4
+ # Add your custom steps here
5
5
  # $driver is instance of webdriver use this instance to write your custom code
@@ -1,38 +1,38 @@
1
- require 'rubygems'
2
- require 'selenium-webdriver'
3
-
4
- def print_error
5
- puts "\nInappropraite browser \"#{ENV['BROWSER']}\""
6
- puts "\nUsage : cucumber BROWSER=browser_name"
7
- puts "\nbrowser_name can be one of following :"
8
- puts "1.ie\n2.chrome\n3.ff\n4.safari\n5.opera"
9
- puts "\nNow using default browser \"Firefox\""
10
- end
11
-
12
- case ENV['BROWSER']
13
- when 'ie'
14
- browser_type = :ie
15
- when 'ff'
16
- browser_type = :ff
17
- when 'chrome'
18
- browser_type = :chrome
19
- when 'opera'
20
- browser_type = :opera
21
- when 'safari'
22
- browser_type = :safari
23
- else
24
- if ENV['BROWSER']
25
- print_error
26
- end
27
- browser_type = :ff
28
- end
29
-
30
-
31
- begin
32
- $driver = Selenium::WebDriver.for(browser_type)
33
- $driver.manage().window().maximize()
34
-
35
- rescue Exception => e
36
- puts e.message
37
- end
38
-
1
+ require 'rubygems'
2
+ require 'selenium-webdriver'
3
+
4
+ def print_error
5
+ puts "\nInappropraite browser \"#{ENV['BROWSER']}\""
6
+ puts "\nUsage : cucumber BROWSER=browser_name"
7
+ puts "\nbrowser_name can be one of following :"
8
+ puts "1.ie\n2.chrome\n3.ff\n4.safari\n5.opera"
9
+ puts "\nNow using default browser \"Firefox\""
10
+ end
11
+
12
+ case ENV['BROWSER']
13
+ when 'ie'
14
+ browser_type = :ie
15
+ when 'ff'
16
+ browser_type = :ff
17
+ when 'chrome'
18
+ browser_type = :chrome
19
+ when 'opera'
20
+ browser_type = :opera
21
+ when 'safari'
22
+ browser_type = :safari
23
+ else
24
+ if ENV['BROWSER']
25
+ print_error
26
+ end
27
+ browser_type = :ff
28
+ end
29
+
30
+
31
+ begin
32
+ $driver = Selenium::WebDriver.for(browser_type)
33
+ $driver.manage().window().maximize()
34
+
35
+ rescue Exception => e
36
+ puts e.message
37
+ end
38
+
@@ -1,34 +1,34 @@
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 @cucumis OR @sativus.
29
- end
30
-
31
- AfterStep('@Ex_tag1, @Ex_tag2') do
32
- # This will only run after steps within scenarios tagged
33
- # with @cucumis AND @sativus.
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 @cucumis OR @sativus.
29
+ end
30
+
31
+ AfterStep('@Ex_tag1, @Ex_tag2') do
32
+ # This will only run after steps within scenarios tagged
33
+ # with @cucumis AND @sativus.
34
34
  end
@@ -1,2 +1,2 @@
1
-
2
- Dir[File.dirname(__FILE__) + '/selenium-cucumber/*.rb'].each {|file| require file }
1
+
2
+ Dir[File.dirname(__FILE__) + '/selenium-cucumber/*.rb'].each {|file| require file }
@@ -68,9 +68,14 @@ Then(/^I should see alert text as "(.*?)"$/) do |actual_value|
68
68
  check_alert_text(actual_value)
69
69
  end
70
70
 
71
- #Step tp assert dropdown list
71
+ #Step to assert dropdown list
72
72
  Then(/^option "(.*?)" by (.+) from dropdown having (.+) "(.*?)" should be (selected|unselected)$/) do |option, by, type, access_name, state|
73
73
  validate_locator type
74
74
  flag = state == "selected"
75
75
  is_option_from_dropdown_selected(type,by,option,access_name,state)
76
- end
76
+ end
77
+
78
+ #Step to assert difference in images
79
+ 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|
80
+ does_images_similar?(actual_img_access_type, actual_img_access_name, excp_img_access_type, excp_img_access_name)
81
+ end
@@ -12,6 +12,13 @@ Then(/^I forcefully click on element having (.+) "(.*?)"$/) do |type, access_nam
12
12
  click_forcefully(type, access_name)
13
13
  end
14
14
 
15
+ # double click on web element
16
+
17
+ Then(/^I double click on element having (.+) "(.*?)"$/) do |type, access_value|
18
+ validate_locator type
19
+ double_click(type, access_value)
20
+ end
21
+
15
22
  #steps to click on link
16
23
 
17
24
  Then(/^I click on link having text "(.*?)"$/) do |access_name|
@@ -13,7 +13,7 @@ def check_title(title)
13
13
  end
14
14
 
15
15
  #method to get element text
16
- def get_element_text(access_type,access_name)
16
+ def get_element_text(access_type,access_name)
17
17
  return WAIT.until {$driver.find_element(:"#{access_type}" => "#{access_name}")}.text
18
18
  end
19
19
 
@@ -22,11 +22,11 @@ def check_element_text(access_type, actual_value, access_name, test_case)
22
22
  element_text = get_element_text(access_type,access_name)
23
23
 
24
24
  if test_case
25
- if(element_text!=actual_value)
25
+ if(element_text!=actual_value)
26
26
  raise TestCaseFailed ,"Text Not Matched"
27
27
  end
28
28
  else
29
- if(element_text==actual_value)
29
+ if(element_text==actual_value)
30
30
  raise TestCaseFailed ,"Text Matched"
31
31
  end
32
32
  end
@@ -37,17 +37,17 @@ def is_element_enabled(access_type,access_name)
37
37
  return WAIT.until{$driver.find_element(:"#{access_type}" => "#{access_name}")}.enabled?
38
38
  end
39
39
 
40
- #Element enabled checking
40
+ #Element enabled checking
41
41
  def check_element_enable(access_type, access_name, test_case)
42
-
42
+
43
43
  result=is_element_enabled(access_type,access_name)
44
44
 
45
45
  if test_case
46
- if(!result)
46
+ if(!result)
47
47
  raise TestCaseFailed ,"Element Not Enabled"
48
48
  end
49
49
  else
50
- if(result)
50
+ if(result)
51
51
  raise TestCaseFailed ,"Element Enabled"
52
52
  end
53
53
  end
@@ -60,15 +60,15 @@ end
60
60
 
61
61
  #method to check attribute value
62
62
  def check_element_attribute(access_type, attribute_name, attribute_value, access_name, test_case)
63
-
63
+
64
64
  attr_val=get_element_attribute(access_type, access_name, attribute_name)
65
-
65
+
66
66
  if test_case
67
- if(attr_val!=attribute_value)
67
+ if(attr_val!=attribute_value)
68
68
  raise TestCaseFailed ,"Attribute Value Not Matched"
69
69
  end
70
70
  else
71
- if(attr_val==attribute_value)
71
+ if(attr_val==attribute_value)
72
72
  raise TestCaseFailed ,"Attribute Value Matched"
73
73
  end
74
74
  end
@@ -88,7 +88,7 @@ def check_element_presence(access_type, access_name, test_case)
88
88
  else
89
89
  begin
90
90
  if is_element_displayed(access_type,access_name)
91
- raise "Present"
91
+ raise "Present"
92
92
  end
93
93
  rescue Exception => e
94
94
  if e.message=="present"
@@ -101,7 +101,7 @@ end
101
101
  #method to assert checkbox check/uncheck
102
102
  def is_checkbox_checked(access_type, access_name, should_be_checked=true)
103
103
  checkbox = WAIT.until{$driver.find_element(:"#{access_type}" => "#{access_name}")}
104
-
104
+
105
105
  if !checkbox.selected? && should_be_checked
106
106
  raise TestCaseFailed ,"Checkbox is not checked"
107
107
  elsif checkbox.selected? && !should_be_checked
@@ -112,7 +112,7 @@ end
112
112
  #method to assert radio button selected/unselected
113
113
  def is_radio_button_selected(access_type, access_name, should_be_selected=true)
114
114
  radio_button = WAIT.until{$driver.find_element(:"#{access_type}" => "#{access_name}")}
115
-
115
+
116
116
  if !radio_button.selected? && should_be_selected
117
117
  raise TestCaseFailed ,"Radio Button not selected"
118
118
  elsif radio_button.selected? && !should_be_selected
@@ -124,11 +124,11 @@ end
124
124
  #method to assert option from radio button group is selected/unselected
125
125
  def is_option_from_radio_button_group_selected(access_type, by, option, access_name, should_be_selected=true)
126
126
  radio_button_group = WAIT.until{$driver.find_elements(:"#{access_type}" => "#{access_name}")}
127
-
128
- getter = ->(rb, by) { by == 'value' ? rb.attribute('value') : rb.text }
129
-
127
+
128
+ getter = ->(rb, by) { by == 'value' ? rb.attribute('value') : rb.text }
129
+
130
130
  ele = radio_button_group.find { |rb| getter.call(rb, by) == option }
131
-
131
+
132
132
  if !ele.selected? && should_be_selected
133
133
  raise TestCaseFailed ,'Radio button is not selected'
134
134
  elsif ele.selected? && !should_be_selected
@@ -151,18 +151,68 @@ end
151
151
  def is_option_from_dropdown_selected(access_type, by, option, access_name, should_be_selected=true)
152
152
  dropdown = WAIT.until {$driver.find_element(:"#{access_type}" => "#{access_name}")}
153
153
  select_list = Selenium::WebDriver::Support::Select.new(dropdown)
154
-
155
- puts select_list.first_selected_option.attribute("value")
156
154
 
157
155
  if by=="text"
158
156
  actual_value = select_list.first_selected_option.text
159
157
  else
160
158
  actual_value = select_list.first_selected_option.attribute("value")
161
159
  end
162
-
160
+
163
161
  if !actual_value==option && should_be_selected
164
- raise "Option Not Selected From Dropwdown"
162
+ raise TestCaseFailed , "Option Not Selected From Dropwdown"
165
163
  elsif actual_value==option && !should_be_selected
166
- raise "Option Selected From Dropwdown"
164
+ raise TestCaseFailed , "Option Selected From Dropwdown"
167
165
  end
168
- end
166
+ end
167
+
168
+ #Method to find difference between images
169
+ def does_images_similar?(actual_img_access_type, actual_img_access_name, excp_img_access_type, excp_img_access_name)
170
+ if !compare_image(actual_img_access_type, actual_img_access_name, excp_img_access_type, excp_img_access_name)
171
+ raise TestCaseFailed , "Actual image is different from expected image"
172
+ end
173
+ end
174
+
175
+ #Method to compare two images
176
+ def compare_image(actual_img_access_type, actual_img_access_name, excp_img_access_type, excp_img_access_name)
177
+
178
+ if actual_img_access_type!="path"
179
+ actual_img_url = get_element_attribute(actual_img_access_type, actual_img_access_name, "src")
180
+ else
181
+ actual_img_url = actual_img_access_name
182
+ end
183
+
184
+ if excp_img_access_type!="path"
185
+ expected_img_url = get_element_attribute(excp_img_access_type, excp_img_access_name, "src")
186
+ else
187
+ expected_img_url = excp_img_access_name
188
+ end
189
+
190
+ images = [
191
+ ChunkyPNG::Image.from_file(open(actual_img_url)),
192
+ ChunkyPNG::Image.from_file(open(expected_img_url))
193
+ ]
194
+
195
+ diff = []
196
+
197
+ images.first.height.times do |y|
198
+ images.first.row(y).each_with_index do |pixel, x|
199
+ diff << [x,y] unless pixel == images.last[x,y]
200
+ end
201
+ end
202
+
203
+ if diff.length != 0
204
+ puts "\npixels (total): #{images.first.pixels.length}"
205
+ puts "pixels changed: #{diff.length}"
206
+ puts "pixels changed (%): #{(diff.length.to_f / images.first.pixels.length) * 100}%"
207
+
208
+ x, y = diff.map{ |xy| xy[0] }, diff.map{ |xy| xy[1] }
209
+ images.last.rect(x.min, y.min, x.max, y.max, ChunkyPNG::Color.rgb(0,255,0))
210
+ curTime = Time.now.strftime('%Y%m%d%H%M%S%L')
211
+ images.last.save("difference_#{curTime}.png")
212
+
213
+ puts "\nDifference between images saved as : difference_#{curTime}.png\n"
214
+ return false
215
+ else
216
+ return true
217
+ end
218
+ end