Ifd_Automation 1.9.2 → 2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (38) hide show
  1. checksums.yaml +4 -4
  2. data/bin/documentation_generator.rb +1 -1
  3. data/lib/Ifd_Automation/REST_steps.rb +105 -0
  4. data/lib/Ifd_Automation/SOAP_steps.rb +54 -0
  5. data/lib/Ifd_Automation/database_steps.rb +17 -47
  6. data/lib/Ifd_Automation/dynamic_store_vavue_steps.rb +25 -0
  7. data/lib/Ifd_Automation/email_steps.rb +32 -36
  8. data/lib/Ifd_Automation/file_steps.rb +7 -58
  9. data/lib/Ifd_Automation/require_libs.rb +6 -0
  10. data/lib/Ifd_Automation/ssh_steps.rb +14 -23
  11. data/lib/Ifd_Automation/version.rb +1 -1
  12. data/lib/Ifd_Automation/web_steps.rb +58 -293
  13. data/lib/helper/assertion_helpers.rb +100 -0
  14. data/lib/helper/auto_utils.rb +67 -0
  15. data/lib/{Ifd_Automation_support → helper}/connection_helpers.rb +2 -2
  16. data/lib/{Ifd_Automation_support → helper}/core.rb +154 -60
  17. data/lib/{Ifd_Automation_support → helper}/mail_helpers.rb +2 -2
  18. data/lib/helper/web_steps_helpers.rb +123 -0
  19. data/project/Gemfile +1 -2
  20. data/project/features/Screenshot/failed_sample.png +0 -0
  21. data/project/features/TestData/globalData.yml +4 -1
  22. data/project/features/TestSuite/test.feature +1 -4
  23. data/project/features/step_definitions/lib_steps/test.rb +5 -3
  24. data/project/features/step_definitions/repositories/project_object.yml +2 -2
  25. data/project/features/support/env.rb +53 -52
  26. data/project/features/support/hooks.rb +2 -0
  27. data/project/features/support/project_config.yml +6 -6
  28. metadata +36 -148
  29. data/lib/Ifd_Automation/javascript_steps.rb +0 -33
  30. data/lib/Ifd_Automation/required_libs.rb +0 -7
  31. data/lib/Ifd_Automation/response.rb +0 -105
  32. data/lib/Ifd_Automation/webservice_steps.rb +0 -281
  33. data/lib/Ifd_Automation_support/assertion_helpers.rb +0 -205
  34. data/lib/Ifd_Automation_support/javascript_helpers.rb +0 -45
  35. data/lib/Ifd_Automation_support/selenium_sync_issues.rb +0 -62
  36. data/lib/Ifd_Automation_support/web_steps_helpers.rb +0 -296
  37. data/project/Gemfile.lock +0 -203
  38. data/project/Rakefile +0 -46
