lapis_lazuli 0.6.1

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 (79) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +18 -0
  3. data/Gemfile +4 -0
  4. data/Gemfile.lock +42 -0
  5. data/LICENSE +30 -0
  6. data/README.md +74 -0
  7. data/Rakefile +1 -0
  8. data/bin/lapis_lazuli +3 -0
  9. data/lapis_lazuli.gemspec +32 -0
  10. data/lib/lapis_lazuli/api.rb +52 -0
  11. data/lib/lapis_lazuli/argparse.rb +128 -0
  12. data/lib/lapis_lazuli/ast.rb +160 -0
  13. data/lib/lapis_lazuli/browser/error.rb +93 -0
  14. data/lib/lapis_lazuli/browser/find.rb +500 -0
  15. data/lib/lapis_lazuli/browser/interaction.rb +91 -0
  16. data/lib/lapis_lazuli/browser/screenshots.rb +70 -0
  17. data/lib/lapis_lazuli/browser/wait.rb +158 -0
  18. data/lib/lapis_lazuli/browser.rb +246 -0
  19. data/lib/lapis_lazuli/cli.rb +110 -0
  20. data/lib/lapis_lazuli/cucumber.rb +25 -0
  21. data/lib/lapis_lazuli/generators/cucumber/template/.gitignore +6 -0
  22. data/lib/lapis_lazuli/generators/cucumber/template/Gemfile +37 -0
  23. data/lib/lapis_lazuli/generators/cucumber/template/README.md +27 -0
  24. data/lib/lapis_lazuli/generators/cucumber/template/config/config.yml +29 -0
  25. data/lib/lapis_lazuli/generators/cucumber/template/config/cucumber.yml +34 -0
  26. data/lib/lapis_lazuli/generators/cucumber/template/features/example.feature +11 -0
  27. data/lib/lapis_lazuli/generators/cucumber/template/features/step_definitions/interaction_steps.rb +20 -0
  28. data/lib/lapis_lazuli/generators/cucumber/template/features/step_definitions/validation_steps.rb +21 -0
  29. data/lib/lapis_lazuli/generators/cucumber/template/features/support/env.rb +12 -0
  30. data/lib/lapis_lazuli/generators/cucumber/template/features/support/transition.rb +12 -0
  31. data/lib/lapis_lazuli/generators/cucumber.rb +128 -0
  32. data/lib/lapis_lazuli/generic/xpath.rb +49 -0
  33. data/lib/lapis_lazuli/options.rb +28 -0
  34. data/lib/lapis_lazuli/placeholders.rb +36 -0
  35. data/lib/lapis_lazuli/proxy.rb +179 -0
  36. data/lib/lapis_lazuli/runtime.rb +88 -0
  37. data/lib/lapis_lazuli/scenario.rb +88 -0
  38. data/lib/lapis_lazuli/storage.rb +59 -0
  39. data/lib/lapis_lazuli/version.rb +10 -0
  40. data/lib/lapis_lazuli/versions.rb +40 -0
  41. data/lib/lapis_lazuli/world/annotate.rb +45 -0
  42. data/lib/lapis_lazuli/world/api.rb +35 -0
  43. data/lib/lapis_lazuli/world/browser.rb +75 -0
  44. data/lib/lapis_lazuli/world/config.rb +292 -0
  45. data/lib/lapis_lazuli/world/error.rb +141 -0
  46. data/lib/lapis_lazuli/world/hooks.rb +109 -0
  47. data/lib/lapis_lazuli/world/logging.rb +53 -0
  48. data/lib/lapis_lazuli/world/proxy.rb +59 -0
  49. data/lib/lapis_lazuli/world/variable.rb +139 -0
  50. data/lib/lapis_lazuli.rb +75 -0
  51. data/test/.gitignore +8 -0
  52. data/test/Gemfile +42 -0
  53. data/test/README.md +35 -0
  54. data/test/config/config.yml +37 -0
  55. data/test/config/cucumber.yml +37 -0
  56. data/test/features/annotation.feature +23 -0
  57. data/test/features/browser.feature +10 -0
  58. data/test/features/button.feature +38 -0
  59. data/test/features/click.feature +35 -0
  60. data/test/features/error.feature +30 -0
  61. data/test/features/find.feature +92 -0
  62. data/test/features/har.feature +9 -0
  63. data/test/features/modules.feature +14 -0
  64. data/test/features/step_definitions/interaction_steps.rb +154 -0
  65. data/test/features/step_definitions/validation_steps.rb +350 -0
  66. data/test/features/support/env.rb +21 -0
  67. data/test/features/text_field.feature +32 -0
  68. data/test/features/timing.feature +47 -0
  69. data/test/features/variable.feature +11 -0
  70. data/test/features/xpath.feature +41 -0
  71. data/test/server/start.rb +17 -0
  72. data/test/server/www/button.html +22 -0
  73. data/test/server/www/error_html.html +9 -0
  74. data/test/server/www/find.html +66 -0
  75. data/test/server/www/javascript_error.html +12 -0
  76. data/test/server/www/text_fields.html +15 -0
  77. data/test/server/www/timing.html +32 -0
  78. data/test/server/www/xpath.html +22 -0
  79. metadata +295 -0
