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.
- checksums.yaml +7 -0
- data/.gitignore +18 -0
- data/Gemfile +4 -0
- data/Gemfile.lock +42 -0
- data/LICENSE +30 -0
- data/README.md +74 -0
- data/Rakefile +1 -0
- data/bin/lapis_lazuli +3 -0
- data/lapis_lazuli.gemspec +32 -0
- data/lib/lapis_lazuli/api.rb +52 -0
- data/lib/lapis_lazuli/argparse.rb +128 -0
- data/lib/lapis_lazuli/ast.rb +160 -0
- data/lib/lapis_lazuli/browser/error.rb +93 -0
- data/lib/lapis_lazuli/browser/find.rb +500 -0
- data/lib/lapis_lazuli/browser/interaction.rb +91 -0
- data/lib/lapis_lazuli/browser/screenshots.rb +70 -0
- data/lib/lapis_lazuli/browser/wait.rb +158 -0
- data/lib/lapis_lazuli/browser.rb +246 -0
- data/lib/lapis_lazuli/cli.rb +110 -0
- data/lib/lapis_lazuli/cucumber.rb +25 -0
- data/lib/lapis_lazuli/generators/cucumber/template/.gitignore +6 -0
- data/lib/lapis_lazuli/generators/cucumber/template/Gemfile +37 -0
- data/lib/lapis_lazuli/generators/cucumber/template/README.md +27 -0
- data/lib/lapis_lazuli/generators/cucumber/template/config/config.yml +29 -0
- data/lib/lapis_lazuli/generators/cucumber/template/config/cucumber.yml +34 -0
- data/lib/lapis_lazuli/generators/cucumber/template/features/example.feature +11 -0
- data/lib/lapis_lazuli/generators/cucumber/template/features/step_definitions/interaction_steps.rb +20 -0
- data/lib/lapis_lazuli/generators/cucumber/template/features/step_definitions/validation_steps.rb +21 -0
- data/lib/lapis_lazuli/generators/cucumber/template/features/support/env.rb +12 -0
- data/lib/lapis_lazuli/generators/cucumber/template/features/support/transition.rb +12 -0
- data/lib/lapis_lazuli/generators/cucumber.rb +128 -0
- data/lib/lapis_lazuli/generic/xpath.rb +49 -0
- data/lib/lapis_lazuli/options.rb +28 -0
- data/lib/lapis_lazuli/placeholders.rb +36 -0
- data/lib/lapis_lazuli/proxy.rb +179 -0
- data/lib/lapis_lazuli/runtime.rb +88 -0
- data/lib/lapis_lazuli/scenario.rb +88 -0
- data/lib/lapis_lazuli/storage.rb +59 -0
- data/lib/lapis_lazuli/version.rb +10 -0
- data/lib/lapis_lazuli/versions.rb +40 -0
- data/lib/lapis_lazuli/world/annotate.rb +45 -0
- data/lib/lapis_lazuli/world/api.rb +35 -0
- data/lib/lapis_lazuli/world/browser.rb +75 -0
- data/lib/lapis_lazuli/world/config.rb +292 -0
- data/lib/lapis_lazuli/world/error.rb +141 -0
- data/lib/lapis_lazuli/world/hooks.rb +109 -0
- data/lib/lapis_lazuli/world/logging.rb +53 -0
- data/lib/lapis_lazuli/world/proxy.rb +59 -0
- data/lib/lapis_lazuli/world/variable.rb +139 -0
- data/lib/lapis_lazuli.rb +75 -0
- data/test/.gitignore +8 -0
- data/test/Gemfile +42 -0
- data/test/README.md +35 -0
- data/test/config/config.yml +37 -0
- data/test/config/cucumber.yml +37 -0
- data/test/features/annotation.feature +23 -0
- data/test/features/browser.feature +10 -0
- data/test/features/button.feature +38 -0
- data/test/features/click.feature +35 -0
- data/test/features/error.feature +30 -0
- data/test/features/find.feature +92 -0
- data/test/features/har.feature +9 -0
- data/test/features/modules.feature +14 -0
- data/test/features/step_definitions/interaction_steps.rb +154 -0
- data/test/features/step_definitions/validation_steps.rb +350 -0
- data/test/features/support/env.rb +21 -0
- data/test/features/text_field.feature +32 -0
- data/test/features/timing.feature +47 -0
- data/test/features/variable.feature +11 -0
- data/test/features/xpath.feature +41 -0
- data/test/server/start.rb +17 -0
- data/test/server/www/button.html +22 -0
- data/test/server/www/error_html.html +9 -0
- data/test/server/www/find.html +66 -0
- data/test/server/www/javascript_error.html +12 -0
- data/test/server/www/text_fields.html +15 -0
- data/test/server/www/timing.html +32 -0
- data/test/server/www/xpath.html +22 -0
- 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,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
|
+
|