@@ -1,45 +0,0 @@
1
-
2
- def handle_alert(decision)
3
- if decision == 'accept'
4
- page.driver.browser.switch_to.alert.accept
5
- else
6
- page.driver.browser.switch_to.alert.dismiss
7
- end
8
- end
9
-
10
- def switch_to_windows(decision)
11
- if decision == 'last'
12
- page.driver.browser.switch_to.window(page.driver.browser.window_handles.last)
13
- else
14
- page.driver.browser.switch_to.window(page.driver.browser.window_handles.first)
15
- end
16
- end
17
-
18
- def close_windows
19
- page.driver.browser.close
20
- page.driver.browser.switch_to.window(page.driver.browser.window_handles[0])
21
- end
22
-
23
- def get_browser_back
24
- page.evaluate_script('window.history.back()')
25
- end
26
-
27
- def refresh_page
28
- visit page.driver.browser.current_url
29
- end
30
-
31
- def open_new_windows_browser
32
- page.driver.execute_script("window.open()")
33
- end
34
-
35
- # method to get javascript pop-up alert text
36
- def get_alert_text
37
- page.driver.browser.switch_to.alert.text
38
- end
39
-
40
- # method to check javascript pop-up alert text
41
- def check_alert_text(text)
42
- if get_alert_text != text
43
- raise TestCaseFailed, "Text on alert pop up not matched, Actual Text : #{get_alert_text}, Expected Text : #{text}"
44
- end
45
- end
@@ -1,62 +0,0 @@
1
- # coding: UTF-8
2
-
3
- module SeleniumSyncIssues
4
- RETRY_ERRORS = %w[
5
- Capybara::ElementNotFound
6
- Spec::Expectations::ExpectationNotMetError
7
- RSpec::Expectations::ExpectationNotMetError
8
- Minitest::Assertion
9
- Capybara::Poltergeist::ClickFailed
10
- Capybara::ExpectationNotMet
11
- Selenium::WebDriver::Error::StaleElementReferenceError
12
- Selenium::WebDriver::Error::NoAlertPresentError
13
- Selenium::WebDriver::Error::ElementNotVisibleError
14
- Selenium::WebDriver::Error::NoSuchFrameError
15
- Selenium::WebDriver::Error::NoAlertPresentError
16
- Selenium::WebDriver::Error::JavascriptError
17
- Selenium::WebDriver::Error::UnknownError
18
- ]
19
-
20
- class CapybaraWrapper
21
- def self.default_max_wait_time
22
- if Capybara.respond_to?(:default_max_wait_time)
23
- Capybara.default_max_wait_time
24
- else
25
- Capybara.default_wait_time
26
- end
27
- end
28
-
29
- def self.default_max_wait_time=(value)
30
- if Capybara.respond_to?(:default_max_wait_time=)
31
- Capybara.default_max_wait_time = value
32
- else
33
- Capybara.default_wait_time = value
34
- end
35
- end
36
- end
37
-
38
- # This is similiar but not entirely the same as Capybara::Node::Base#wait_until or Capybara::Session#wait_until
39
- def patiently(seconds = CapybaraWrapper.default_max_wait_time, &block)
40
- old_wait_time = CapybaraWrapper.default_max_wait_time
41
- # dont make nested wait_untils use up all the alloted time
42
- CapybaraWrapper.default_max_wait_time = 0 # for we are a jealous gem
43
- if page.driver.wait?
44
- start_time = Time.now
45
- begin
46
- block.call
47
- rescue Exception => e
48
- raise e unless RETRY_ERRORS.include?(e.class.name)
49
- raise e if (Time.now - start_time) >= seconds
50
- sleep(0.05)
51
- 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
52
- retry
53
- end
54
- else
55
- block.call
56
- end
57
- ensure
58
- CapybaraWrapper.default_max_wait_time = old_wait_time
59
- end
60
- end
61
-
62
- World(SeleniumSyncIssues)
@@ -1,296 +0,0 @@
1
- require 'net/https'
2
- # require 'Ifd_Automation_support/core'
3
-
4
- # This file contains assertion methods which are called from assertion_steps.rb
5
-
6
- # Method to return page title
7
- def get_page_title
8
- page.title
9
- end
10
-
11
- # Method to verify title
12
- # param 1 : String : expected title
13
- # param 2 : Boolean : test case [true or flase]
14
- def check_title(title, test_case)
15
- page_title = get_page_title
16
- if test_case
17
- if page_title != "#{title}"
18
- raise TestCaseFailed, "Page Title Not Matched, Actual Page Title : #{page_title}, Expected Page Title : #{title}"
19
- end
20
- else
21
- if page_title == "#{title}"
22
- raise TestCaseFailed, "Page Title Matched, Actual Page Title: #{page_title}"
23
- end
24
- end
25
- end
26
-
27
- # Method to verify partial title
28
- # param 1 : String : partial title string
29
- # param 2 : Boolean : test case [true or flase]
30
- def check_partial_title(partial_text_title, test_case)
31
- page_title = get_page_title
32
- if test_case
33
- if not page_title.include? "#{partial_text_title}"
34
- raise TestCaseFailed, 'Partial Page Title Not Present'
35
- end
36
- else
37
- if page_title.include? "#{partial_text_title}"
38
- raise TestCaseFailed, 'Page Title Matched'
39
- end
40
- end
41
- end
42
-
43
-
44
- # Open Browser with config-able maximize browser option
45
- def execute_openbrowser url_site #, redirect
46
- begin
47
- if $_CFWEB['Maximize Browser'] == true
48
- page.driver.browser.manage.window.maximize
49
- end
50
- rescue StandardError => myStandardError
51
- put_log "\n>>> Error: #{myStandardError}"
52
- end
53
-
54
- if url_site == ""
55
- visit("")
56
- else
57
- visit(url_site)
58
- end
59
- end
60
-
61
- # Click on element
62
- def execute_click element
63
- foundElement = find_object(element)
64
- if foundElement != nil
65
- page.driver.execute_script('window.focus();')
66
- startTime = Time.new.to_i
67
- begin
68
- sleep(0.5)
69
- currentTime = Time.new.to_i
70
- end while (foundElement.native.enabled? == false and (currentTime - startTime) < $_CFWEB['Wait Time'])
71
- page.driver.browser.execute_script("arguments[0].scrollIntoView(true);", foundElement.native)
72
- page.driver.browser.mouse.click(foundElement.native)
73
- else
74
- put_log "\nError >> Not found object: #{element}"
75
- end
76
- end
77
-
78
- # Set option state with state value True/False
79
- def execute_setstate element, state
80
- foundElement = find_object(element)
81
- if foundElement != nil
82
- if state.upcase == "TRUE"
83
- foundElement.set(true)
84
- else
85
- foundElement.set(false)
86
- end
87
- else
88
- put_log "\nError >> Not found object: #{element}"
89
- exit
90
- end
91
- end
92
-
93
- #Enter text to element
94
- def execute_settext element, text
95
- foundElement = find_object(element)
96
- if foundElement != nil
97
- begin
98
- foundElement.set(text)
99
- #page.driver.browser.mouse.click(foundElement.native)
100
- #foundElement.native.send_keys(text)
101
- # put_log "\nfoundElement.value: #{foundElement.value}"
102
- #foundElement.native.send_keys([:tab])
103
- rescue StandardError => myStandardError
104
- put_log "\n>>> Error: #{myStandardError}"
105
- end
106
- else
107
- put_log "\nError >> Not found object: #{element}"
108
- exit
109
- end
110
- end
111
-
112
- # Move mouse to element then click
113
- def execute_mousehoverandclick element
114
- foundElement = find_object(element)
115
- if foundElement != nil
116
- page.driver.browser.mouse.move_to(foundElement.native, element)
117
- page.driver.browser.mouse.click(foundElement.native)
118
- sleep(2)
119
- else
120
- put_log "\nError >> Not found object: #{element}"
121
- end
122
- end
123
-
124
- def execute_drag_to_new_object from_element, element
125
- found_from_element = find_object(from_element)
126
- foundElement = find_object(element)
127
- if foundElement != nil and found_from_element != nil
128
- found_from_element.drag_to(foundElement)
129
- end
130
- end
131
-
132
- def execute_hover_mouse_on element
133
- foundElement = find_object(element)
134
- if foundElement != nil
135
- page.driver.browser.mouse.move_to(foundElement.native, element)
136
- sleep 1
137
- else
138
- put_log "\nError >> Not found object: #{element}"
139
- end
140
- end
141
-
142
- def execute_click_to_upload object, file_name
143
- upload_file = ($test_data_dir + file_name).gsub!(/\//, "\\")
144
- foundElement = find_object(object)
145
- if foundElement != nil
146
- call_step("I click on \"#{object}\"")
147
- window = RAutomation::Window.new(:title => /File Upload/)
148
- window.text_field(:class => "Edit").set(upload_file)
149
- window.button(:value => "&Open").click
150
- else
151
- raise "Error >> Object #{object} not found.!"
152
- end
153
- end
154
-
155
- # Check exists
156
- def execute_checkexists negate, element, timeout
157
- origin_timeout = $_CFWEB['Wait Time']
158
- set_time_out(timeout)
159
- foundElement = find_object(element)
160
- set_time_out(origin_timeout)
161
- #put_log "\nexecute_checkexists : #{foundElement}"
162
- check = false
163
- if foundElement != nil
164
- check = true
165
- end
166
-
167
- negate = negate.strip if negate != nil
168
- #puts "---------->#{negate}"
169
- if negate == "not"
170
- # check.should_not eq true
171
- expect(check).not_to eql true
172
- elsif check.should eq true
173
- expect(check).to eq true
174
- end
175
- end
176
-
177
- # Send Key
178
- def execute_sendkeys element, text
179
- foundElement = find_object(element)
180
- if foundElement != nil
181
- if foundElement[:disabled] == ''
182
- if text == ":down"
183
- foundElement.native.send_keys([:down])
184
- elsif text == ":enter"
185
- foundElement.native.send_keys([:enter])
186
- elsif text == ":tab"
187
- foundElement.native.send_keys([:tab])
188
- else
189
- foundElement.native.send_keys(text)
190
- end
191
- end
192
- else
193
- put_log "\nError >> Not found object: #{element}"
194
- exit
195
- end
196
- end
197
-
198
- # method to scroll page to top or end
199
- def scroll_page(to)
200
- if to == 'end'
201
- page.driver.execute_script('window.scrollTo(0,Math.max(document.documentElement.scrollHeight,document.body.scrollHeight,document.documentElement.clientHeight));')
202
- elsif to == 'top'
203
- page.driver.execute_script('window.scrollTo(Math.max(document.documentElement.scrollHeight,document.body.scrollHeight,document.documentElement.clientHeight),0);')
204
- else
205
- raise "Exception : Invalid Direction (only scroll \"top\" or \"end\")"
206
- end
207
- end
208
-
209
- # Method to return element status - enabled?
210
- # param 1 : String : Locator type (id, name, class, xpath, css)
211
- # param 2 : String : Locator value
212
- def is_element_enabled(element)
213
- foundElement = find_object(element)
214
- expect(foundElement).to be_visible
215
- end
216
-
217
- # Element enabled checking
218
- # param 1 : String : Expected element text
219
- # param 2 : Boolean : test case [true or flase]
220
- def check_element_enable(element, test_case)
221
- result = is_element_enabled(element)
222
-
223
- if test_case
224
- raise TestCaseFailed, 'Element Not Enabled' unless result
225
- else
226
- raise TestCaseFailed, 'Element Enabled' unless !result
227
- end
228
- end
229
-
230
-
231
- # method to assert checkbox check/uncheck
232
- # param 1 : String : Locator value
233
- # param 2 : Boolean : test case [true or flase]
234
- def is_checkbox_checked(element, should_be_checked = true)
235
- foundElement = find_object(element)
236
- checkbox = expect(foundElement).to be_checked
237
-
238
- if !checkbox && should_be_checked
239
- raise TestCaseFailed, 'Checkbox is not checked'
240
- elsif checkbox && !should_be_checked
241
- raise TestCaseFailed, 'Checkbox is checked'
242
- end
243
- end
244
-
245
- # method to assert radio button selected/unselected
246
- # param 1 : String : Locator value
247
- # param 2 : Boolean : test case [true or flase]
248
- def is_radio_button_selected(element, should_be_selected = true)
249
- foundElement = find_object(element)
250
- radio = expect(foundElement).to be_checked
251
-
252
- if !radio && should_be_selected
253
- raise TestCaseFailed, 'Radio Button not selected'
254
- elsif radio && !should_be_selected
255
- raise TestCaseFailed, 'Radio Button is selected'
256
- end
257
- end
258
-
259
- def double_click(element)
260
- foundElement = find_object(element)
261
- page.driver.browser.mouse.double_click(foundElement.native)
262
- end
263
-
264
- # Method to maximize browser
265
- def maximize_browser
266
- page.driver.browser.manage.window.maximize
267
- end
268
-
269
- # Method to switch to window by title
270
- def switch_to_window_by_title window_title
271
- $previous_window = page.driver.browser.window_handle
272
- window_found = false
273
- page.driver.browser.window_handles.each{ |handle|
274
- page.driver.browser.switch_to.window handle
275
- if page.title == window_title
276
- window_found = true
277
- break
278
- end
279
- }
280
- raise "Window having title \"#{window_title}\" not found" if not window_found
281
- end
282
-
283
- # Method to resize browser
284
- def resize_browser(width, heigth)
285
- page.driver.browser.manage.window.resize_to(width, heigth)
286
- end
287
-
288
- def take_screenshot
289
- cur_time = Time.now.strftime('%Y%m%d%H%M%S%L')
290
- page.driver.browser.save_screenshot($test_data_dir + '/screenshots/screenshot' + cur_time + '.png')
291
- end
292
-
293
- def get_element_attribute(access_type, access_name, attribute_name)
294
- $driver.find_element(:"#{access_type}" => "#{access_name}").attribute("#{attribute_name}")
295
- end
296
-
data/project/Gemfile.lock DELETED
@@ -1,203 +0,0 @@
1
- GEM
2
- remote: http://rubygems.org/
3
- specs:
4
- Ifd_Automation (0.1.8)
5
- appium_lib (>= 4.0.0, > 4.1.0)
6
- chunky_png (>= 1.3.0, > 1.3.3)
7
- cucumber (>= 1.3.18, > 2.0.0)
8
- selenium-webdriver (>= 2.46.2, > 2.46.2)
9
- actionmailer (5.0.0.1)
10
- actionpack (= 5.0.0.1)
11
- actionview (= 5.0.0.1)
12
- activejob (= 5.0.0.1)
13
- mail (~> 2.5, >= 2.5.4)
14
- rails-dom-testing (~> 2.0)
15
- actionpack (5.0.0.1)
16
- actionview (= 5.0.0.1)
17
- activesupport (= 5.0.0.1)
18
- rack (~> 2.0)
19
- rack-test (~> 0.6.3)
20
- rails-dom-testing (~> 2.0)
21
- rails-html-sanitizer (~> 1.0, >= 1.0.2)
22
- actionview (5.0.0.1)
23
- activesupport (= 5.0.0.1)
24
- builder (~> 3.1)
25
- erubis (~> 2.7.0)
26
- rails-dom-testing (~> 2.0)
27
- rails-html-sanitizer (~> 1.0, >= 1.0.2)
28
- activejob (5.0.0.1)
29
- activesupport (= 5.0.0.1)
30
- globalid (>= 0.3.6)
31
- activemodel (5.0.0.1)
32
- activesupport (= 5.0.0.1)
33
- activerecord (5.0.0.1)
34
- activemodel (= 5.0.0.1)
35
- activesupport (= 5.0.0.1)
36
- arel (~> 7.0)
37
- activesupport (5.0.0.1)
38
- concurrent-ruby (~> 1.0, >= 1.0.2)
39
- i18n (~> 0.7)
40
- minitest (~> 5.1)
41
- tzinfo (~> 1.1)
42
- addressable (2.4.0)
43
- akami (1.3.1)
44
- gyoku (>= 0.4.0)
45
- nokogiri
46
- appium_lib (8.0.2)
47
- awesome_print (~> 1.6)
48
- json (~> 1.8)
49
- nokogiri (~> 1.6.6)
50
- selenium-webdriver (~> 2.49)
51
- tomlrb (~> 1.1)
52
- arel (7.1.4)
53
- awesome_print (1.7.0)
54
- builder (3.2.2)
55
- capybara (2.10.1)
56
- addressable
57
- mime-types (>= 1.16)
58
- nokogiri (>= 1.3.3)
59
- rack (>= 1.0.0)
60
- rack-test (>= 0.5.4)
61
- xpath (~> 2.0)
62
- childprocess (0.5.9)
63
- ffi (~> 1.0, >= 1.0.11)
64
- chunky_png (1.3.7)
65
- concurrent-ruby (1.0.2)
66
- cucumber (2.4.0)
67
- builder (>= 2.1.2)
68
- cucumber-core (~> 1.5.0)
69
- cucumber-wire (~> 0.0.1)
70
- diff-lcs (>= 1.1.3)
71
- gherkin (~> 4.0)
72
- multi_json (>= 1.7.5, < 2.0)
73
- multi_test (>= 0.1.2)
74
- cucumber-core (1.5.0)
75
- gherkin (~> 4.0)
76
- cucumber-wire (0.0.1)
77
- diff-lcs (1.2.5)
78
- domain_name (0.5.20160826)
79
- unf (>= 0.0.5, < 1.0.0)
80
- erubis (2.7.0)
81
- ffi (1.9.14)
82
- ffi (1.9.14-x64-mingw32)
83
- ffi (1.9.14-x86-mingw32)
84
- gherkin (4.0.0)
85
- globalid (0.3.7)
86
- activesupport (>= 4.1.0)
87
- gyoku (1.3.1)
88
- builder (>= 2.1.2)
89
- http-cookie (1.0.3)
90
- domain_name (~> 0.5)
91
- httpi (2.4.2)
92
- rack
93
- socksify
94
- i18n (0.7.0)
95
- json (1.8.3)
96
- json-schema (2.7.0)
97
- addressable (>= 2.4)
98
- jsonpath (0.5.8)
99
- multi_json
100
- loofah (2.0.3)
101
- nokogiri (>= 1.5.9)
102
- mail (2.6.4)
103
- mime-types (>= 1.16, < 4)
104
- mime-types (3.1)
105
- mime-types-data (~> 3.2015)
106
- mime-types-data (3.2016.0521)
107
- mini_portile2 (2.1.0)
108
- minitest (5.9.1)
109
- multi_json (1.12.1)
110
- multi_test (0.1.2)
111
- mysql2 (0.4.4)
112
- mysql2 (0.4.4-x64-mingw32)
113
- mysql2 (0.4.4-x86-mingw32)
114
- net-ssh (3.2.0)
115
- netrc (0.11.0)
116
- nokogiri (1.6.8.1)
117
- mini_portile2 (~> 2.1.0)
118
- nokogiri (1.6.8.1-x64-mingw32)
119
- mini_portile2 (~> 2.1.0)
120
- nokogiri (1.6.8.1-x86-mingw32)
121
- mini_portile2 (~> 2.1.0)
122
- nori (2.6.0)
123
- rack (2.0.1)
124
- rack-test (0.6.3)
125
- rack (>= 1.0)
126
- rails-dom-testing (2.0.1)
127
- activesupport (>= 4.2.0, < 6.0)
128
- nokogiri (~> 1.6.0)
129
- rails-html-sanitizer (1.0.3)
130
- loofah (~> 2.0)
131
- rest-client (2.0.0)
132
- http-cookie (>= 1.0.2, < 2.0)
133
- mime-types (>= 1.16, < 4.0)
134
- netrc (~> 0.8)
135
- rest-client (2.0.0-x64-mingw32)
136
- ffi (~> 1.9)
137
- http-cookie (>= 1.0.2, < 2.0)
138
- mime-types (>= 1.16, < 4.0)
139
- netrc (~> 0.8)
140
- rest-client (2.0.0-x86-mingw32)
141
- ffi (~> 1.9)
142
- http-cookie (>= 1.0.2, < 2.0)
143
- mime-types (>= 1.16, < 4.0)
144
- netrc (~> 0.8)
145
- rubyzip (1.2.0)
146
- savon (2.11.1)
147
- akami (~> 1.2)
148
- builder (>= 2.1.2)
149
- gyoku (~> 1.2)
150
- httpi (~> 2.3)
151
- nokogiri (>= 1.4.0)
152
- nori (~> 2.4)
153
- wasabi (~> 3.4)
154
- selenium-webdriver (2.53.4)
155
- childprocess (~> 0.5)
156
- rubyzip (~> 1.0)
157
- websocket (~> 1.0)
158
- socksify (1.7.0)
159
- thread_safe (0.3.5)
160
- tiny_tds (1.0.5)
161
- mini_portile2 (~> 2.0)
162
- tiny_tds (1.0.5-x64-mingw32)
163
- mini_portile2 (~> 2.0)
164
- tiny_tds (1.0.5-x86-mingw32)
165
- mini_portile2 (~> 2.0)
166
- tomlrb (1.2.3)
167
- tzinfo (1.2.2)
168
- thread_safe (~> 0.1)
169
- unf (0.1.4)
170
- unf_ext
171
- unf_ext (0.0.7.2)
172
- unf_ext (0.0.7.2-x64-mingw32)
173
- unf_ext (0.0.7.2-x86-mingw32)
174
- wasabi (3.5.0)
175
- httpi (~> 2.0)
176
- nokogiri (>= 1.4.2)
177
- websocket (1.2.3)
178
- xpath (2.0.0)
179
- nokogiri (~> 1.3)
180
-
181
- PLATFORMS
182
- ruby
183
- x64-mingw32
184
- x86-mingw32
185
-
186
- DEPENDENCIES
187
- Ifd_Automation
188
- actionmailer
189
- activerecord
190
- capybara
191
- cucumber
192
- json-schema (~> 2.7)
193
- jsonpath (~> 0.5.8)
194
- mail
195
- mysql2 (~> 0.4.4)
196
- net-ssh (~> 3.2)
197
- rest-client (~> 2.0)
198
- savon (~> 2.11.0)
199
- selenium-webdriver (~> 2.46)
200
- tiny_tds (~> 1.0, >= 1.0.5)
201
-
202
- BUNDLED WITH
203
- 1.13.5