@@ -0,0 +1,35 @@
1
+ @click @p
2
+ Feature: clicks
3
+ When I want to test the Lapis Lazuli library
4
+ I want to run a webserver with some test files
5
+ And execute the each library function that handles clicks.
6
+
7
+ @click_01
8
+ Scenario: click_01 - use onClick event
9
+ Given I navigate to the button test page
10
+ And I click the last button
11
+ Then I should be able to click the first button by event
12
+
13
+ @click_02
14
+ Scenario: click_02 - use JavaScript
15
+ Given I navigate to the button test page
16
+ And I click the last button
17
+ Then I should be able to click the first button by using JavaScript
18
+
19
+ @click_03
20
+ Scenario Outline: click_03 - use click types
21
+ Given I navigate to the button test page
22
+ And I click the last button
23
+ Then I should be able to click the first button by click type <type>
24
+
25
+ Examples:
26
+ | type |
27
+ | method |
28
+ | event |
29
+ | js |
30
+
31
+ @click_04
32
+ Scenario: click_04 - use force click
33
+ Given I navigate to the button test page
34
+ And I click the last button
35
+ Then I should be able to click the first button by force click
@@ -0,0 +1,30 @@
1
+ @error @p
2
+ Feature: Error
3
+ When I want to test the Lapis Lazuli library
4
+ I want to run a webserver with some test files
5
+ And execute the each library function that handles errors.
6
+
7
+ @error_01
8
+ Scenario: error_01 - Has JS error
9
+ Given I navigate to the javascript error test page
10
+ Then I expect javascript errors
11
+
12
+ @error_02
13
+ Scenario: error_02 - Status Code 404
14
+ Given I navigate to the 404 test page
15
+ Then I expect a 404 status code
16
+
17
+ @error_04
18
+ Scenario: error_03 - Status Code 200
19
+ Given I navigate to the text fields test page
20
+ Then I expect a 200 status code
21
+
22
+ @error_04
23
+ Scenario: error_04 - HTML Error
24
+ Given I navigate to the error html test page
25
+ Then I expect 1 HTML error
26
+
27
+ @error_05
28
+ Scenario: error_05 - HTML Error
29
+ Given I navigate to the text fields test page
30
+ Then I expect no HTML error
@@ -0,0 +1,92 @@
1
+ @find @p
2
+ Feature: Find
3
+ When I want to test the Lapis Lazuli library
4
+ I want to run a webserver with some test files
5
+ And execute the each library function searches for elements.
6
+
7
+ @find_01
8
+ Scenario: Find by string
9
+ Given I navigate to the find test page
10
+ Then I expect the "header" to exist
11
+ And I expect the "footer" to exist
12
+
13
+ @find_02
14
+ Scenario: Find by element
15
+ Given I navigate to the find test page
16
+ Then I expect a nav element to exist
17
+ And I expect a div element to exist
18
+
19
+ @find_03
20
+ Scenario Outline: Find by attribute
21
+ Given I navigate to the find test page
22
+ Then I expect to find a <element> element with <attribute> "<text>" using <settings> settings
23
+
24
+ Examples:
25
+ | element | attribute | text | settings |
26
+ | button | class | submit | method |
27
+ | a | href | /full/link | method |
28
+ | div | text | Second | method |
29
+ | button | class | submit | like with hash |
30
+ | a | href | /full/link | like with hash |
31
+ | div | text | Second | like with hash |
32
+ | button | class | submit | like with array |
33
+ | a | href | /full/link | like with array |
34
+ | div | text | Second | like with array |
35
+ | button | class | submit | tag name |
36
+ # :tag_name + :href not supported by watir
37
+ # | a | href | /full/link | tag name |
38
+ | div | text | Second | tag name |
39
+
40
+ @find_04
41
+ Scenario Outline: Find one of multiple
42
+ Given I navigate to the find test page
43
+ Then I expect to find a <element1> element or a <element2> element
44
+
45
+ Examples:
46
+ | element1 | element2 |
47
+ | a | does_not_exist |
48
+ | does_not_exist | a |
49
+
50
+ @find_05
51
+ Scenario Outline: Find with context
52
+ Given I navigate to the find test page
53
+ When I find "<context>" and name it "test_element"
54
+ Then I should find "<element>" using "test_element" as context
55
+ And I should not find "<error_element>" using "test_element" as context
56
+
57
+ Examples:
58
+ | context | element | error_element |
59
+ | deep3 | deep6 | deep1 |
60
+ | deep2 | deep7 | deep1 |
61
+ | deep6 | deep7 | header |
62
+
63
+ @find_06
64
+ Scenario Outline: FindAllPresent with context
65
+ Given I navigate to the find test page
66
+ When I find "<context>" and name it "test_element"
67
+ Then I should find "<element>" <number> times using "test_element" as context
68
+ Examples:
69
+ | context | element | number |
70
+ | deep3 | deep6 | 1 |
71
+ | deep3 | count | 4 |
72
+ | deep3 | does_not_exist | 0 |
73
+
74
+ @find_07 @find_errors @issue_6
75
+ Scenario: Find in always returns an element, defaulting to the document root
76
+ Given I navigate to the find test page
77
+ Then I expect not to find "does_not_exist"
78
+
79
+ @find_08 @find_errors @issue_6
80
+ Scenario Outline: Find with tagname to hash options seems broken
81
+ Given I navigate to the find test page
82
+ Then I expect to use tagname to hash options to <mode> find element <element>
83
+
84
+ Examples:
85
+ | element | mode |
86
+ | deep3 | |
87
+ | does_not_exist | not |
88
+
89
+ @find_09 @issue_8
90
+ Scenario: Find should throw, unless no :throw is specified
91
+ Given I navigate to the find test page
92
+ Then I expect not to find "does_not_exist" with no :throw option
@@ -0,0 +1,9 @@
1
+ @har @p
2
+ Feature: HAR
3
+ When I want to test the Lapis Lazuli library
4
+ I want to run a webserver with some test files
5
+ And execute the each library function handle HAR files.
6
+
7
+ @har_01
8
+ Scenario: Goto simple HTTP site
9
+ When I go to "http://ipecho.net/plain"
@@ -0,0 +1,14 @@
1
+ @modules @p
2
+ Feature: Modules
3
+ When I want to test the Lapis Lazuli library
4
+ I want to ensure that including modules works as expected
5
+
6
+ @modules_01
7
+ Scenario: modules_01 - World module
8
+ Given I include a world module
9
+ Then I expect the world module's functions to be available
10
+
11
+ @modules_02
12
+ Scenario: modules_02 - Browser module
13
+ Given I include a browser module
14
+ Then I expect the browser module's functions to be available
@@ -0,0 +1,154 @@
1
+ ################################################################################
2
+ # Copyright 2014 spriteCloud B.V. All rights reserved.
3
+ # Generated by LapisLazuli, version 0.0.1
4
+ # Author: "Onno Steenbergen" <onno@steenbe.nl>
5
+
6
+ require 'test/unit/assertions'
7
+
8
+ include Test::Unit::Assertions
9
+
10
+ Given(/^I navigate to the (.*) test page$/) do |page|
11
+ config = "server.url"
12
+ if has_env?(config)
13
+ url = env(config)
14
+ browser.goto "#{url}#{page.downcase.gsub(" ","_")}.html"
15
+ else
16
+ error(:env => config)
17
+ end
18
+ end
19
+
20
+ Given(/I click (the|a) (first|last|random|[0-9]+[a-z]+) (.*)$/) do |arg1, index, type|
21
+ # Convert the type text to a symbol
22
+ type = type.downcase.gsub(" ","_")
23
+
24
+ pick = 0
25
+ if ["first","last","random"].include?(index)
26
+ pick = index.to_sym
27
+ else
28
+ pick = index.to_i - 1
29
+ end
30
+ # Options for find
31
+ options = {}
32
+ # Select the correct element
33
+ options[type.to_sym] = {}
34
+ # Pick the correct one
35
+ options[:pick] = pick
36
+ # Execute the find
37
+ type_element = browser.find(options)
38
+ type_element.click
39
+ end
40
+
41
+
42
+ Given(/^I create a firefox browser named "(.*?)"( with proxy to "(.*?)")$/) do |name, proxy, proxy_url|
43
+ b = nil
44
+ if proxy
45
+ log.debug("Starting with profile")
46
+ profile = Selenium::WebDriver::Firefox::Profile.new
47
+ profile.proxy = Selenium::WebDriver::Proxy.new :http => proxy_url
48
+ b = browser.create :firefox, :profile => profile
49
+ else
50
+ b = browser.create :firefox
51
+ end
52
+ scenario.storage.set(name, browser)
53
+ end
54
+
55
+ Given(/^I close the browser named "(.*?)"$/) do |name|
56
+ if scenario.storage.has? name
57
+ browser = scenario.storage.get name
58
+ browser.close
59
+ else
60
+ error("No item in the storage named #{name}")
61
+ end
62
+ end
63
+
64
+ When(/^I find "(.*?)" and name it "(.*?)"$/) do |id, name|
65
+ element = browser.find(id)
66
+ scenario.storage.set(name, element)
67
+ end
68
+
69
+ xpath_fragment = nil
70
+ Given(/^I specify a needle "(.+?)" and a node "(.+?)" (and an empty separator )?to xp_contains$/) do |needle, node, empty_sep|
71
+ if empty_sep.nil?
72
+ xpath_fragment = xp_contains(node, needle)
73
+ else
74
+ xpath_fragment = xp_contains(node, needle, '')
75
+ end
76
+ end
77
+
78
+ Then(/^I expect an xpath fragment "(.*?)"$/) do |fragment|
79
+ assert fragment == xpath_fragment, "Fragment was not as expected: got '#{xpath_fragment}' vs expected '#{fragment}'."
80
+ end
81
+
82
+ Then(/^I expect the fragment "(.*?)" to find (\d+) element\(s\)\.$/) do |fragment, n|
83
+ elems = browser.elements(:xpath => "//div[#{fragment}]")
84
+ assert n.to_i == elems.length, "Mismatched amount: got #{elems.length} vs. expected #{n}"
85
+ end
86
+
87
+ elems = []
88
+ Given(/^I search for elements where node "(.+?)" contains "(.+?)" and not "(.+?)"$/) do |node, first, second|
89
+ clause = xp_and(xp_contains(node, first), xp_not(xp_contains(node, second)))
90
+ elems = browser.elements(:xpath => "//div[#{clause}]")
91
+ end
92
+
93
+ Then(/^I expect to find (\d+) elements\.$/) do |n|
94
+ assert n.to_i == elems.length, "Mismatched amount: got #{elems.length} vs. expected #{n}"
95
+ end
96
+
97
+ When(/^I go to "(.*?)"$/) do |url|
98
+ browser.goto url
99
+ end
100
+
101
+ Then(/^I should be able to click the first button by event$/) do
102
+ elem = browser.button(:id => 'first')
103
+ browser.on_click(elem)
104
+ browser.wait(
105
+ :timeout => 1,
106
+ :text => 'first clicked',
107
+ :groups => ['wait'],
108
+ )
109
+ end
110
+
111
+ Then(/^I should be able to click the first button by using JavaScript$/) do
112
+ elem = browser.button(:id => 'first')
113
+ browser.js_click(elem)
114
+ browser.wait(
115
+ :timeout => 1,
116
+ :text => 'first clicked',
117
+ :groups => ['wait'],
118
+ )
119
+ end
120
+
121
+ Then(/^I should be able to click the first button by click type (.*?)$/) do |type|
122
+ elem = browser.button(:id => 'first')
123
+ browser.click_type(elem, type)
124
+ browser.wait(
125
+ :timeout => 1,
126
+ :text => 'first clicked',
127
+ :groups => ['wait'],
128
+ )
129
+ end
130
+
131
+
132
+ Then(/^I should be able to click the first button by force click$/) do
133
+ elem = browser.button(:id => 'first')
134
+ browser.force_click(elem)
135
+ browser.wait(
136
+ :timeout => 1,
137
+ :text => 'first clicked',
138
+ :groups => ['wait'],
139
+ )
140
+ end
141
+
142
+
143
+ Given(/^I annotate a step with (.*?)$/) do |data|
144
+ annotate data
145
+ end
146
+
147
+ Then(/^the report should include (.*?) and (.*?) in the correct place$/) do |data1, data2|
148
+ # Our test completely ignores the "scope" part, because the scope is the
149
+ # scenario/example anyway. Instead we just check the stored values are
150
+ # as expected.
151
+ annotations.each do |scope, values|
152
+ assert ([[data1], [data2]] == values), "Stored values: #{values}, expected [[#{data1}], [#{data2}]]"
153
+ end
154
+ end
@@ -0,0 +1,350 @@
1
+ ################################################################################
2
+ # Copyright 2014-2015 spriteCloud B.V. All rights reserved.
3
+ # Generated by LapisLazuli, version 0.0.1
4
+ # Author: "Onno Steenbergen" <onno@steenbe.nl>
5
+
6
+ require 'test/unit/assertions'
7
+
8
+ include Test::Unit::Assertions
9
+
10
+ Then(/(first|last|random|[0-9]+[a-z]+) (.*) should (not )?be the (first|last|[0-9]+[a-z]+) element on the page$/) do |index, type, differ, location_on_page|
11
+ # Convert the type text to a symbol
12
+ type = type.downcase.gsub(" ","_")
13
+
14
+ pick = 0
15
+ if ["first","last","random"].include?(index)
16
+ pick = index.to_sym
17
+ else
18
+ pick = index.to_i - 1
19
+ end
20
+ # Options for find
21
+ options = {}
22
+ # Select the correct element
23
+ options[type.to_sym] = {}
24
+ # Pick the correct one
25
+ options[:pick] = pick
26
+ # Execute the find
27
+ type_element = browser.find(options)
28
+
29
+ # All elements on the page
30
+ body_elements = browser.body.elements
31
+ # Find the element we need
32
+ page_element = nil
33
+ if location_on_page == "first"
34
+ page_element = body_elements.first
35
+ elsif location_on_page == "last"
36
+ page_element = body_elements.last
37
+ else
38
+ page_element = body_elements[location_on_page.to_i - 1]
39
+ end
40
+
41
+ # No page element
42
+ if not page_element
43
+ error("Could not find an element on the page")
44
+ # Elements are the same but it should not be
45
+ elsif page_element == type_element and differ
46
+ error("Elements on the page are the same")
47
+ # Elements are different but should be the same
48
+ elsif page_element != type_element and not differ
49
+ error("Elements should be the same")
50
+ end
51
+ end
52
+
53
+ Then(/(first|last|random|[0-9]+[a-z]+) (.*) should (not )?be present$/) do |index, type, hidden|
54
+ # Convert the type text to a symbol
55
+ type = type.downcase.gsub(" ","_")
56
+
57
+ pick = 0
58
+ if ["first","last","random"].include?(index)
59
+ pick = index.to_sym
60
+ else
61
+ pick = index.to_i - 1
62
+ end
63
+
64
+ # Options for find_all
65
+ options = {}
66
+ # Select the correct element
67
+ options[type.to_sym] = {}
68
+ # Pick the correct one
69
+ options[:pick] = pick
70
+ # Execute the find
71
+ type_element = browser.find(options)
72
+ # Find all
73
+ all_elements = browser.find_all(options)
74
+
75
+ options[:filter_by] = :present?
76
+ all_present = browser.find_all(options)
77
+
78
+ if hidden and type_element.present?
79
+ error("Hidden element is visible")
80
+ elsif not hidden and not type_element.present?
81
+ error("Element is hidden")
82
+ elsif hidden and not type_element.present? and
83
+ (not all_elements.include?(type_element) or all_present.include?(type_element))
84
+ error("Hidden element (not) found via find_all(:filter_by => :present?)")
85
+ elsif not hidden and type_element.present? and
86
+ (not all_elements.include?(type_element) or not all_present.include?(type_element))
87
+ error("Visible element (not) found via find_all(:filter_by => :present?)")
88
+ end
89
+ end
90
+
91
+ Then(/^within (\d+) seconds I should see "([^"]+?)"( disappear)?$/) do |timeout, text, condition|
92
+ if condition
93
+ condition = :while
94
+ else
95
+ condition = :until
96
+ end
97
+
98
+ browser.wait(
99
+ :timeout => timeout,
100
+ :text => text,
101
+ :condition => condition,
102
+ :groups => ["wait"]
103
+ )
104
+ end
105
+
106
+ Then(/^within (\d+) seconds I should see "([^"]+?)" and "([^"]+?)"( disappear)?$/) do |timeout, first, second, condition|
107
+ if condition
108
+ condition = :while
109
+ else
110
+ condition = :until
111
+ end
112
+
113
+ browser.multi_wait_all(
114
+ :timeout => timeout,
115
+ :condition => condition,
116
+ :mode => :match_all,
117
+ :groups => ["wait"],
118
+ :selectors => [
119
+ { :tag_name => 'span', :class => /foo/ },
120
+ { :tag_name => 'div', :id => 'bar' }
121
+ ]
122
+ )
123
+ end
124
+
125
+ Then(/^within (\d+) seconds I should see added elements with matching$/) do |timeout|
126
+ elems = browser.multi_wait_all(
127
+ :timeout => timeout,
128
+ :condition => :until,
129
+ :mode => :match_all,
130
+ :groups => ["wait"],
131
+ :selectors => [
132
+ { :tag_name => 'span', :class => /foo/, :text => /foo/ },
133
+ { :tag_name => 'div', :id => 'bar', :html => "bar" }
134
+ ]
135
+ )
136
+ assert (2 == elems.length), "Expected two elements, found #{elems.length}"
137
+ end
138
+
139
+ Then(/^within 10 seconds I should see either added element/) do
140
+ browser.multi_wait_all(
141
+ { :tag_name => 'a', :class => /foo/ },
142
+ { :tag_name => 'div', :id => 'bar' }
143
+ )
144
+ end
145
+
146
+ Then(/^within (\d+) seconds I get an error waiting for "(.*?)"( disappear)?$/) do |timeout, text, condition|
147
+ if condition
148
+ condition = :while
149
+ else
150
+ condition = :until
151
+ end
152
+
153
+ begin
154
+ browser.wait(
155
+ :timeout => timeout,
156
+ :text => text,
157
+ :condition => condition,
158
+ :screenshot => true,
159
+ :groups => ["wait"]
160
+ )
161
+ error(
162
+ :message => "Didn't receive an error with this timeout",
163
+ :screenshot => true,
164
+ :groups => ["wait"]
165
+ )
166
+ rescue StandardError => err
167
+ end
168
+ end
169
+
170
+
171
+ Then(/^within (\d+) seconds I should not see nonexistent elements$/) do |timeout|
172
+
173
+ ex = nil
174
+ begin
175
+ browser.wait_all(:timeout => timeout, :id => "does_not_exist")
176
+ rescue StandardError => e
177
+ ex = e
178
+ end
179
+
180
+ assert !ex.nil?, "We need a timeout error to occur here!"
181
+ end
182
+
183
+
184
+ Then(/^a screenshot should have been created$/) do
185
+ # Check if there is a screenshot with the correct name
186
+ name = browser.screenshot_name
187
+ if Dir[name].empty?
188
+ error(
189
+ :message => "Didn't find a screenshot for this scenario: #{name}",
190
+ :groups => ["screenshot"]
191
+ )
192
+ end
193
+ end
194
+
195
+ Then(/^I expect javascript errors$/) do
196
+ errors = browser.get_js_errors
197
+ if !errors.nil? and errors.length > 0
198
+ scenario.check_browser_errors = false
199
+ else
200
+ error(
201
+ :message => "No Javascript errors detected",
202
+ :groups => ["error"]
203
+ )
204
+ end
205
+ end
206
+
207
+ Then(/^I expect a (\d+) status code$/) do |expected|
208
+ expected = expected.to_i
209
+ if browser.get_http_status == expected && expected > 299
210
+ scenario.check_browser_errors = false
211
+ elsif browser.get_http_status != expected
212
+ error(
213
+ :message => "Incorrect status code: #{browser.get_http_status}",
214
+ :groups => ["error"]
215
+ )
216
+ end
217
+ end
218
+
219
+ Then(/^I expect (no|\d+) HTML errors?$/) do |expected|
220
+ expected = expected.to_i
221
+ scenario.check_browser_errors = false
222
+ if browser.get_html_errors.length != expected
223
+ error(
224
+ :message => "Expected #{expected} errors: #{browser.get_html_errors}",
225
+ :groups => ["error"]
226
+ )
227
+ end
228
+ end
229
+
230
+ Then(/^the firefox browser named "(.*?)" has a profile$/) do |name|
231
+ if scenario.storage.has? name
232
+ browser = scenario.storage.get name
233
+ if browser.driver.capabilities.firefox_profile.nil?
234
+ raise "Profile is not set"
235
+ end
236
+ else
237
+ error("No item in the storage named #{name}")
238
+ end
239
+ end
240
+
241
+ Then(/^I expect the "(.*?)" to exist$/) do |name|
242
+ browser.find(name)
243
+ end
244
+
245
+ Then(/^I expect an? (.*?) element to exist$/) do |element|
246
+ browser.find(element.to_sym)
247
+ end
248
+
249
+ Then(/^I expect to find an? (.*?) element with (.*?) "(.*?)" using (.*?) settings$/) do |element, attribute, text, setting_choice|
250
+ settings = {
251
+ "method" => {element.downcase => { attribute.to_sym => /#{text}/}},
252
+ "like with hash" => {:like =>{
253
+ :element => element.downcase,
254
+ :attribute => attribute,
255
+ :include => text
256
+ }},
257
+ "like with array" => {:like => [element.downcase, attribute, text]},
258
+ "tag name" => {:tag_name => element.downcase, attribute.to_sym => /#{text}/}
259
+ }
260
+ setting = settings[setting_choice]
261
+ # Find always throws an error if not found
262
+ elem_find = browser.find(setting)
263
+ elem_findall = browser.find_all(setting).first
264
+ if elem_find != elem_findall
265
+ error "Incorrect results"
266
+ end
267
+ end
268
+
269
+ Then(/^I expect to find an? (.*?) element or an? (.*?) element$/) do |element1, element2|
270
+ element = browser.multi_find(element1.to_sym, element2.to_sym)
271
+ end
272
+
273
+ Then(/^I should (not )?find "(.*?)" ([0-9]+ times )?using "(.*?)" as context$/) do |result, id, number, name|
274
+ context = scenario.storage.get name
275
+ if context.nil?
276
+ error(:not_found => "Find context in storage")
277
+ end
278
+ begin
279
+ settings = {:element => id, :context => context}
280
+ settings[:filter_by] = :present?
281
+ settings[:throw] = false
282
+ elements = browser.find_all(settings)
283
+ if not number.nil? and elements.length != number.to_i
284
+ error("Incorrect number of elements: #{elements.length}")
285
+ end
286
+ rescue
287
+ if result.nil?
288
+ raise $!
289
+ end
290
+ end
291
+ end
292
+
293
+ Given(/^I generate and store an email$/) do
294
+ x = variable("%{email}")
295
+ storage.set("test_email", x)
296
+ end
297
+
298
+ Then(/^I can retrieve the email$/) do
299
+ x = storage.get("test_email")
300
+ assert !x.nil?, "Could not retrieve email from storage."
301
+ end
302
+
303
+ Then(/^I expect the email to contain the domain name I specified\.$/) do
304
+ x = storage.get("test_email")
305
+ domain = env_or_config('email_domain')
306
+ assert x.include?(domain), "Generated email #{x} does not contain configured domain #{domain}!"
307
+ end
308
+
309
+
310
+ Given(/^I include a (world|browser) module$/) do |type|
311
+ # Nothing to do - see features/support/env.rb
312
+ true
313
+ end
314
+
315
+ Then(/^I expect the (world|browser) module's functions to be available$/) do |type|
316
+ # We're essentially testing that NoMethodError is not being raised here.
317
+ case type
318
+ when "browser"
319
+ browser.test_func
320
+ when "world"
321
+ test_func
322
+ else
323
+ raise "No such module type: #{type}"
324
+ end
325
+ end
326
+
327
+ Then(/^I expect not to find "(.*?)"(.*?)$/) do |id, extra|
328
+ throw_opt = !(extra.length > 0)
329
+ if throw_opt
330
+ ex = nil
331
+ begin
332
+ element = browser.find(:id => id, :throw => throw_opt)
333
+ rescue RuntimeError => e
334
+ ex = e
335
+ end
336
+ assert !ex.nil?, "No exception thrown when finding element that doesn't exist."
337
+ else
338
+ assert element.nil?, "Found the some element!"
339
+ end
340
+ end
341
+
342
+ Then(/^I expect to use tagname to hash options to (.*?) find element (.*?)$/) do |mode, elem_id|
343
+ element = browser.find(:div => {:id => elem_id}, :throw => false)
344
+ if mode.length > 0 # "not "
345
+ assert element.nil?, "Could find element with a tagname => hash selector"
346
+ else
347
+ assert element.exists?, "Could not find element with a tagname => hash selector"
348
+ end
349
+ end
350
+