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,38 +1,38 @@
|
|
1
|
-
# coding: UTF-8
|
2
|
-
# :nocov:
|
3
|
-
module ToleranceForSyncIssues
|
4
|
-
RETRY_ERRORS = %w[Capybara::ElementNotFound Capybara::ExpectationNotMet
|
5
|
-
Spec::Expectations::ExpectationNotMetError RSpec::Expectations::ExpectationNotMetError
|
6
|
-
Capybara::Poltergeist::ClickFailed Selenium::WebDriver::Error::StaleElementReferenceError
|
7
|
-
Selenium::WebDriver::Error::NoAlertPresentError Capybara::Poltergeist::JavascriptError
|
8
|
-
Capybara::Driver::Webkit::WebkitInvalidResponseError Capybara::Webkit::InvalidResponseError]
|
9
|
-
|
10
|
-
# This is similiar but not entirely the same as Capybara::Node::Base#wait_until or Capybara::Session#wait_until
|
11
|
-
def patiently(seconds=Capybara.default_max_wait_time, &block)
|
12
|
-
#puts "Tried waiting"
|
13
|
-
old_wait_time = Capybara.default_max_wait_time
|
14
|
-
# dont make nested wait_untils use up all the alloted time
|
15
|
-
Capybara.default_max_wait_time = 0 # for we are a jealous gem
|
16
|
-
if page.driver.wait?
|
17
|
-
start_time = Time.now
|
18
|
-
begin
|
19
|
-
block.call
|
20
|
-
rescue Exception => e
|
21
|
-
raise e unless RETRY_ERRORS.include?(e.class.name)
|
22
|
-
puts "Failed: #{e.message}" if SimpliTest.mode == 'DEBUG'
|
23
|
-
wait_time = SimpliTest.config_settings ? SimpliTest.config_settings['MAX_WAIT_TIME'] : 5
|
24
|
-
raise e if (Time.now - start_time) >= wait_time
|
25
|
-
sleep(0.1)
|
26
|
-
raise Capybara::FrozenInTime, "time appears to be frozen, Capybara does not work with libraries which freeze time, consider using time travelling instead" if Time.now == start_time
|
27
|
-
puts "Retrying..." if SimpliTest.mode == 'DEBUG'
|
28
|
-
retry
|
29
|
-
end
|
30
|
-
else
|
31
|
-
block.call
|
32
|
-
end
|
33
|
-
ensure
|
34
|
-
Capybara.default_max_wait_time = old_wait_time
|
35
|
-
end
|
36
|
-
end
|
37
|
-
# :nocov:
|
38
|
-
World(ToleranceForSyncIssues)
|
1
|
+
# coding: UTF-8
|
2
|
+
# :nocov:
|
3
|
+
module ToleranceForSyncIssues
|
4
|
+
RETRY_ERRORS = %w[Capybara::ElementNotFound Capybara::ExpectationNotMet
|
5
|
+
Spec::Expectations::ExpectationNotMetError RSpec::Expectations::ExpectationNotMetError
|
6
|
+
Capybara::Poltergeist::ClickFailed Selenium::WebDriver::Error::StaleElementReferenceError
|
7
|
+
Selenium::WebDriver::Error::NoAlertPresentError Capybara::Poltergeist::JavascriptError
|
8
|
+
Capybara::Driver::Webkit::WebkitInvalidResponseError Capybara::Webkit::InvalidResponseError]
|
9
|
+
|
10
|
+
# This is similiar but not entirely the same as Capybara::Node::Base#wait_until or Capybara::Session#wait_until
|
11
|
+
def patiently(seconds=Capybara.default_max_wait_time, &block)
|
12
|
+
#puts "Tried waiting"
|
13
|
+
old_wait_time = Capybara.default_max_wait_time
|
14
|
+
# dont make nested wait_untils use up all the alloted time
|
15
|
+
Capybara.default_max_wait_time = 0 # for we are a jealous gem
|
16
|
+
if page.driver.wait?
|
17
|
+
start_time = Time.now
|
18
|
+
begin
|
19
|
+
block.call
|
20
|
+
rescue Exception => e
|
21
|
+
raise e unless RETRY_ERRORS.include?(e.class.name)
|
22
|
+
puts "Failed: #{e.message}" if SimpliTest.mode == 'DEBUG'
|
23
|
+
wait_time = SimpliTest.config_settings ? SimpliTest.config_settings['MAX_WAIT_TIME'] : 5
|
24
|
+
raise e if (Time.now - start_time) >= wait_time
|
25
|
+
sleep(0.1)
|
26
|
+
raise Capybara::FrozenInTime, "time appears to be frozen, Capybara does not work with libraries which freeze time, consider using time travelling instead" if Time.now == start_time
|
27
|
+
puts "Retrying..." if SimpliTest.mode == 'DEBUG'
|
28
|
+
retry
|
29
|
+
end
|
30
|
+
else
|
31
|
+
block.call
|
32
|
+
end
|
33
|
+
ensure
|
34
|
+
Capybara.default_max_wait_time = old_wait_time
|
35
|
+
end
|
36
|
+
end
|
37
|
+
# :nocov:
|
38
|
+
World(ToleranceForSyncIssues)
|
@@ -1,6 +1,6 @@
|
|
1
|
-
module WithinHelpers
|
2
|
-
def with_scope(locator)
|
3
|
-
locator ? within(*selector_for(locator)) { yield } : yield
|
4
|
-
end
|
5
|
-
end
|
6
|
-
World(WithinHelpers)
|
1
|
+
module WithinHelpers
|
2
|
+
def with_scope(locator)
|
3
|
+
locator ? within(*selector_for(locator)) { yield } : yield
|
4
|
+
end
|
5
|
+
end
|
6
|
+
World(WithinHelpers)
|
@@ -1,52 +1,52 @@
|
|
1
|
-
module WindowsUIHelpers
|
2
|
-
# :nocov:
|
3
|
-
# button constants
|
4
|
-
BUTTONS_OK = 0
|
5
|
-
BUTTONS_OKCANCEL = 1
|
6
|
-
BUTTONS_ABORTRETRYIGNORE = 2
|
7
|
-
BUTTONS_YESNO = 4
|
8
|
-
|
9
|
-
# return code constants
|
10
|
-
CLICKED_OK = 1
|
11
|
-
CLICKED_CANCEL = 2
|
12
|
-
CLICKED_ABORT = 3
|
13
|
-
CLICKED_RETRY = 4
|
14
|
-
CLICKED_IGNORE = 5
|
15
|
-
CLICKED_YES = 6
|
16
|
-
CLICKED_NO = 7
|
17
|
-
APP_TITLE ='SimpliTest'
|
18
|
-
|
19
|
-
def message_box(txt, title, buttons)
|
20
|
-
MessageBox::MessageBoxA nil, txt, title, buttons
|
21
|
-
end
|
22
|
-
|
23
|
-
def user_consents_via_prompt?(question)
|
24
|
-
message_box(question, APP_TITLE, BUTTONS_YESNO) == CLICKED_YES
|
25
|
-
end
|
26
|
-
|
27
|
-
def user_informed_via_prompt?(message)
|
28
|
-
message_box(message, APP_TITLE, BUTTONS_OK) == CLICKED_OK
|
29
|
-
end
|
30
|
-
# :nocov:
|
31
|
-
end
|
32
|
-
|
33
|
-
|
34
|
-
# Create module as body for an importer instance
|
35
|
-
module MessageBox
|
36
|
-
# Load importer part of fiddle (ffi) library
|
37
|
-
require 'fiddle/import'
|
38
|
-
|
39
|
-
# Extend this module to an importer
|
40
|
-
extend Fiddle::Importer
|
41
|
-
# Load 'user32' dynamic library into this importer
|
42
|
-
dlload 'user32'
|
43
|
-
# Set C aliases to this importer for further understanding of function signatures
|
44
|
-
typealias 'HANDLE', 'void*'
|
45
|
-
typealias 'HWND', 'HANDLE'
|
46
|
-
typealias 'LPCSTR', 'const char*'
|
47
|
-
typealias 'LPCWSTR', 'const wchar_t*'
|
48
|
-
typealias 'UINT', 'unsigned int'
|
49
|
-
# Import C functions from loaded libraries and set them as module functions
|
50
|
-
extern 'int MessageBoxA(HWND, LPCSTR, LPCSTR, UINT)'
|
51
|
-
extern 'int MessageBoxW(HWND, LPCWSTR, LPCWSTR, UINT)'
|
1
|
+
module WindowsUIHelpers
|
2
|
+
# :nocov:
|
3
|
+
# button constants
|
4
|
+
BUTTONS_OK = 0
|
5
|
+
BUTTONS_OKCANCEL = 1
|
6
|
+
BUTTONS_ABORTRETRYIGNORE = 2
|
7
|
+
BUTTONS_YESNO = 4
|
8
|
+
|
9
|
+
# return code constants
|
10
|
+
CLICKED_OK = 1
|
11
|
+
CLICKED_CANCEL = 2
|
12
|
+
CLICKED_ABORT = 3
|
13
|
+
CLICKED_RETRY = 4
|
14
|
+
CLICKED_IGNORE = 5
|
15
|
+
CLICKED_YES = 6
|
16
|
+
CLICKED_NO = 7
|
17
|
+
APP_TITLE ='SimpliTest'
|
18
|
+
|
19
|
+
def message_box(txt, title, buttons)
|
20
|
+
MessageBox::MessageBoxA nil, txt, title, buttons
|
21
|
+
end
|
22
|
+
|
23
|
+
def user_consents_via_prompt?(question)
|
24
|
+
message_box(question, APP_TITLE, BUTTONS_YESNO) == CLICKED_YES
|
25
|
+
end
|
26
|
+
|
27
|
+
def user_informed_via_prompt?(message)
|
28
|
+
message_box(message, APP_TITLE, BUTTONS_OK) == CLICKED_OK
|
29
|
+
end
|
30
|
+
# :nocov:
|
31
|
+
end
|
32
|
+
|
33
|
+
|
34
|
+
# Create module as body for an importer instance
|
35
|
+
module MessageBox
|
36
|
+
# Load importer part of fiddle (ffi) library
|
37
|
+
require 'fiddle/import'
|
38
|
+
|
39
|
+
# Extend this module to an importer
|
40
|
+
extend Fiddle::Importer
|
41
|
+
# Load 'user32' dynamic library into this importer
|
42
|
+
dlload 'user32'
|
43
|
+
# Set C aliases to this importer for further understanding of function signatures
|
44
|
+
typealias 'HANDLE', 'void*'
|
45
|
+
typealias 'HWND', 'HANDLE'
|
46
|
+
typealias 'LPCSTR', 'const char*'
|
47
|
+
typealias 'LPCWSTR', 'const wchar_t*'
|
48
|
+
typealias 'UINT', 'unsigned int'
|
49
|
+
# Import C functions from loaded libraries and set them as module functions
|
50
|
+
extern 'int MessageBoxA(HWND, LPCSTR, LPCSTR, UINT)'
|
51
|
+
extern 'int MessageBoxW(HWND, LPCWSTR, LPCWSTR, UINT)'
|
52
52
|
end
|
@@ -1,19 +1,19 @@
|
|
1
|
-
#Example: Then show me the page
|
2
|
-
Then /^show me the page$/ do
|
3
|
-
save_and_open_page
|
4
|
-
end
|
5
|
-
|
6
|
-
#Example: And I wait 10 seconds
|
7
|
-
When /^I wait (\d+) second(?:|s)$/ do |seconds|
|
8
|
-
seconds = seconds.to_i #TODO: Write a God Damned Transformer for this for Christ's sake!!!!!
|
9
|
-
sleep(seconds)
|
10
|
-
end
|
11
|
-
|
12
|
-
#Example: And I take a screenshot
|
13
|
-
And /^I take a screenshot$/ do
|
14
|
-
timestamp = Time.now.strftime('%b_%e_%Y_%m_%M_%p')
|
15
|
-
dir = File.join(SimpliTest.config_support_directory, 'files', 'screenshots')
|
16
|
-
FileUtils.mkdir_p(dir) unless Dir.exists?(dir)
|
17
|
-
file_name = File.join(dir, "screenshot-#{timestamp}") + '.png'
|
18
|
-
capture_screenshot file_name
|
19
|
-
end
|
1
|
+
#Example: Then show me the page
|
2
|
+
Then /^show me the page$/ do
|
3
|
+
save_and_open_page
|
4
|
+
end
|
5
|
+
|
6
|
+
#Example: And I wait 10 seconds
|
7
|
+
When /^I wait (\d+) second(?:|s)$/ do |seconds|
|
8
|
+
seconds = seconds.to_i #TODO: Write a God Damned Transformer for this for Christ's sake!!!!!
|
9
|
+
sleep(seconds)
|
10
|
+
end
|
11
|
+
|
12
|
+
#Example: And I take a screenshot
|
13
|
+
And /^I take a screenshot$/ do
|
14
|
+
timestamp = Time.now.strftime('%b_%e_%Y_%m_%M_%p')
|
15
|
+
dir = File.join(SimpliTest.config_support_directory, 'files', 'screenshots')
|
16
|
+
FileUtils.mkdir_p(dir) unless Dir.exists?(dir)
|
17
|
+
file_name = File.join(dir, "screenshot-#{timestamp}") + '.png'
|
18
|
+
capture_screenshot file_name
|
19
|
+
end
|
@@ -1,352 +1,348 @@
|
|
1
|
-
# Use this to fill in an entire form with data from a table. Example:
|
2
|
-
#
|
3
|
-
# When I fill in the following:
|
4
|
-
# | Account Number | 5002 |
|
5
|
-
# | Expiry date | 2009-11-01 |
|
6
|
-
# | Note | Nice guy |
|
7
|
-
# | Wants Email? | |
|
8
|
-
# | Sex (select) | Male |
|
9
|
-
# | Accept user agrement (checkbox) | check |
|
10
|
-
# | Send me letters (checkbox) | uncheck |
|
11
|
-
# | radio 1 (radio) | choose |
|
12
|
-
# | Avatar (file) | avatar.png |
|
13
|
-
#
|
14
|
-
#Example: When I fill in the following:
|
15
|
-
When /^(?:|I )fill in the following:$/ do |fields|
|
16
|
-
|
17
|
-
select_tag = /^(.+\S+)\s*(?:\(select\))$/
|
18
|
-
check_box_tag = /^(.+\S+)\s*(?:\(checkbox\))$/
|
19
|
-
radio_button = /^(.+\S+)\s*(?:\(radio\))$/
|
20
|
-
file_field = /^(.+\S+)\s*(?:\(file\))$/
|
21
|
-
|
22
|
-
fields.rows_hash.each do |name, value|
|
23
|
-
case name
|
24
|
-
when select_tag
|
25
|
-
step %(I select "#{value}" from "#{$1}")
|
26
|
-
when check_box_tag
|
27
|
-
case value
|
28
|
-
when 'check'
|
29
|
-
step %(I check "#{$1}")
|
30
|
-
when 'uncheck'
|
31
|
-
step %(I uncheck "#{$1}")
|
32
|
-
else
|
33
|
-
raise 'checkbox values: check|uncheck!'
|
34
|
-
end
|
35
|
-
when radio_button
|
36
|
-
step %{I choose "#{$1}"}
|
37
|
-
when file_field
|
38
|
-
#step %{I attach the file "#{value}" to "#{$1}"}
|
39
|
-
else
|
40
|
-
step %{I fill in "#{name}" with "#{value}"}
|
41
|
-
end
|
42
|
-
end
|
43
|
-
end
|
44
|
-
|
45
|
-
#************************ UPLOAD A FILE *****************************************
|
46
|
-
#Example: When I attach the file "sample.txt" to "field_name"
|
47
|
-
When /^(?:|I )attach the file "([^"]*)" to "([^"]*)"$/ do |file, field|
|
48
|
-
dir = File.join(SimpliTest.config_support_directory, 'files', 'attachments')
|
49
|
-
FileUtils.mkdir_p(dir) unless Dir.exists?(dir)
|
50
|
-
path = File.join(dir, file)
|
51
|
-
raise RuntimeError, "file '#{path}' does not exists" unless File.exists?(path)
|
52
|
-
attach_file(field, path)
|
53
|
-
end
|
54
|
-
|
55
|
-
#************************ UPLOAD A FILE *****************************************
|
56
|
-
|
57
|
-
#************************ TEXT FIELDS ********************************************
|
58
|
-
|
59
|
-
|
60
|
-
#Example: When I fill in "Name" with "my name"
|
61
|
-
When /^(?:|I )fill in "([^"]*)" with "([^"]*)"$/ do |field, value|
|
62
|
-
selector, selector_type = selector_for(field)
|
63
|
-
if ['xpath', 'css'].include?(selector_type)
|
64
|
-
patiently do
|
65
|
-
element = find(selector_type.to_sym, selector)
|
66
|
-
element.set value
|
67
|
-
end
|
68
|
-
else
|
69
|
-
patiently { fill_in(field, :with => value) }
|
70
|
-
end
|
71
|
-
end
|
72
|
-
|
73
|
-
#TODO: Deprecate the step below
|
74
|
-
#Example: See Gist
|
75
|
-
When /^(?:|I )fill in "([^"]*)" with:$/ do |field, value|
|
76
|
-
selector, selector_type = selector_for(field)
|
77
|
-
if ['xpath', 'css'].include?(selector_type)
|
78
|
-
patiently do
|
79
|
-
element = find(selector_type.to_sym, selector)
|
80
|
-
element.set value
|
81
|
-
end
|
82
|
-
else
|
83
|
-
patiently { fill_in(field, :with => value) }
|
84
|
-
end
|
85
|
-
end
|
86
|
-
|
87
|
-
#Example: And I enter "I made this" in the "Describe yourself" field
|
88
|
-
When /^I enter "(.*?)" in the "(.*?)" field$/ do |value, field|
|
89
|
-
patiently do
|
90
|
-
step %Q{I fill in "#{field}" with "#{value}"}
|
91
|
-
step %Q{I move focus away from "#{field}"}
|
92
|
-
end
|
93
|
-
end
|
94
|
-
|
95
|
-
#TODO: Clean this code up, blur should handle xpath and name attributes as well
|
96
|
-
#Example: Then I key in the date "12/01/2013" in the "Date" field
|
97
|
-
When /^I key in the date "(.*?)" in the "(.*?)" field$/ do |date_rule, field|
|
98
|
-
selector, selector_type = selector_for(field)
|
99
|
-
value = calculated_date_from(date_rule)
|
100
|
-
raise "xpath is not yet supported for masked input. Please use the css selector instead" if selector_type == 'xpath'
|
101
|
-
patiently do
|
102
|
-
field = get_element_from(selector)
|
103
|
-
field.set(value)
|
104
|
-
end
|
105
|
-
end
|
106
|
-
|
107
|
-
#Example: When I key in "22031" in the "Location" field
|
108
|
-
When /^I key in "(.*?)" in the "(.*)" field$/ do |text, field|
|
109
|
-
selector, selector_type = selector_for(field)
|
110
|
-
if selector_type == 'other'
|
111
|
-
element = find_field(selector)
|
112
|
-
else
|
113
|
-
element = find(selector_type.to_sym, selector)
|
114
|
-
end
|
115
|
-
key_in text, element
|
116
|
-
end
|
117
|
-
|
118
|
-
|
119
|
-
#************************ END TEXT FIELDS ****************************************
|
120
|
-
|
121
|
-
|
122
|
-
#************************ DROP DOWNS**********************************************
|
123
|
-
|
124
|
-
|
125
|
-
#Example: When I select "Male" from "Sex"
|
126
|
-
When /^(?:|I )select "([^"]*)" from "([^"]*)"$/ do |value, select_field_name_id_or_text|
|
127
|
-
selector, selector_type = selector_for(select_field_name_id_or_text)
|
128
|
-
if selector_type == 'other'
|
129
|
-
patiently { select(value, :from => select_field_name_id_or_text) }
|
130
|
-
else
|
131
|
-
field = find(selector_type.to_sym, selector)
|
132
|
-
patiently { field.select value }
|
133
|
-
end
|
134
|
-
end
|
135
|
-
|
136
|
-
|
137
|
-
#************************ END DROP DOWNS******************************************
|
138
|
-
|
139
|
-
|
140
|
-
#************************ CHECKBOXES *********************************************
|
141
|
-
|
142
|
-
|
143
|
-
#Example: And I check "Accept user agrement"
|
144
|
-
When /^(?:|I )check "([^"]*)"$/ do |field|
|
145
|
-
selector, selector_type = selector_for(field)
|
146
|
-
if selector_type == 'other'
|
147
|
-
patiently { check(field) }
|
148
|
-
else
|
149
|
-
field = find(selector_type.to_sym, selector)
|
150
|
-
field.set(true)
|
151
|
-
end
|
152
|
-
end
|
153
|
-
|
154
|
-
#Example: When I uncheck "Send me letters"
|
155
|
-
When /^(?:|I )uncheck "([^"]*)"$/ do |field|
|
156
|
-
patiently { uncheck(field) }
|
157
|
-
end
|
158
|
-
|
159
|
-
|
160
|
-
#************************ END CHECKBOXES******************************************
|
161
|
-
|
162
|
-
|
163
|
-
#************************ MULTI SELECT BOXES *************************************
|
164
|
-
|
165
|
-
|
166
|
-
#Example: When I select following values from "Filters": Accepts Gherkin Table
|
167
|
-
When /^(?:I|i) select following values from "([^"]*)":$/ do |field, values|
|
168
|
-
values = values.transpose.raw
|
169
|
-
if values.size > 1
|
170
|
-
raise 'table should have only one column in this step!'
|
171
|
-
else
|
172
|
-
values = values.first
|
173
|
-
end
|
174
|
-
|
175
|
-
values.each do |value|
|
176
|
-
patiently { select(value, :from => field) }
|
177
|
-
end
|
178
|
-
end
|
179
|
-
|
180
|
-
#Example: When I unselect following values from "Filters": Accepts Gherkin Table
|
181
|
-
When /^(?:I|i) unselect following values from "([^"]*)":$/ do |field, values|
|
182
|
-
values = values.transpose.raw
|
183
|
-
if values.size > 1
|
184
|
-
raise 'table should have only one column in this step!'
|
185
|
-
else
|
186
|
-
values = values.first
|
187
|
-
end
|
188
|
-
|
189
|
-
values.each do |value|
|
190
|
-
patiently { unselect(value, :from => field) }
|
191
|
-
end
|
192
|
-
end
|
193
|
-
|
194
|
-
|
195
|
-
#************************ END MULTI SELECT BOXES *********************************
|
196
|
-
|
197
|
-
|
198
|
-
#************************ RADIO BUTTONS*******************************************
|
199
|
-
|
200
|
-
|
201
|
-
#Example: When I choose "radio 1"
|
202
|
-
When /^(?:|I )choose "([^"]*)"$/ do |field|
|
203
|
-
patiently { choose(field) }
|
204
|
-
end
|
205
|
-
|
206
|
-
#************************ END RADIO BUTTONS***************************************
|
207
|
-
|
208
|
-
|
209
|
-
#************************ BUTTONS AND LINKS***************************************
|
210
|
-
|
211
|
-
|
212
|
-
#Example: When I press "Submit"
|
213
|
-
When /^(?:|I )press "([^"]*)"$/ do |button|
|
214
|
-
patiently { click_on(button) }
|
215
|
-
end
|
216
|
-
#Example: When I press the 4th instance of "nextButton"
|
217
|
-
Given /^I press the (first|last|[0-9]+(?:th|st|rd|nd)) instance of "(.*?)"$/ do |index,link|
|
218
|
-
index = numerize index
|
219
|
-
locator, selector_type = selector_for(link)
|
220
|
-
selector_type = selector_type == 'xpath' ? :xpath : :css
|
221
|
-
patiently do
|
222
|
-
begin
|
223
|
-
elements = all(selector_type, locator)
|
224
|
-
element = elements[index]
|
225
|
-
element.click
|
226
|
-
rescue
|
227
|
-
raise Capybara::ElementNotFound
|
228
|
-
end
|
229
|
-
end
|
230
|
-
end
|
231
|
-
|
232
|
-
#Example: When I click the next page button
|
233
|
-
When /^I click the (first|last|next|previous) page button$/ do |index|
|
234
|
-
pagination_element_for(index).click
|
235
|
-
end
|
236
|
-
|
237
|
-
|
238
|
-
#Example: When I click the "Submit" button
|
239
|
-
When /^I click the "(.*?)" (?:button|link)$/ do |button_or_link|
|
240
|
-
patiently do
|
241
|
-
element = get_button_or_link_from(button_or_link)
|
242
|
-
click_element(element)
|
243
|
-
end
|
244
|
-
end
|
245
|
-
|
246
|
-
|
247
|
-
#************************ END BUTTONS AND LINKS***********************************
|
248
|
-
|
249
|
-
|
250
|
-
#************************ PAGINATION ***********************************
|
251
|
-
#Example: When I go to page 1
|
252
|
-
When /^I go to page (\d+)$/ do |page_number|
|
253
|
-
pagination_links_for(page_number).first.click
|
254
|
-
end
|
255
|
-
|
256
|
-
|
257
|
-
#************************ KEYBOARD EVENTS ****************************************
|
258
|
-
|
259
|
-
#Example: Not implemented yet
|
260
|
-
When /^I move focus away from "(.*)"$/ do |locator|
|
261
|
-
element = get_element_from(locator)
|
262
|
-
tab_on element
|
263
|
-
end
|
264
|
-
|
265
|
-
#Example: When I press keydown on "LocationCSSSelector"
|
266
|
-
When /^I press keydown on "(.*)"$/ do |locator|
|
267
|
-
#selector, selector_type = selector_for(locator)
|
268
|
-
#element = get_element_from(locator)
|
269
|
-
#if selector_type == 'css'
|
270
|
-
#script = "var e = $.Event('keydown');e.keyCode = 40;$('#{locator}').trigger(e)"
|
271
|
-
#script = "var e = $.Event('keydown', { keyCode: 40 }); $('#nameTxtBox').trigger(e)"
|
272
|
-
#execute_js script
|
273
|
-
#keydown_on(element)
|
274
|
-
#else
|
275
|
-
#raise "OnlyCSSSelectorsAreSupported"
|
276
|
-
#end
|
277
|
-
end
|
278
|
-
|
279
|
-
|
280
|
-
|
281
|
-
#************************ END KEYBOARD EVENTS ************************************
|
282
|
-
|
283
|
-
|
284
|
-
#************************ MOUSE EVENTS *******************************************
|
285
|
-
#Example: And I hover over "BidPlansMenu"
|
286
|
-
Then /^I hover over "(.*?)"$/ do |locator|
|
287
|
-
element = get_element_from(locator)
|
288
|
-
element.hover
|
289
|
-
end
|
290
|
-
|
291
|
-
#************************ END MOUSE EVENTS ***************************************
|
292
|
-
|
293
|
-
#************************ MODAL AND DIALOGS **************************************
|
294
|
-
|
295
|
-
|
296
|
-
#Example: And I accept the confirmation dialog
|
297
|
-
When /^I accept the confirmation dialog box$/ do
|
298
|
-
page.driver.browser.switch_to.alert.accept
|
299
|
-
|
300
|
-
#accept_confirmation
|
301
|
-
end
|
302
|
-
|
303
|
-
|
304
|
-
|
305
|
-
|
306
|
-
|
307
|
-
|
308
|
-
|
309
|
-
|
310
|
-
|
311
|
-
|
312
|
-
|
313
|
-
|
314
|
-
|
315
|
-
|
316
|
-
|
317
|
-
|
318
|
-
|
319
|
-
|
320
|
-
|
321
|
-
|
322
|
-
|
323
|
-
|
324
|
-
|
325
|
-
|
326
|
-
|
327
|
-
|
328
|
-
|
329
|
-
|
330
|
-
|
331
|
-
|
332
|
-
|
333
|
-
|
334
|
-
|
335
|
-
|
336
|
-
|
337
|
-
|
338
|
-
|
339
|
-
|
340
|
-
|
341
|
-
|
342
|
-
|
343
|
-
|
344
|
-
|
345
|
-
|
346
|
-
|
347
|
-
|
348
|
-
|
349
|
-
click_element(element)
|
350
|
-
end
|
351
|
-
end
|
352
|
-
|
1
|
+
# Use this to fill in an entire form with data from a table. Example:
|
2
|
+
#
|
3
|
+
# When I fill in the following:
|
4
|
+
# | Account Number | 5002 |
|
5
|
+
# | Expiry date | 2009-11-01 |
|
6
|
+
# | Note | Nice guy |
|
7
|
+
# | Wants Email? | |
|
8
|
+
# | Sex (select) | Male |
|
9
|
+
# | Accept user agrement (checkbox) | check |
|
10
|
+
# | Send me letters (checkbox) | uncheck |
|
11
|
+
# | radio 1 (radio) | choose |
|
12
|
+
# | Avatar (file) | avatar.png |
|
13
|
+
#
|
14
|
+
#Example: When I fill in the following:
|
15
|
+
When /^(?:|I )fill in the following:$/ do |fields|
|
16
|
+
|
17
|
+
select_tag = /^(.+\S+)\s*(?:\(select\))$/
|
18
|
+
check_box_tag = /^(.+\S+)\s*(?:\(checkbox\))$/
|
19
|
+
radio_button = /^(.+\S+)\s*(?:\(radio\))$/
|
20
|
+
file_field = /^(.+\S+)\s*(?:\(file\))$/
|
21
|
+
|
22
|
+
fields.rows_hash.each do |name, value|
|
23
|
+
case name
|
24
|
+
when select_tag
|
25
|
+
step %(I select "#{value}" from "#{$1}")
|
26
|
+
when check_box_tag
|
27
|
+
case value
|
28
|
+
when 'check'
|
29
|
+
step %(I check "#{$1}")
|
30
|
+
when 'uncheck'
|
31
|
+
step %(I uncheck "#{$1}")
|
32
|
+
else
|
33
|
+
raise 'checkbox values: check|uncheck!'
|
34
|
+
end
|
35
|
+
when radio_button
|
36
|
+
step %{I choose "#{$1}"}
|
37
|
+
when file_field
|
38
|
+
#step %{I attach the file "#{value}" to "#{$1}"}
|
39
|
+
else
|
40
|
+
step %{I fill in "#{name}" with "#{value}"}
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
#************************ UPLOAD A FILE *****************************************
|
46
|
+
#Example: When I attach the file "sample.txt" to "field_name"
|
47
|
+
When /^(?:|I )attach the file "([^"]*)" to "([^"]*)"$/ do |file, field|
|
48
|
+
dir = File.join(SimpliTest.config_support_directory, 'files', 'attachments')
|
49
|
+
FileUtils.mkdir_p(dir) unless Dir.exists?(dir)
|
50
|
+
path = File.join(dir, file)
|
51
|
+
raise RuntimeError, "file '#{path}' does not exists" unless File.exists?(path)
|
52
|
+
attach_file(field, path)
|
53
|
+
end
|
54
|
+
|
55
|
+
#************************ UPLOAD A FILE *****************************************
|
56
|
+
|
57
|
+
#************************ TEXT FIELDS ********************************************
|
58
|
+
|
59
|
+
|
60
|
+
#Example: When I fill in "Name" with "my name"
|
61
|
+
When /^(?:|I )fill in "([^"]*)" with "([^"]*)"$/ do |field, value|
|
62
|
+
selector, selector_type = selector_for(field)
|
63
|
+
if ['xpath', 'css'].include?(selector_type)
|
64
|
+
patiently do
|
65
|
+
element = find(selector_type.to_sym, selector)
|
66
|
+
element.set value
|
67
|
+
end
|
68
|
+
else
|
69
|
+
patiently { fill_in(field, :with => value) }
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
#TODO: Deprecate the step below
|
74
|
+
#Example: See Gist
|
75
|
+
When /^(?:|I )fill in "([^"]*)" with:$/ do |field, value|
|
76
|
+
selector, selector_type = selector_for(field)
|
77
|
+
if ['xpath', 'css'].include?(selector_type)
|
78
|
+
patiently do
|
79
|
+
element = find(selector_type.to_sym, selector)
|
80
|
+
element.set value
|
81
|
+
end
|
82
|
+
else
|
83
|
+
patiently { fill_in(field, :with => value) }
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
#Example: And I enter "I made this" in the "Describe yourself" field
|
88
|
+
When /^I enter "(.*?)" in the "(.*?)" field$/ do |value, field|
|
89
|
+
patiently do
|
90
|
+
step %Q{I fill in "#{field}" with "#{value}"}
|
91
|
+
step %Q{I move focus away from "#{field}"}
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
95
|
+
#TODO: Clean this code up, blur should handle xpath and name attributes as well
|
96
|
+
#Example: Then I key in the date "12/01/2013" in the "Date" field
|
97
|
+
When /^I key in the date "(.*?)" in the "(.*?)" field$/ do |date_rule, field|
|
98
|
+
selector, selector_type = selector_for(field)
|
99
|
+
value = calculated_date_from(date_rule)
|
100
|
+
raise "xpath is not yet supported for masked input. Please use the css selector instead" if selector_type == 'xpath'
|
101
|
+
patiently do
|
102
|
+
field = get_element_from(selector)
|
103
|
+
field.set(value)
|
104
|
+
end
|
105
|
+
end
|
106
|
+
|
107
|
+
#Example: When I key in "22031" in the "Location" field
|
108
|
+
When /^I key in "(.*?)" in the "(.*)" field$/ do |text, field|
|
109
|
+
selector, selector_type = selector_for(field)
|
110
|
+
if selector_type == 'other'
|
111
|
+
element = find_field(selector)
|
112
|
+
else
|
113
|
+
element = find(selector_type.to_sym, selector)
|
114
|
+
end
|
115
|
+
key_in text, element
|
116
|
+
end
|
117
|
+
|
118
|
+
|
119
|
+
#************************ END TEXT FIELDS ****************************************
|
120
|
+
|
121
|
+
|
122
|
+
#************************ DROP DOWNS**********************************************
|
123
|
+
|
124
|
+
|
125
|
+
#Example: When I select "Male" from "Sex"
|
126
|
+
When /^(?:|I )select "([^"]*)" from "([^"]*)"$/ do |value, select_field_name_id_or_text|
|
127
|
+
selector, selector_type = selector_for(select_field_name_id_or_text)
|
128
|
+
if selector_type == 'other'
|
129
|
+
patiently { select(value, :from => select_field_name_id_or_text) }
|
130
|
+
else
|
131
|
+
field = find(selector_type.to_sym, selector)
|
132
|
+
patiently { field.select value }
|
133
|
+
end
|
134
|
+
end
|
135
|
+
|
136
|
+
|
137
|
+
#************************ END DROP DOWNS******************************************
|
138
|
+
|
139
|
+
|
140
|
+
#************************ CHECKBOXES *********************************************
|
141
|
+
|
142
|
+
|
143
|
+
#Example: And I check "Accept user agrement"
|
144
|
+
When /^(?:|I )check "([^"]*)"$/ do |field|
|
145
|
+
selector, selector_type = selector_for(field)
|
146
|
+
if selector_type == 'other'
|
147
|
+
patiently { check(field) }
|
148
|
+
else
|
149
|
+
field = find(selector_type.to_sym, selector)
|
150
|
+
field.set(true)
|
151
|
+
end
|
152
|
+
end
|
153
|
+
|
154
|
+
#Example: When I uncheck "Send me letters"
|
155
|
+
When /^(?:|I )uncheck "([^"]*)"$/ do |field|
|
156
|
+
patiently { uncheck(field) }
|
157
|
+
end
|
158
|
+
|
159
|
+
|
160
|
+
#************************ END CHECKBOXES******************************************
|
161
|
+
|
162
|
+
|
163
|
+
#************************ MULTI SELECT BOXES *************************************
|
164
|
+
|
165
|
+
|
166
|
+
#Example: When I select following values from "Filters": Accepts Gherkin Table
|
167
|
+
When /^(?:I|i) select following values from "([^"]*)":$/ do |field, values|
|
168
|
+
values = values.transpose.raw
|
169
|
+
if values.size > 1
|
170
|
+
raise 'table should have only one column in this step!'
|
171
|
+
else
|
172
|
+
values = values.first
|
173
|
+
end
|
174
|
+
|
175
|
+
values.each do |value|
|
176
|
+
patiently { select(value, :from => field) }
|
177
|
+
end
|
178
|
+
end
|
179
|
+
|
180
|
+
#Example: When I unselect following values from "Filters": Accepts Gherkin Table
|
181
|
+
When /^(?:I|i) unselect following values from "([^"]*)":$/ do |field, values|
|
182
|
+
values = values.transpose.raw
|
183
|
+
if values.size > 1
|
184
|
+
raise 'table should have only one column in this step!'
|
185
|
+
else
|
186
|
+
values = values.first
|
187
|
+
end
|
188
|
+
|
189
|
+
values.each do |value|
|
190
|
+
patiently { unselect(value, :from => field) }
|
191
|
+
end
|
192
|
+
end
|
193
|
+
|
194
|
+
|
195
|
+
#************************ END MULTI SELECT BOXES *********************************
|
196
|
+
|
197
|
+
|
198
|
+
#************************ RADIO BUTTONS*******************************************
|
199
|
+
|
200
|
+
|
201
|
+
#Example: When I choose "radio 1"
|
202
|
+
When /^(?:|I )choose "([^"]*)"$/ do |field|
|
203
|
+
patiently { choose(field) }
|
204
|
+
end
|
205
|
+
|
206
|
+
#************************ END RADIO BUTTONS***************************************
|
207
|
+
|
208
|
+
|
209
|
+
#************************ BUTTONS AND LINKS***************************************
|
210
|
+
|
211
|
+
|
212
|
+
#Example: When I press "Submit"
|
213
|
+
When /^(?:|I )press "([^"]*)"$/ do |button|
|
214
|
+
patiently { click_on(button) }
|
215
|
+
end
|
216
|
+
#Example: When I press the 4th instance of "nextButton"
|
217
|
+
Given /^I press the (first|last|[0-9]+(?:th|st|rd|nd)) instance of "(.*?)"$/ do |index,link|
|
218
|
+
index = numerize index
|
219
|
+
locator, selector_type = selector_for(link)
|
220
|
+
selector_type = selector_type == 'xpath' ? :xpath : :css
|
221
|
+
patiently do
|
222
|
+
begin
|
223
|
+
elements = all(selector_type, locator)
|
224
|
+
element = elements[index]
|
225
|
+
element.click
|
226
|
+
rescue
|
227
|
+
raise Capybara::ElementNotFound
|
228
|
+
end
|
229
|
+
end
|
230
|
+
end
|
231
|
+
|
232
|
+
#Example: When I click the next page button
|
233
|
+
When /^I click the (first|last|next|previous) page button$/ do |index|
|
234
|
+
pagination_element_for(index).click
|
235
|
+
end
|
236
|
+
|
237
|
+
|
238
|
+
#Example: When I click the "Submit" button
|
239
|
+
When /^I click the "(.*?)" (?:button|link)$/ do |button_or_link|
|
240
|
+
patiently do
|
241
|
+
element = get_button_or_link_from(button_or_link)
|
242
|
+
click_element(element)
|
243
|
+
end
|
244
|
+
end
|
245
|
+
|
246
|
+
|
247
|
+
#************************ END BUTTONS AND LINKS***********************************
|
248
|
+
|
249
|
+
|
250
|
+
#************************ PAGINATION ***********************************
|
251
|
+
#Example: When I go to page 1
|
252
|
+
When /^I go to page (\d+)$/ do |page_number|
|
253
|
+
pagination_links_for(page_number).first.click
|
254
|
+
end
|
255
|
+
|
256
|
+
|
257
|
+
#************************ KEYBOARD EVENTS ****************************************
|
258
|
+
|
259
|
+
#Example: Not implemented yet
|
260
|
+
When /^I move focus away from "(.*)"$/ do |locator|
|
261
|
+
element = get_element_from(locator)
|
262
|
+
tab_on element
|
263
|
+
end
|
264
|
+
|
265
|
+
#Example: When I press keydown on "LocationCSSSelector"
|
266
|
+
When /^I press keydown on "(.*)"$/ do |locator|
|
267
|
+
#selector, selector_type = selector_for(locator)
|
268
|
+
#element = get_element_from(locator)
|
269
|
+
#if selector_type == 'css'
|
270
|
+
#script = "var e = $.Event('keydown');e.keyCode = 40;$('#{locator}').trigger(e)"
|
271
|
+
#script = "var e = $.Event('keydown', { keyCode: 40 }); $('#nameTxtBox').trigger(e)"
|
272
|
+
#execute_js script
|
273
|
+
#keydown_on(element)
|
274
|
+
#else
|
275
|
+
#raise "OnlyCSSSelectorsAreSupported"
|
276
|
+
#end
|
277
|
+
end
|
278
|
+
|
279
|
+
|
280
|
+
|
281
|
+
#************************ END KEYBOARD EVENTS ************************************
|
282
|
+
|
283
|
+
|
284
|
+
#************************ MOUSE EVENTS *******************************************
|
285
|
+
#Example: And I hover over "BidPlansMenu"
|
286
|
+
Then /^I hover over "(.*?)"$/ do |locator|
|
287
|
+
element = get_element_from(locator)
|
288
|
+
element.hover
|
289
|
+
end
|
290
|
+
|
291
|
+
#************************ END MOUSE EVENTS ***************************************
|
292
|
+
|
293
|
+
#************************ MODAL AND DIALOGS **************************************
|
294
|
+
|
295
|
+
|
296
|
+
#Example: And I accept the confirmation dialog
|
297
|
+
When /^I accept the confirmation dialog box$/ do
|
298
|
+
page.driver.browser.switch_to.alert.accept
|
299
|
+
|
300
|
+
#accept_confirmation
|
301
|
+
end
|
302
|
+
|
303
|
+
|
304
|
+
#************************ END MODAL AND DIALOGS **********************************
|
305
|
+
|
306
|
+
#Example: Then I attach file "testAttachment.txt" to "File"
|
307
|
+
Then /^I attach file "([^"]*)" to "([^"]*)"$/ do |file, field|
|
308
|
+
dir = File.join(SimpliTest.config_support_directory, 'files', 'attachments')
|
309
|
+
FileUtils.mkdir_p(dir) unless Dir.exists?(dir)
|
310
|
+
path = File.join(dir, file)
|
311
|
+
raise RuntimeError, "file '#{path}' does not exists" unless File.exists?(path)
|
312
|
+
|
313
|
+
element = get_element_from(field)
|
314
|
+
element.send_keys(path)
|
315
|
+
end
|
316
|
+
|
317
|
+
# Enter's current date in a field (e.g., 03/01/2016)
|
318
|
+
|
319
|
+
#Example: Then I enter today's date in the "date" field"
|
320
|
+
Then /^(?:|I )[Ee]nter today's date in the "([^"]*)" field$/ do |locator|
|
321
|
+
element = get_element_from(locator)
|
322
|
+
element.set Date.today.strftime('%m/%d/%Y')
|
323
|
+
end
|
324
|
+
|
325
|
+
#Example: Then I verify "date" field has today's date
|
326
|
+
Then(/^I verify "([^"]*)" field has today's date$/) do |locator|
|
327
|
+
date_td = get_element_from(locator).value
|
328
|
+
date_td.should == Date.today.strftime('%m/%d/%Y')
|
329
|
+
end
|
330
|
+
|
331
|
+
#Example: When I right-click "some element" and then click "Some Link" option
|
332
|
+
When /^I right-click on "(.*?)" and then click the "(.*?)" option$/ do | locator, link|
|
333
|
+
|
334
|
+
element = find('.x-grid-cell',:text => locator, :exact => true)
|
335
|
+
element.right_click
|
336
|
+
menulink = get_button_or_link_from(link)
|
337
|
+
click_element(menulink)
|
338
|
+
|
339
|
+
end
|
340
|
+
|
341
|
+
#Example: When I click the "Submit" tab
|
342
|
+
When /^I click the "(.*?)" tab$/ do |button_or_link|
|
343
|
+
patiently do
|
344
|
+
element = get_button_or_link_from(button_or_link)
|
345
|
+
click_element(element)
|
346
|
+
end
|
347
|
+
end
|
348
|
+
|