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