selenium-cucumber 0.0.9 → 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
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