Ifd_Automation 1.9.2 → 2.0

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