SimpliTest 0.0.4 → 0.0.5
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 +4 -4
- data/README.md +21 -21
- data/SimpliTest.gemspec +42 -42
- data/bin/SimpliTest +22 -22
- data/lib/SimpliTest.rb +2 -2
- data/lib/SimpliTest/cli/main.rb +333 -333
- data/lib/SimpliTest/config/configuration.rb +107 -107
- data/lib/SimpliTest/config/directory_paths.rb +36 -36
- data/lib/SimpliTest/config/environment.rb +67 -67
- data/lib/SimpliTest/config/local_environment.rb +20 -20
- data/lib/SimpliTest/config/profiles/chrome.rb +18 -18
- data/lib/SimpliTest/config/profiles/firefox.rb +14 -14
- data/lib/SimpliTest/config/profiles/internet_explorer.rb +11 -11
- data/lib/SimpliTest/config/profiles/phantom.rb +9 -9
- data/lib/SimpliTest/config/profiles/phantom_debug.rb +12 -12
- data/lib/SimpliTest/config/profiles/selenium.rb +13 -13
- data/lib/SimpliTest/config/screen_size.rb +25 -25
- data/lib/SimpliTest/config/steps.rb +8 -8
- data/lib/SimpliTest/helpers/data_validation.rb +60 -60
- data/lib/SimpliTest/helpers/file.rb +38 -38
- data/lib/SimpliTest/helpers/project_setup.rb +186 -186
- data/lib/SimpliTest/helpers/step_helpers/custom_chrome_helpers.rb +14 -14
- data/lib/SimpliTest/helpers/step_helpers/custom_date_helpers.rb +64 -64
- data/lib/SimpliTest/helpers/step_helpers/custom_form_helpers.rb +66 -66
- data/lib/SimpliTest/helpers/step_helpers/custom_phantomjs_helpers.rb +49 -49
- data/lib/SimpliTest/helpers/step_helpers/custom_selenium_helpers.rb +41 -41
- data/lib/SimpliTest/helpers/step_helpers/html_selectors_helpers.rb +154 -154
- data/lib/SimpliTest/helpers/step_helpers/navigation_helpers.rb +206 -206
- data/lib/SimpliTest/helpers/step_helpers/tolerance_for_sync_issues.rb +38 -38
- data/lib/SimpliTest/helpers/step_helpers/within_helpers.rb +6 -6
- data/lib/SimpliTest/helpers/windows_ui.rb +51 -51
- data/lib/SimpliTest/steps/debugging_steps.rb +19 -19
- data/lib/SimpliTest/steps/form_steps.rb +348 -352
- data/lib/SimpliTest/steps/form_verification_steps.rb +189 -189
- data/lib/SimpliTest/steps/navigation_steps.rb +58 -47
- data/lib/SimpliTest/steps/scoper.rb +42 -42
- data/lib/SimpliTest/steps/verification_steps.rb +306 -306
- data/lib/SimpliTest/tasks/document.rb +169 -169
- data/lib/SimpliTest/tasks/examples.rb +18 -18
- data/lib/SimpliTest/tasks/testinstall.rb +5 -5
- data/lib/SimpliTest/templates/NewSimpliTestProject/Readme.txt +4 -4
- data/lib/SimpliTest/templates/NewSimpliTestProject/cucumber.yml +26 -26
- data/lib/SimpliTest/templates/NewSimpliTestProject/documentation/step_definitions.html +88 -87
- data/lib/SimpliTest/templates/NewSimpliTestProject/features/specifications/RegressionTests/HelloWorld.feature +3 -3
- data/lib/SimpliTest/templates/NewSimpliTestProject/features/specifications/SmokeTest/HelloWorld.feature +3 -3
- data/lib/SimpliTest/templates/NewSimpliTestProject/features/specifications/accessibilityTests/HelloWorld.feature +3 -3
- data/lib/SimpliTest/templates/NewSimpliTestProject/features/support/config/environments.yml +10 -10
- data/lib/SimpliTest/templates/NewSimpliTestProject/features/support/config/pages.yml +26 -26
- data/lib/SimpliTest/templates/NewSimpliTestProject/features/support/config/selectors.yml +44 -44
- data/lib/SimpliTest/templates/NewSimpliTestProject/features/support/config/settings.yml +26 -26
- data/lib/SimpliTest/templates/NewSimpliTestProject/features/support/env.rb +33 -33
- data/lib/SimpliTest/templates/NewSimpliTestProject/license.txt +29 -29
- data/lib/SimpliTest/templates/document/css/style.css +28 -28
- data/lib/SimpliTest/templates/document/index.html +60 -60
- data/lib/version.rb +3 -3
- metadata +4 -4
@@ -1,154 +1,154 @@
|
|
1
|
-
module HtmlSelectorsHelpers
|
2
|
-
#TODO: Rewrite without test app for template. The code here effing nuts'...clean this shit
|
3
|
-
@selectors_file = 'features/support/config/selectors.yml'
|
4
|
-
|
5
|
-
def pagination_links_for(page_number)
|
6
|
-
selector = "input[title='Page #{page_number}']"
|
7
|
-
all(:css, selector)
|
8
|
-
end
|
9
|
-
|
10
|
-
def pagination_element_for(index)
|
11
|
-
lookup = {
|
12
|
-
'first' => 'firstButton',
|
13
|
-
'last' => 'lastButton',
|
14
|
-
'previous' => 'prevButton',
|
15
|
-
'next' => 'nextButton'
|
16
|
-
}
|
17
|
-
selector = "##{lookup[index]}"
|
18
|
-
elements = all(:css, selector)
|
19
|
-
elements.first if elements
|
20
|
-
end
|
21
|
-
|
22
|
-
def select_options_for(locator)
|
23
|
-
element = get_element_from(locator)
|
24
|
-
get_text_from(element)
|
25
|
-
end
|
26
|
-
|
27
|
-
def get_element_from(locator, try_field=true, find_button_or_link=false)
|
28
|
-
selector, selector_type = selector_for(locator)
|
29
|
-
element = nil
|
30
|
-
patiently do
|
31
|
-
if selector_type == 'xpath'
|
32
|
-
element = page.find(:xpath, selector)
|
33
|
-
elsif selector_type == 'css'
|
34
|
-
element = page.find(:css, selector)
|
35
|
-
elsif try_field
|
36
|
-
element = page.find_field(selector)
|
37
|
-
elsif find_button_or_link
|
38
|
-
raise "Button or Link Not Found"
|
39
|
-
else
|
40
|
-
element = find(selector)
|
41
|
-
end
|
42
|
-
end
|
43
|
-
end
|
44
|
-
|
45
|
-
|
46
|
-
def get_button_or_link_from(locator)
|
47
|
-
begin
|
48
|
-
get_element_from(locator, false, true)
|
49
|
-
rescue
|
50
|
-
begin
|
51
|
-
page.find_link(locator)
|
52
|
-
rescue
|
53
|
-
page.find_button(locator)
|
54
|
-
end
|
55
|
-
end
|
56
|
-
end
|
57
|
-
|
58
|
-
def selector_for(locator)
|
59
|
-
if SimpliTest.config_selectors
|
60
|
-
mapping = mapping_for(locator)
|
61
|
-
mapping ? selector_from(mapping) : default_selector_for(locator)
|
62
|
-
else
|
63
|
-
default_selector_for(locator)
|
64
|
-
end
|
65
|
-
end
|
66
|
-
|
67
|
-
def mapping_for(selector)
|
68
|
-
SimpliTest.config_selectors[unquoted(selector)] || false
|
69
|
-
end
|
70
|
-
|
71
|
-
def selector_from(selector)
|
72
|
-
selector_type = is_xpath?(selector) ? 'xpath' : (is_css?(selector) ? 'css' : 'other')
|
73
|
-
selector = without_identifier(selector)
|
74
|
-
return selector, selector_type
|
75
|
-
end
|
76
|
-
|
77
|
-
|
78
|
-
def is_xpath?(locator)
|
79
|
-
selector_for(locator)[0].match(/xpath:(.*)/)
|
80
|
-
end
|
81
|
-
|
82
|
-
def is_css?(locator)
|
83
|
-
selector_for(locator)[0].match(/css:(.*)/)
|
84
|
-
end
|
85
|
-
|
86
|
-
def without_identifier(locator)
|
87
|
-
if match = (is_xpath?(locator) || is_css?(locator))
|
88
|
-
return match[1]
|
89
|
-
else
|
90
|
-
return locator
|
91
|
-
end
|
92
|
-
end
|
93
|
-
|
94
|
-
|
95
|
-
def unquoted(string)
|
96
|
-
#string[0] is the first char
|
97
|
-
#string[-1,1] is the last char
|
98
|
-
is_string_quoted = (string[0] == string[-1, 1]) && (%w[' "].include?(string[0]))
|
99
|
-
is_string_quoted ? string.gsub(/^"|"$/, '') : string
|
100
|
-
end
|
101
|
-
|
102
|
-
def default_selector_for(locator)
|
103
|
-
case locator
|
104
|
-
|
105
|
-
when "the page"
|
106
|
-
with_selector_type "html > body"
|
107
|
-
when "table's header"
|
108
|
-
with_selector_type "table tbody > tr th"
|
109
|
-
when /^paragraphs?$/
|
110
|
-
with_selector_type "p"
|
111
|
-
when "\"table tr\""
|
112
|
-
with_selector_type "table tr"
|
113
|
-
when "\"div.some_class\""
|
114
|
-
with_selector_type "div.some_class"
|
115
|
-
else
|
116
|
-
with_selector_type locator
|
117
|
-
end
|
118
|
-
end
|
119
|
-
|
120
|
-
def with_selector_type(selector, selector_type='other')
|
121
|
-
[selector, selector_type]
|
122
|
-
end
|
123
|
-
|
124
|
-
def validate_absence_of(text)
|
125
|
-
min_wait_time = SimpliTest.config_settings ? SimpliTest.config_settings['MIN_WAIT_TIME'] : 2
|
126
|
-
using_wait_time min_wait_time do #because we are validating absence we don't need to wait all 5 seconds?
|
127
|
-
begin
|
128
|
-
should_not have_link(text)
|
129
|
-
rescue RSpec::Expectations::ExpectationNotMetError, Capybara::ExpectationNotMet
|
130
|
-
element = get_button_or_link_from(text)
|
131
|
-
element.should_not be_visible if element.respond_to?(:visible?)
|
132
|
-
## deprecating the approach below for performance reasons
|
133
|
-
##xpath = potential_hidden_paths_for(text).join('|')
|
134
|
-
##should have_xpath(xpath)
|
135
|
-
end
|
136
|
-
end
|
137
|
-
end
|
138
|
-
|
139
|
-
def selectors_from_section(section)
|
140
|
-
SimpliTest.config_selectors[section].values
|
141
|
-
end
|
142
|
-
|
143
|
-
#def potential_hidden_paths_for(text) #the different ways developers might choose to hide things in the DOM
|
144
|
-
#[
|
145
|
-
#"//*[@class='hidden' and contains(.,'#{text}')]",
|
146
|
-
#"//*[@class='invisible' and contains(.,'#{text}')]",
|
147
|
-
#"//*[@style='display: none;' and contains(.,'#{text}')]"
|
148
|
-
#]
|
149
|
-
|
150
|
-
#end
|
151
|
-
|
152
|
-
end
|
153
|
-
|
154
|
-
World(HtmlSelectorsHelpers)
|
1
|
+
module HtmlSelectorsHelpers
|
2
|
+
#TODO: Rewrite without test app for template. The code here effing nuts'...clean this shit
|
3
|
+
@selectors_file = 'features/support/config/selectors.yml'
|
4
|
+
|
5
|
+
def pagination_links_for(page_number)
|
6
|
+
selector = "input[title='Page #{page_number}']"
|
7
|
+
all(:css, selector)
|
8
|
+
end
|
9
|
+
|
10
|
+
def pagination_element_for(index)
|
11
|
+
lookup = {
|
12
|
+
'first' => 'firstButton',
|
13
|
+
'last' => 'lastButton',
|
14
|
+
'previous' => 'prevButton',
|
15
|
+
'next' => 'nextButton'
|
16
|
+
}
|
17
|
+
selector = "##{lookup[index]}"
|
18
|
+
elements = all(:css, selector)
|
19
|
+
elements.first if elements
|
20
|
+
end
|
21
|
+
|
22
|
+
def select_options_for(locator)
|
23
|
+
element = get_element_from(locator)
|
24
|
+
get_text_from(element)
|
25
|
+
end
|
26
|
+
|
27
|
+
def get_element_from(locator, try_field=true, find_button_or_link=false)
|
28
|
+
selector, selector_type = selector_for(locator)
|
29
|
+
element = nil
|
30
|
+
patiently do
|
31
|
+
if selector_type == 'xpath'
|
32
|
+
element = page.find(:xpath, selector)
|
33
|
+
elsif selector_type == 'css'
|
34
|
+
element = page.find(:css, selector)
|
35
|
+
elsif try_field
|
36
|
+
element = page.find_field(selector)
|
37
|
+
elsif find_button_or_link
|
38
|
+
raise "Button or Link Not Found"
|
39
|
+
else
|
40
|
+
element = find(selector)
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
|
46
|
+
def get_button_or_link_from(locator)
|
47
|
+
begin
|
48
|
+
get_element_from(locator, false, true)
|
49
|
+
rescue
|
50
|
+
begin
|
51
|
+
page.find_link(locator)
|
52
|
+
rescue
|
53
|
+
page.find_button(locator)
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
def selector_for(locator)
|
59
|
+
if SimpliTest.config_selectors
|
60
|
+
mapping = mapping_for(locator)
|
61
|
+
mapping ? selector_from(mapping) : default_selector_for(locator)
|
62
|
+
else
|
63
|
+
default_selector_for(locator)
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
def mapping_for(selector)
|
68
|
+
SimpliTest.config_selectors[unquoted(selector)] || false
|
69
|
+
end
|
70
|
+
|
71
|
+
def selector_from(selector)
|
72
|
+
selector_type = is_xpath?(selector) ? 'xpath' : (is_css?(selector) ? 'css' : 'other')
|
73
|
+
selector = without_identifier(selector)
|
74
|
+
return selector, selector_type
|
75
|
+
end
|
76
|
+
|
77
|
+
|
78
|
+
def is_xpath?(locator)
|
79
|
+
selector_for(locator)[0].match(/xpath:(.*)/)
|
80
|
+
end
|
81
|
+
|
82
|
+
def is_css?(locator)
|
83
|
+
selector_for(locator)[0].match(/css:(.*)/)
|
84
|
+
end
|
85
|
+
|
86
|
+
def without_identifier(locator)
|
87
|
+
if match = (is_xpath?(locator) || is_css?(locator))
|
88
|
+
return match[1]
|
89
|
+
else
|
90
|
+
return locator
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
94
|
+
|
95
|
+
def unquoted(string)
|
96
|
+
#string[0] is the first char
|
97
|
+
#string[-1,1] is the last char
|
98
|
+
is_string_quoted = (string[0] == string[-1, 1]) && (%w[' "].include?(string[0]))
|
99
|
+
is_string_quoted ? string.gsub(/^"|"$/, '') : string
|
100
|
+
end
|
101
|
+
|
102
|
+
def default_selector_for(locator)
|
103
|
+
case locator
|
104
|
+
|
105
|
+
when "the page"
|
106
|
+
with_selector_type "html > body"
|
107
|
+
when "table's header"
|
108
|
+
with_selector_type "table tbody > tr th"
|
109
|
+
when /^paragraphs?$/
|
110
|
+
with_selector_type "p"
|
111
|
+
when "\"table tr\""
|
112
|
+
with_selector_type "table tr"
|
113
|
+
when "\"div.some_class\""
|
114
|
+
with_selector_type "div.some_class"
|
115
|
+
else
|
116
|
+
with_selector_type locator
|
117
|
+
end
|
118
|
+
end
|
119
|
+
|
120
|
+
def with_selector_type(selector, selector_type='other')
|
121
|
+
[selector, selector_type]
|
122
|
+
end
|
123
|
+
|
124
|
+
def validate_absence_of(text)
|
125
|
+
min_wait_time = SimpliTest.config_settings ? SimpliTest.config_settings['MIN_WAIT_TIME'] : 2
|
126
|
+
using_wait_time min_wait_time do #because we are validating absence we don't need to wait all 5 seconds?
|
127
|
+
begin
|
128
|
+
should_not have_link(text)
|
129
|
+
rescue RSpec::Expectations::ExpectationNotMetError, Capybara::ExpectationNotMet
|
130
|
+
element = get_button_or_link_from(text)
|
131
|
+
element.should_not be_visible if element.respond_to?(:visible?)
|
132
|
+
## deprecating the approach below for performance reasons
|
133
|
+
##xpath = potential_hidden_paths_for(text).join('|')
|
134
|
+
##should have_xpath(xpath)
|
135
|
+
end
|
136
|
+
end
|
137
|
+
end
|
138
|
+
|
139
|
+
def selectors_from_section(section)
|
140
|
+
SimpliTest.config_selectors[section].values
|
141
|
+
end
|
142
|
+
|
143
|
+
#def potential_hidden_paths_for(text) #the different ways developers might choose to hide things in the DOM
|
144
|
+
#[
|
145
|
+
#"//*[@class='hidden' and contains(.,'#{text}')]",
|
146
|
+
#"//*[@class='invisible' and contains(.,'#{text}')]",
|
147
|
+
#"//*[@style='display: none;' and contains(.,'#{text}')]"
|
148
|
+
#]
|
149
|
+
|
150
|
+
#end
|
151
|
+
|
152
|
+
end
|
153
|
+
|
154
|
+
World(HtmlSelectorsHelpers)
|
@@ -1,206 +1,206 @@
|
|
1
|
-
module NavigationHelpers
|
2
|
-
# Maps a name to a path. Used by the
|
3
|
-
#
|
4
|
-
# When /^I go to (.+)$/ do |page_name|
|
5
|
-
#
|
6
|
-
#TODO: Rewrite without test app for template
|
7
|
-
def path_to(page_name)
|
8
|
-
if is_url?(page_name)
|
9
|
-
page_name
|
10
|
-
elsif SimpliTest.config_pages
|
11
|
-
matches = SimpliTest.config_pages.select { |p| unquoted(page_name) == p }
|
12
|
-
matches.any? ? url_from(matches, page_name) : default_path_for(page_name)
|
13
|
-
else
|
14
|
-
default_path_for(page_name)
|
15
|
-
end
|
16
|
-
end
|
17
|
-
# :nocov:
|
18
|
-
def url_from(matches, page_name)
|
19
|
-
if matches.length > 1
|
20
|
-
raise "Oops ambigous page name! More than one matched our search. It seems you have similar page names. \n" +
|
21
|
-
"Now, go and modify #{page_name} to something cooler in config/pages.yml"
|
22
|
-
else
|
23
|
-
path = matches.values.first
|
24
|
-
end
|
25
|
-
url_to(path) if path
|
26
|
-
end
|
27
|
-
|
28
|
-
def default_path_for(page_name)
|
29
|
-
case page_name
|
30
|
-
|
31
|
-
when /^home$/
|
32
|
-
'/'
|
33
|
-
when /^congratulations$/
|
34
|
-
'/congratulations'
|
35
|
-
when /^other$/
|
36
|
-
'/other/page'
|
37
|
-
when /^form$/
|
38
|
-
'/form/page'
|
39
|
-
when /^valid_links$/
|
40
|
-
'/valid-links'
|
41
|
-
when /^invalid_links$/
|
42
|
-
'/invalid-links'
|
43
|
-
# Add more mappings here.
|
44
|
-
# Here is an example that pulls values out of the Regexp:
|
45
|
-
#
|
46
|
-
# when /^(.*)'s profile page$/i
|
47
|
-
# user_profile_path(User.find_by_login($1))
|
48
|
-
|
49
|
-
else
|
50
|
-
begin
|
51
|
-
page_name =~ /^the (.*) page$/
|
52
|
-
path_components = $1.split(/\s+/)
|
53
|
-
self.send(path_components.push('path').join('_').to_sym)
|
54
|
-
rescue NoMethodError, ArgumentError
|
55
|
-
raise "Can't find mapping from \"#{page_name}\" to a path.\n" +
|
56
|
-
"Now, go and add a mapping in #{__FILE__}"
|
57
|
-
end
|
58
|
-
end
|
59
|
-
end
|
60
|
-
# :nocov:
|
61
|
-
|
62
|
-
def url_to(path)
|
63
|
-
if is_url?(path)
|
64
|
-
path
|
65
|
-
else
|
66
|
-
begin
|
67
|
-
URI.parse(SimpliTest.config_environments[SimpliTest.config_environment] + path).normalize.to_s
|
68
|
-
rescue
|
69
|
-
puts "It seems that the #{SimpliTest.config_environment} enviroment has not been set up. Please add it to features/config/environments.yml"
|
70
|
-
raise "Unidentified Environment Requested!!"
|
71
|
-
end
|
72
|
-
end
|
73
|
-
end
|
74
|
-
|
75
|
-
def is_url?(path)
|
76
|
-
uri = URI.parse(path)
|
77
|
-
uri if uri.scheme =~ /^https?$/
|
78
|
-
rescue URI::BadURIError, URI::InvalidURIError
|
79
|
-
false
|
80
|
-
end
|
81
|
-
|
82
|
-
def is_relative?(path)
|
83
|
-
uri = URI.parse(path)
|
84
|
-
uri.relative?
|
85
|
-
end
|
86
|
-
|
87
|
-
def is_valid_url_or_path?(path)
|
88
|
-
is_url?(path) || is_relative?(path)
|
89
|
-
end
|
90
|
-
|
91
|
-
def is_javascript_href?(href)
|
92
|
-
href =~ /^(javascript|#)/
|
93
|
-
end
|
94
|
-
|
95
|
-
def parse_dom_tree(url)
|
96
|
-
Nokogiri::HTML(open(url))
|
97
|
-
end
|
98
|
-
|
99
|
-
def valid_assets_links_from(nokogiri_html_document)
|
100
|
-
doc = nokogiri_html_document
|
101
|
-
links = stylesheet_references_on(doc) + javascript_references_on(doc)
|
102
|
-
links.select{ |l| !is_javascript_href?(l) }
|
103
|
-
end
|
104
|
-
|
105
|
-
def stylesheet_references_on(doc)
|
106
|
-
doc.css('link').collect{|l| l['href'] }.compact
|
107
|
-
end
|
108
|
-
|
109
|
-
def javascript_references_on(doc)
|
110
|
-
doc.css('script').collect{|l| l['src']}.compact
|
111
|
-
end
|
112
|
-
|
113
|
-
def links_on(doc)
|
114
|
-
doc.css('a').collect{|l| l['href']}.compact.select{ |l| !is_javascript_href?(l) }
|
115
|
-
end
|
116
|
-
|
117
|
-
def validate_response_from(page_name, href)
|
118
|
-
begin
|
119
|
-
root_path = path_to(page_name)
|
120
|
-
uri = is_relative?(href) ? (URI.join(root_path, href)) : URI.parse(href)
|
121
|
-
response = get_response_from(uri)
|
122
|
-
valid_status_groups = [Net::HTTPRedirection, Net::HTTPInformation, Net::HTTPSuccess ]
|
123
|
-
valid_status_groups.should include(response.class.superclass)
|
124
|
-
rescue RSpec::Expectations::ExpectationNotMetError
|
125
|
-
message = "Received a #{response.code} #{ response.msg } from #{href} on #{page_name}"
|
126
|
-
fail message
|
127
|
-
rescue
|
128
|
-
message = "Invalid reference: #{href} found on #{page_name} page"
|
129
|
-
fail message
|
130
|
-
end
|
131
|
-
end
|
132
|
-
|
133
|
-
#this returns a hash with a response code and the url to help provide good fail detail
|
134
|
-
def get_response_from(uri)
|
135
|
-
http = Net::HTTP.new(uri.host, uri.port)
|
136
|
-
http.read_timeout = http.open_timeout = SimpliTest.config[:settings]["HTTP_TIMEOUT"] || 3
|
137
|
-
request = Net::HTTP::Get.new(uri.request_uri)
|
138
|
-
if uri.scheme == 'https'
|
139
|
-
http.use_ssl = true
|
140
|
-
http.verify_mode = OpenSSL::SSL::VERIFY_NONE
|
141
|
-
end
|
142
|
-
http.request(request)
|
143
|
-
end
|
144
|
-
|
145
|
-
#FIXME: Code not used. Should be deleted
|
146
|
-
def url_in_new_window
|
147
|
-
if handles = page.driver.browser.window_handles rescue nil
|
148
|
-
new_window = handles.last
|
149
|
-
page.within_window(new_window) do
|
150
|
-
return without_trailing_slash(current_url)
|
151
|
-
end
|
152
|
-
end
|
153
|
-
end
|
154
|
-
|
155
|
-
def without_trailing_slash(url)
|
156
|
-
url.chomp('/')
|
157
|
-
end
|
158
|
-
|
159
|
-
def with_encoded_white_space(string)
|
160
|
-
string.gsub(' ', '%20')
|
161
|
-
end
|
162
|
-
|
163
|
-
def with_unencoded_white_space(string)
|
164
|
-
string.gsub('%20', ' ')
|
165
|
-
end
|
166
|
-
|
167
|
-
def normalize(url)
|
168
|
-
normalized_uri = URI.parse(url).normalize
|
169
|
-
url = normalized_uri.to_s
|
170
|
-
encoded_url = URI::encode(url)
|
171
|
-
without_trailing_slash(encoded_url)
|
172
|
-
end
|
173
|
-
|
174
|
-
def normalize_path(path)
|
175
|
-
if path = is_url?(path)
|
176
|
-
path = path.path
|
177
|
-
end
|
178
|
-
with_encoded_white_space(without_trailing_slash(path))
|
179
|
-
end
|
180
|
-
|
181
|
-
def wait_for(left_argument, right_argument)
|
182
|
-
called_at = Time.now
|
183
|
-
until left_argument > right_argument do
|
184
|
-
past_wait_time = called_at < Time.now - SimpliTest.config['HTTP_TIMEOUT']
|
185
|
-
return if past_wait_time
|
186
|
-
sleep 1
|
187
|
-
end
|
188
|
-
end
|
189
|
-
|
190
|
-
def comparable_urls_for(target_url, source_url)
|
191
|
-
is_url?(target_url) ? [target_url, source_url].map{|u| normalize(u)} : [target_url, URI.parse(source_url).path]
|
192
|
-
end
|
193
|
-
|
194
|
-
def wait_jquery_to_complete()
|
195
|
-
wait = Selenium::WebDriver::Wait.new(:timeout => 60)
|
196
|
-
wait.until {any_jquery_running}
|
197
|
-
end
|
198
|
-
|
199
|
-
def any_jquery_running
|
200
|
-
evaluate_script("!window.jQuery") || evaluate_script("jQuery.active").zero? rescue "unexpected error checking jquery"
|
201
|
-
end
|
202
|
-
|
203
|
-
|
204
|
-
end
|
205
|
-
|
206
|
-
World(NavigationHelpers)
|
1
|
+
module NavigationHelpers
|
2
|
+
# Maps a name to a path. Used by the
|
3
|
+
#
|
4
|
+
# When /^I go to (.+)$/ do |page_name|
|
5
|
+
#
|
6
|
+
#TODO: Rewrite without test app for template
|
7
|
+
def path_to(page_name)
|
8
|
+
if is_url?(page_name)
|
9
|
+
page_name
|
10
|
+
elsif SimpliTest.config_pages
|
11
|
+
matches = SimpliTest.config_pages.select { |p| unquoted(page_name) == p }
|
12
|
+
matches.any? ? url_from(matches, page_name) : default_path_for(page_name)
|
13
|
+
else
|
14
|
+
default_path_for(page_name)
|
15
|
+
end
|
16
|
+
end
|
17
|
+
# :nocov:
|
18
|
+
def url_from(matches, page_name)
|
19
|
+
if matches.length > 1
|
20
|
+
raise "Oops ambigous page name! More than one matched our search. It seems you have similar page names. \n" +
|
21
|
+
"Now, go and modify #{page_name} to something cooler in config/pages.yml"
|
22
|
+
else
|
23
|
+
path = matches.values.first
|
24
|
+
end
|
25
|
+
url_to(path) if path
|
26
|
+
end
|
27
|
+
|
28
|
+
def default_path_for(page_name)
|
29
|
+
case page_name
|
30
|
+
|
31
|
+
when /^home$/
|
32
|
+
'/'
|
33
|
+
when /^congratulations$/
|
34
|
+
'/congratulations'
|
35
|
+
when /^other$/
|
36
|
+
'/other/page'
|
37
|
+
when /^form$/
|
38
|
+
'/form/page'
|
39
|
+
when /^valid_links$/
|
40
|
+
'/valid-links'
|
41
|
+
when /^invalid_links$/
|
42
|
+
'/invalid-links'
|
43
|
+
# Add more mappings here.
|
44
|
+
# Here is an example that pulls values out of the Regexp:
|
45
|
+
#
|
46
|
+
# when /^(.*)'s profile page$/i
|
47
|
+
# user_profile_path(User.find_by_login($1))
|
48
|
+
|
49
|
+
else
|
50
|
+
begin
|
51
|
+
page_name =~ /^the (.*) page$/
|
52
|
+
path_components = $1.split(/\s+/)
|
53
|
+
self.send(path_components.push('path').join('_').to_sym)
|
54
|
+
rescue NoMethodError, ArgumentError
|
55
|
+
raise "Can't find mapping from \"#{page_name}\" to a path.\n" +
|
56
|
+
"Now, go and add a mapping in #{__FILE__}"
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
# :nocov:
|
61
|
+
|
62
|
+
def url_to(path)
|
63
|
+
if is_url?(path)
|
64
|
+
path
|
65
|
+
else
|
66
|
+
begin
|
67
|
+
URI.parse(SimpliTest.config_environments[SimpliTest.config_environment] + path).normalize.to_s
|
68
|
+
rescue
|
69
|
+
puts "It seems that the #{SimpliTest.config_environment} enviroment has not been set up. Please add it to features/config/environments.yml"
|
70
|
+
raise "Unidentified Environment Requested!!"
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
def is_url?(path)
|
76
|
+
uri = URI.parse(path)
|
77
|
+
uri if uri.scheme =~ /^https?$/
|
78
|
+
rescue URI::BadURIError, URI::InvalidURIError
|
79
|
+
false
|
80
|
+
end
|
81
|
+
|
82
|
+
def is_relative?(path)
|
83
|
+
uri = URI.parse(path)
|
84
|
+
uri.relative?
|
85
|
+
end
|
86
|
+
|
87
|
+
def is_valid_url_or_path?(path)
|
88
|
+
is_url?(path) || is_relative?(path)
|
89
|
+
end
|
90
|
+
|
91
|
+
def is_javascript_href?(href)
|
92
|
+
href =~ /^(javascript|#)/
|
93
|
+
end
|
94
|
+
|
95
|
+
def parse_dom_tree(url)
|
96
|
+
Nokogiri::HTML(open(url))
|
97
|
+
end
|
98
|
+
|
99
|
+
def valid_assets_links_from(nokogiri_html_document)
|
100
|
+
doc = nokogiri_html_document
|
101
|
+
links = stylesheet_references_on(doc) + javascript_references_on(doc)
|
102
|
+
links.select{ |l| !is_javascript_href?(l) }
|
103
|
+
end
|
104
|
+
|
105
|
+
def stylesheet_references_on(doc)
|
106
|
+
doc.css('link').collect{|l| l['href'] }.compact
|
107
|
+
end
|
108
|
+
|
109
|
+
def javascript_references_on(doc)
|
110
|
+
doc.css('script').collect{|l| l['src']}.compact
|
111
|
+
end
|
112
|
+
|
113
|
+
def links_on(doc)
|
114
|
+
doc.css('a').collect{|l| l['href']}.compact.select{ |l| !is_javascript_href?(l) }
|
115
|
+
end
|
116
|
+
|
117
|
+
def validate_response_from(page_name, href)
|
118
|
+
begin
|
119
|
+
root_path = path_to(page_name)
|
120
|
+
uri = is_relative?(href) ? (URI.join(root_path, href)) : URI.parse(href)
|
121
|
+
response = get_response_from(uri)
|
122
|
+
valid_status_groups = [Net::HTTPRedirection, Net::HTTPInformation, Net::HTTPSuccess ]
|
123
|
+
valid_status_groups.should include(response.class.superclass)
|
124
|
+
rescue RSpec::Expectations::ExpectationNotMetError
|
125
|
+
message = "Received a #{response.code} #{ response.msg } from #{href} on #{page_name}"
|
126
|
+
fail message
|
127
|
+
rescue
|
128
|
+
message = "Invalid reference: #{href} found on #{page_name} page"
|
129
|
+
fail message
|
130
|
+
end
|
131
|
+
end
|
132
|
+
|
133
|
+
#this returns a hash with a response code and the url to help provide good fail detail
|
134
|
+
def get_response_from(uri)
|
135
|
+
http = Net::HTTP.new(uri.host, uri.port)
|
136
|
+
http.read_timeout = http.open_timeout = SimpliTest.config[:settings]["HTTP_TIMEOUT"] || 3
|
137
|
+
request = Net::HTTP::Get.new(uri.request_uri)
|
138
|
+
if uri.scheme == 'https'
|
139
|
+
http.use_ssl = true
|
140
|
+
http.verify_mode = OpenSSL::SSL::VERIFY_NONE
|
141
|
+
end
|
142
|
+
http.request(request)
|
143
|
+
end
|
144
|
+
|
145
|
+
#FIXME: Code not used. Should be deleted
|
146
|
+
def url_in_new_window
|
147
|
+
if handles = page.driver.browser.window_handles rescue nil
|
148
|
+
new_window = handles.last
|
149
|
+
page.within_window(new_window) do
|
150
|
+
return without_trailing_slash(current_url)
|
151
|
+
end
|
152
|
+
end
|
153
|
+
end
|
154
|
+
|
155
|
+
def without_trailing_slash(url)
|
156
|
+
url.chomp('/')
|
157
|
+
end
|
158
|
+
|
159
|
+
def with_encoded_white_space(string)
|
160
|
+
string.gsub(' ', '%20')
|
161
|
+
end
|
162
|
+
|
163
|
+
def with_unencoded_white_space(string)
|
164
|
+
string.gsub('%20', ' ')
|
165
|
+
end
|
166
|
+
|
167
|
+
def normalize(url)
|
168
|
+
normalized_uri = URI.parse(url).normalize
|
169
|
+
url = normalized_uri.to_s
|
170
|
+
encoded_url = URI::encode(url)
|
171
|
+
without_trailing_slash(encoded_url)
|
172
|
+
end
|
173
|
+
|
174
|
+
def normalize_path(path)
|
175
|
+
if path = is_url?(path)
|
176
|
+
path = path.path
|
177
|
+
end
|
178
|
+
with_encoded_white_space(without_trailing_slash(path))
|
179
|
+
end
|
180
|
+
|
181
|
+
def wait_for(left_argument, right_argument)
|
182
|
+
called_at = Time.now
|
183
|
+
until left_argument > right_argument do
|
184
|
+
past_wait_time = called_at < Time.now - SimpliTest.config['HTTP_TIMEOUT']
|
185
|
+
return if past_wait_time
|
186
|
+
sleep 1
|
187
|
+
end
|
188
|
+
end
|
189
|
+
|
190
|
+
def comparable_urls_for(target_url, source_url)
|
191
|
+
is_url?(target_url) ? [target_url, source_url].map{|u| normalize(u)} : [target_url, URI.parse(source_url).path]
|
192
|
+
end
|
193
|
+
|
194
|
+
def wait_jquery_to_complete()
|
195
|
+
wait = Selenium::WebDriver::Wait.new(:timeout => 60)
|
196
|
+
wait.until {any_jquery_running}
|
197
|
+
end
|
198
|
+
|
199
|
+
def any_jquery_running
|
200
|
+
evaluate_script("!window.jQuery") || evaluate_script("jQuery.active").zero? rescue "unexpected error checking jquery"
|
201
|
+
end
|
202
|
+
|
203
|
+
|
204
|
+
end
|
205
|
+
|
206
|
+
World(NavigationHelpers)
|