testcentricity 2.3.13
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/.gitignore +11 -0
- data/.rspec +3 -0
- data/.ruby-gemset +1 -0
- data/.ruby-version +1 -0
- data/Gemfile +6 -0
- data/Gemfile.lock +93 -0
- data/LICENSE.txt +28 -0
- data/README.md +1634 -0
- data/Rakefile +1 -0
- data/bin/console +14 -0
- data/bin/setup +8 -0
- data/lib/devices/devices.yml +344 -0
- data/lib/testcentricity.rb +144 -0
- data/lib/testcentricity/app_core/appium_connect_helper.rb +154 -0
- data/lib/testcentricity/app_core/appium_server.rb +69 -0
- data/lib/testcentricity/app_core/screen_objects_helper.rb +180 -0
- data/lib/testcentricity/app_core/screen_sections_helper.rb +332 -0
- data/lib/testcentricity/app_elements/app_element_helper.rb +293 -0
- data/lib/testcentricity/app_elements/button.rb +8 -0
- data/lib/testcentricity/app_elements/checkbox.rb +20 -0
- data/lib/testcentricity/app_elements/label.rb +8 -0
- data/lib/testcentricity/app_elements/list.rb +25 -0
- data/lib/testcentricity/app_elements/switch.rb +20 -0
- data/lib/testcentricity/app_elements/textfield.rb +12 -0
- data/lib/testcentricity/browser_helper.rb +174 -0
- data/lib/testcentricity/data_objects/data_objects_helper.rb +78 -0
- data/lib/testcentricity/data_objects/environment.rb +281 -0
- data/lib/testcentricity/data_objects/excel_helper.rb +242 -0
- data/lib/testcentricity/exception_queue_helper.rb +51 -0
- data/lib/testcentricity/utility_helpers.rb +28 -0
- data/lib/testcentricity/version.rb +3 -0
- data/lib/testcentricity/web_core/drag_drop_helper.rb +15 -0
- data/lib/testcentricity/web_core/page_objects_helper.rb +669 -0
- data/lib/testcentricity/web_core/page_sections_helper.rb +866 -0
- data/lib/testcentricity/web_core/webdriver_helper.rb +579 -0
- data/lib/testcentricity/web_elements/button.rb +8 -0
- data/lib/testcentricity/web_elements/cell_button.rb +8 -0
- data/lib/testcentricity/web_elements/cell_checkbox.rb +38 -0
- data/lib/testcentricity/web_elements/cell_element.rb +69 -0
- data/lib/testcentricity/web_elements/cell_image.rb +8 -0
- data/lib/testcentricity/web_elements/cell_radio.rb +31 -0
- data/lib/testcentricity/web_elements/checkbox.rb +100 -0
- data/lib/testcentricity/web_elements/file_field.rb +45 -0
- data/lib/testcentricity/web_elements/image.rb +34 -0
- data/lib/testcentricity/web_elements/label.rb +8 -0
- data/lib/testcentricity/web_elements/link.rb +8 -0
- data/lib/testcentricity/web_elements/list.rb +73 -0
- data/lib/testcentricity/web_elements/list_button.rb +8 -0
- data/lib/testcentricity/web_elements/list_checkbox.rb +38 -0
- data/lib/testcentricity/web_elements/list_element.rb +61 -0
- data/lib/testcentricity/web_elements/list_radio.rb +31 -0
- data/lib/testcentricity/web_elements/radio.rb +74 -0
- data/lib/testcentricity/web_elements/select_list.rb +197 -0
- data/lib/testcentricity/web_elements/siebel_open_ui_helper.rb +15 -0
- data/lib/testcentricity/web_elements/table.rb +612 -0
- data/lib/testcentricity/web_elements/textfield.rb +114 -0
- data/lib/testcentricity/web_elements/ui_elements_helper.rb +502 -0
- data/lib/testcentricity/world_extensions.rb +26 -0
- data/my_templates/default/method_details/setup.rb +3 -0
- data/spec/spec_helper.rb +14 -0
- data/spec/testcentricity_spec.rb +9 -0
- data/testcentricity.gemspec +47 -0
- metadata +328 -0
@@ -0,0 +1,78 @@
|
|
1
|
+
require 'yaml'
|
2
|
+
require 'json'
|
3
|
+
|
4
|
+
|
5
|
+
module TestCentricity
|
6
|
+
|
7
|
+
XL_PRIMARY_DATA_PATH ||= 'features/test_data/'
|
8
|
+
XL_PRIMARY_DATA_FILE ||= "#{XL_PRIMARY_DATA_PATH}data.xls"
|
9
|
+
|
10
|
+
|
11
|
+
class DataObject
|
12
|
+
attr_accessor :current
|
13
|
+
attr_accessor :context
|
14
|
+
attr_accessor :hash_table
|
15
|
+
|
16
|
+
def initialize(data)
|
17
|
+
@hash_table = data
|
18
|
+
end
|
19
|
+
|
20
|
+
# @deprecated Please use {#current=} instead
|
21
|
+
def self.set_current(current)
|
22
|
+
warn "[DEPRECATION] 'TestCentricity::DataObject.set_current' is deprecated. Please use 'current=' instead."
|
23
|
+
@current = current
|
24
|
+
end
|
25
|
+
|
26
|
+
def self.current
|
27
|
+
@current
|
28
|
+
end
|
29
|
+
|
30
|
+
def self.current=(current)
|
31
|
+
@current = current
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
|
36
|
+
class DataSource
|
37
|
+
attr_accessor :current
|
38
|
+
|
39
|
+
def read_yaml_node_data(file_name, node_name)
|
40
|
+
data = YAML.load_file("#{XL_PRIMARY_DATA_PATH}#{file_name}")
|
41
|
+
data[node_name]
|
42
|
+
end
|
43
|
+
|
44
|
+
def read_json_node_data(file_name, node_name)
|
45
|
+
raw_data = File.read("#{XL_PRIMARY_DATA_PATH}#{file_name}")
|
46
|
+
data = JSON.parse(raw_data)
|
47
|
+
data[node_name]
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
|
52
|
+
class ExcelDataSource < TestCentricity::DataSource
|
53
|
+
def pick_excel_data_source(sheet, row_spec)
|
54
|
+
if ENV['TEST_ENVIRONMENT']
|
55
|
+
environment = ENV['TEST_ENVIRONMENT']
|
56
|
+
data_file = "#{XL_PRIMARY_DATA_PATH}#{environment}_data.xls"
|
57
|
+
data_file = XL_PRIMARY_DATA_FILE unless ExcelData.rowspec_exists?(data_file, sheet, row_spec)
|
58
|
+
else
|
59
|
+
data_file = XL_PRIMARY_DATA_FILE
|
60
|
+
end
|
61
|
+
data_file
|
62
|
+
end
|
63
|
+
|
64
|
+
def read_excel_row_data(sheet, row_name, parallel = false)
|
65
|
+
parallel == :parallel && ENV['PARALLEL'] ? row_spec = "#{row_name}#{ENV['TEST_ENV_NUMBER']}" : row_spec = row_name
|
66
|
+
ExcelData.read_row_data(pick_excel_data_source(sheet, row_spec), sheet, row_spec)
|
67
|
+
end
|
68
|
+
|
69
|
+
def read_excel_pool_data(sheet, row_name, parallel = false)
|
70
|
+
parallel == :parallel && ENV['PARALLEL'] ? row_spec = "#{row_name}#{ENV['TEST_ENV_NUMBER']}" : row_spec = row_name
|
71
|
+
ExcelData.read_row_from_pool(pick_excel_data_source(sheet, row_name), sheet, row_spec)
|
72
|
+
end
|
73
|
+
|
74
|
+
def read_excel_range_data(sheet, range_name)
|
75
|
+
ExcelData.read_range_data(pick_excel_data_source(sheet, range_name), sheet, range_name)
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
@@ -0,0 +1,281 @@
|
|
1
|
+
module TestCentricity
|
2
|
+
class EnvironData < TestCentricity::ExcelDataSource
|
3
|
+
attr_accessor :current
|
4
|
+
|
5
|
+
WKS_ENVIRONS ||= 'Environments'
|
6
|
+
|
7
|
+
def find_environ(environ_name, source_type = :excel)
|
8
|
+
case source_type
|
9
|
+
when :excel
|
10
|
+
data = ExcelData.read_row_data(XL_PRIMARY_DATA_FILE, WKS_ENVIRONS, environ_name)
|
11
|
+
when :yaml
|
12
|
+
data = read_yaml_node_data('environments.yml', environ_name)
|
13
|
+
when :json
|
14
|
+
data = read_json_node_data('environments.json', environ_name)
|
15
|
+
end
|
16
|
+
@current = Environ.new(data)
|
17
|
+
Environ.current = @current
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
|
22
|
+
class Environ < TestCentricity::DataObject
|
23
|
+
@session_id = Time.now.strftime('%d%H%M%S%L')
|
24
|
+
@session_time_stamp = Time.now.strftime('%Y%m%d%H%M%S')
|
25
|
+
@session_code
|
26
|
+
@test_environment = ENV['TEST_ENVIRONMENT']
|
27
|
+
@screen_shots = []
|
28
|
+
|
29
|
+
attr_accessor :test_environment
|
30
|
+
attr_accessor :browser
|
31
|
+
attr_accessor :browser_size
|
32
|
+
attr_accessor :session_state
|
33
|
+
attr_accessor :os
|
34
|
+
attr_accessor :device
|
35
|
+
attr_accessor :device_name
|
36
|
+
attr_accessor :device_type
|
37
|
+
attr_accessor :device_os
|
38
|
+
attr_accessor :device_orientation
|
39
|
+
attr_accessor :platform
|
40
|
+
attr_accessor :driver
|
41
|
+
attr_accessor :tunneling
|
42
|
+
|
43
|
+
attr_accessor :signed_in
|
44
|
+
attr_accessor :portal_status
|
45
|
+
attr_accessor :portal_context
|
46
|
+
attr_accessor :external_page
|
47
|
+
|
48
|
+
attr_accessor :default_max_wait_time
|
49
|
+
|
50
|
+
attr_accessor :protocol
|
51
|
+
attr_accessor :hostname
|
52
|
+
attr_accessor :base_url
|
53
|
+
attr_accessor :user_id
|
54
|
+
attr_accessor :password
|
55
|
+
attr_accessor :append
|
56
|
+
attr_accessor :option1
|
57
|
+
attr_accessor :option2
|
58
|
+
attr_accessor :dns
|
59
|
+
attr_accessor :db_username
|
60
|
+
attr_accessor :db_password
|
61
|
+
attr_accessor :ios_app_path
|
62
|
+
attr_accessor :ios_ipa_path
|
63
|
+
attr_accessor :android_apk_path
|
64
|
+
|
65
|
+
def initialize(data)
|
66
|
+
@protocol = data['PROTOCOL']
|
67
|
+
@hostname = data['HOST_NAME']
|
68
|
+
@base_url = data['BASE_URL']
|
69
|
+
@user_id = data['USER_ID']
|
70
|
+
@password = data['PASSWORD']
|
71
|
+
@append = data['APPEND']
|
72
|
+
@option1 = data['OPTIONAL_1']
|
73
|
+
@option2 = data['OPTIONAL_2']
|
74
|
+
@dns = data['DNS']
|
75
|
+
@db_username = data['DB_USERNAME']
|
76
|
+
@db_password = data['DB_PASSWORD']
|
77
|
+
@ios_app_path = data['IOS_APP_PATH']
|
78
|
+
@ios_ipa_path = data['IOS_IPA_PATH']
|
79
|
+
@android_apk_path = data['ANDROID_APK_PATH']
|
80
|
+
super
|
81
|
+
end
|
82
|
+
|
83
|
+
def self.session_code
|
84
|
+
if @session_code.nil?
|
85
|
+
characters = ('a'..'z').to_a
|
86
|
+
@session_code = (0..12).map { characters.sample }.join
|
87
|
+
end
|
88
|
+
@session_code
|
89
|
+
end
|
90
|
+
|
91
|
+
def self.session_id
|
92
|
+
@session_id
|
93
|
+
end
|
94
|
+
|
95
|
+
def self.session_time_stamp
|
96
|
+
@session_time_stamp
|
97
|
+
end
|
98
|
+
|
99
|
+
def self.test_environment
|
100
|
+
if @test_environment.blank?
|
101
|
+
nil
|
102
|
+
else
|
103
|
+
@test_environment.downcase.to_sym
|
104
|
+
end
|
105
|
+
end
|
106
|
+
|
107
|
+
def self.default_max_wait_time=(timeout)
|
108
|
+
@default_max_wait_time = timeout
|
109
|
+
|
110
|
+
Capybara.default_max_wait_time = timeout if driver == :webdriver
|
111
|
+
end
|
112
|
+
|
113
|
+
def self.default_max_wait_time
|
114
|
+
@default_max_wait_time
|
115
|
+
end
|
116
|
+
|
117
|
+
def self.browser=(browser)
|
118
|
+
@browser = browser.downcase.to_sym
|
119
|
+
end
|
120
|
+
|
121
|
+
def self.browser
|
122
|
+
@browser
|
123
|
+
end
|
124
|
+
|
125
|
+
def self.browser_size=(size)
|
126
|
+
@browser_size = size
|
127
|
+
end
|
128
|
+
|
129
|
+
def self.browser_size
|
130
|
+
@browser_size
|
131
|
+
end
|
132
|
+
|
133
|
+
def self.session_state=(session_state)
|
134
|
+
@session_state = session_state
|
135
|
+
end
|
136
|
+
|
137
|
+
def self.session_state
|
138
|
+
@session_state
|
139
|
+
end
|
140
|
+
|
141
|
+
def self.os=(os)
|
142
|
+
@os = os
|
143
|
+
end
|
144
|
+
|
145
|
+
def self.os
|
146
|
+
@os
|
147
|
+
end
|
148
|
+
|
149
|
+
def self.device=(device)
|
150
|
+
@device = device
|
151
|
+
end
|
152
|
+
|
153
|
+
def self.device
|
154
|
+
@device
|
155
|
+
end
|
156
|
+
|
157
|
+
def self.is_device?
|
158
|
+
@device == :device
|
159
|
+
end
|
160
|
+
|
161
|
+
def self.is_simulator?
|
162
|
+
@device == :simulator
|
163
|
+
end
|
164
|
+
|
165
|
+
def self.is_web?
|
166
|
+
@device == :web
|
167
|
+
end
|
168
|
+
|
169
|
+
def self.device_type=(type)
|
170
|
+
@device_type = type.downcase.to_sym
|
171
|
+
end
|
172
|
+
|
173
|
+
def self.device_type
|
174
|
+
@device_type
|
175
|
+
end
|
176
|
+
|
177
|
+
def self.device_name=(name)
|
178
|
+
@device_name = name
|
179
|
+
end
|
180
|
+
|
181
|
+
def self.device_name
|
182
|
+
@device_name
|
183
|
+
end
|
184
|
+
|
185
|
+
def self.device_os=(os)
|
186
|
+
@device_os = os.downcase.to_sym
|
187
|
+
end
|
188
|
+
|
189
|
+
def self.device_os
|
190
|
+
@device_os
|
191
|
+
end
|
192
|
+
|
193
|
+
def self.is_ios?
|
194
|
+
@device_os == :ios
|
195
|
+
end
|
196
|
+
|
197
|
+
def self.is_android?
|
198
|
+
@device_os == :android
|
199
|
+
end
|
200
|
+
|
201
|
+
def self.device_orientation=(orientation)
|
202
|
+
@device_orientation = orientation.downcase.to_sym
|
203
|
+
end
|
204
|
+
|
205
|
+
def self.device_orientation
|
206
|
+
@device_orientation
|
207
|
+
end
|
208
|
+
|
209
|
+
def self.driver=(type)
|
210
|
+
@driver = type
|
211
|
+
end
|
212
|
+
|
213
|
+
def self.driver
|
214
|
+
@driver
|
215
|
+
end
|
216
|
+
|
217
|
+
def self.tunneling=(state)
|
218
|
+
@tunneling = state
|
219
|
+
end
|
220
|
+
|
221
|
+
def self.tunneling
|
222
|
+
@tunneling
|
223
|
+
end
|
224
|
+
|
225
|
+
def self.platform=(platform)
|
226
|
+
@platform = platform
|
227
|
+
end
|
228
|
+
|
229
|
+
def self.is_mobile?
|
230
|
+
@platform == :mobile
|
231
|
+
end
|
232
|
+
|
233
|
+
def self.is_desktop?
|
234
|
+
@platform == :desktop
|
235
|
+
end
|
236
|
+
|
237
|
+
def self.set_signed_in(signed_in)
|
238
|
+
@signed_in = signed_in
|
239
|
+
end
|
240
|
+
|
241
|
+
def self.is_signed_in?
|
242
|
+
@signed_in
|
243
|
+
end
|
244
|
+
|
245
|
+
def self.portal_state=(portal_state)
|
246
|
+
@portal_status = portal_state
|
247
|
+
end
|
248
|
+
|
249
|
+
def self.portal_state
|
250
|
+
@portal_status
|
251
|
+
end
|
252
|
+
|
253
|
+
def self.portal_context=(portal_context)
|
254
|
+
@portal_context = portal_context
|
255
|
+
end
|
256
|
+
|
257
|
+
def self.portal_context
|
258
|
+
@portal_context
|
259
|
+
end
|
260
|
+
|
261
|
+
def self.set_external_page(state)
|
262
|
+
@external_page = state
|
263
|
+
end
|
264
|
+
|
265
|
+
def self.external_page
|
266
|
+
@external_page
|
267
|
+
end
|
268
|
+
|
269
|
+
def self.save_screen_shot(screen_shot)
|
270
|
+
@screen_shots.push(screen_shot)
|
271
|
+
end
|
272
|
+
|
273
|
+
def self.get_screen_shots
|
274
|
+
@screen_shots
|
275
|
+
end
|
276
|
+
|
277
|
+
def self.reset_contexts
|
278
|
+
@screen_shots = []
|
279
|
+
end
|
280
|
+
end
|
281
|
+
end
|
@@ -0,0 +1,242 @@
|
|
1
|
+
require 'time'
|
2
|
+
require 'chronic'
|
3
|
+
require 'faker'
|
4
|
+
require 'spreadsheet'
|
5
|
+
|
6
|
+
|
7
|
+
module TestCentricity
|
8
|
+
class ExcelData
|
9
|
+
@mru = {}
|
10
|
+
|
11
|
+
def self.worksheet_exists?(file, sheet)
|
12
|
+
exists = false
|
13
|
+
if File.exist?(file)
|
14
|
+
work_book = Spreadsheet.open file
|
15
|
+
worksheets = work_book.worksheets
|
16
|
+
worksheets.each do |worksheet|
|
17
|
+
if worksheet.name == sheet
|
18
|
+
exists = true
|
19
|
+
break
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
exists
|
24
|
+
end
|
25
|
+
|
26
|
+
def self.rowspec_exists?(file, sheet, rowspec)
|
27
|
+
exists = false
|
28
|
+
if worksheet_exists?(file, sheet)
|
29
|
+
work_book = Spreadsheet.open file
|
30
|
+
work_sheet = work_book.worksheet sheet
|
31
|
+
# get column headings from row 0 of worksheet
|
32
|
+
headings = work_sheet.row(0)
|
33
|
+
# if rowspec is a string then we have to find a matching row name
|
34
|
+
if rowspec.is_a? String
|
35
|
+
column_number = 0
|
36
|
+
exists = false
|
37
|
+
headings.each do |heading|
|
38
|
+
if heading == 'ROW_NAME'
|
39
|
+
exists = true
|
40
|
+
break
|
41
|
+
end
|
42
|
+
column_number += 1
|
43
|
+
end
|
44
|
+
raise "Could not find a column named ROW_NAME in worksheet #{sheet}" unless exists
|
45
|
+
# find first cell in ROW_NAME column containing a string that matches the rowspec parameter
|
46
|
+
exists = false
|
47
|
+
row_number = 0
|
48
|
+
work_sheet.each do |row|
|
49
|
+
if row[column_number] == rowspec
|
50
|
+
exists = true
|
51
|
+
break
|
52
|
+
end
|
53
|
+
row_number += 1
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
exists
|
58
|
+
end
|
59
|
+
|
60
|
+
def self.read_row_from_pool(file, sheet, rowspec, columns = nil)
|
61
|
+
raise "File #{file} does not exists" unless File.exist?(file)
|
62
|
+
work_book = Spreadsheet.open file
|
63
|
+
work_sheet = work_book.worksheet sheet
|
64
|
+
|
65
|
+
pool_spec_key = "#{sheet}:#{rowspec}"
|
66
|
+
if @mru.key?(pool_spec_key)
|
67
|
+
pool_spec = @mru[pool_spec_key]
|
68
|
+
row_start = pool_spec[:start_row]
|
69
|
+
row_end = pool_spec[:num_rows]
|
70
|
+
pool_rows = (row_start..row_start + row_end - 1).to_a
|
71
|
+
mru_rows = pool_spec[:used_rows]
|
72
|
+
new_row = pool_rows.sample.to_i
|
73
|
+
if mru_rows.size == pool_spec[:num_rows]
|
74
|
+
mru_rows = [new_row]
|
75
|
+
else
|
76
|
+
while mru_rows.include?(new_row)
|
77
|
+
new_row = pool_rows.sample.to_i
|
78
|
+
end
|
79
|
+
mru_rows.push(new_row)
|
80
|
+
mru_rows.sort!
|
81
|
+
end
|
82
|
+
|
83
|
+
pool_spec = {
|
84
|
+
:start_row => row_start,
|
85
|
+
:num_rows => row_end,
|
86
|
+
:used_rows => mru_rows
|
87
|
+
}
|
88
|
+
else
|
89
|
+
# get column headings from row 0 of worksheet
|
90
|
+
headings = work_sheet.row(0)
|
91
|
+
column_number = 0
|
92
|
+
found = false
|
93
|
+
headings.each do |heading|
|
94
|
+
if heading == 'ROW_NAME'
|
95
|
+
found = true
|
96
|
+
break
|
97
|
+
end
|
98
|
+
column_number += 1
|
99
|
+
end
|
100
|
+
raise "Could not find a column named ROW_NAME in worksheet #{sheet}" unless found
|
101
|
+
# find cell(s) in ROW_NAME column containing a string that matches the rowspec parameter
|
102
|
+
found = []
|
103
|
+
row_number = 0
|
104
|
+
work_sheet.each do |row|
|
105
|
+
if row[column_number] == rowspec
|
106
|
+
found.push(row_number)
|
107
|
+
elsif !found.empty?
|
108
|
+
break
|
109
|
+
end
|
110
|
+
row_number += 1
|
111
|
+
end
|
112
|
+
raise "Could not find a row named '#{rowspec}' in worksheet #{sheet}" if found.empty?
|
113
|
+
|
114
|
+
new_row = found.sample.to_i
|
115
|
+
pool_spec = {
|
116
|
+
:start_row => found[0],
|
117
|
+
:num_rows => found.size,
|
118
|
+
:used_rows => [new_row]
|
119
|
+
}
|
120
|
+
end
|
121
|
+
@mru[pool_spec_key] = pool_spec
|
122
|
+
|
123
|
+
read_row_data(file, sheet, new_row, columns)
|
124
|
+
end
|
125
|
+
|
126
|
+
def self.read_row_data(file, sheet, rowspec, columns = nil)
|
127
|
+
raise "File #{file} does not exists" unless File.exist?(file)
|
128
|
+
work_book = Spreadsheet.open file
|
129
|
+
work_sheet = work_book.worksheet sheet
|
130
|
+
# get column headings from row 0 of worksheet
|
131
|
+
headings = work_sheet.row(0)
|
132
|
+
# if rowspec is a string then we have to find a matching row name
|
133
|
+
if rowspec.is_a? String
|
134
|
+
column_number = 0
|
135
|
+
found = false
|
136
|
+
headings.each do |heading|
|
137
|
+
if heading == 'ROW_NAME'
|
138
|
+
found = true
|
139
|
+
break
|
140
|
+
end
|
141
|
+
column_number += 1
|
142
|
+
end
|
143
|
+
raise "Could not find a column named ROW_NAME in worksheet #{sheet}" unless found
|
144
|
+
# find first cell in ROW_NAME column containing a string that matches the rowspec parameter
|
145
|
+
found = false
|
146
|
+
row_number = 0
|
147
|
+
work_sheet.each do |row|
|
148
|
+
if row[column_number] == rowspec
|
149
|
+
found = true
|
150
|
+
break
|
151
|
+
end
|
152
|
+
row_number += 1
|
153
|
+
end
|
154
|
+
raise "Could not find a row named '#{rowspec}' in worksheet #{sheet}" unless found
|
155
|
+
data = work_sheet.row(row_number)
|
156
|
+
# if rowspec is a number then ensure that it doesn't exceed the number of available rows
|
157
|
+
elsif rowspec.is_a? Numeric
|
158
|
+
raise "Row # #{rowspec} is greater than number of rows in worksheet #{sheet}" if rowspec > work_sheet.last_row_index
|
159
|
+
data = work_sheet.row(rowspec)
|
160
|
+
end
|
161
|
+
|
162
|
+
# if no columns have been specified, return all columns
|
163
|
+
columns = headings if columns.nil?
|
164
|
+
# create results hash table
|
165
|
+
result = Hash.new
|
166
|
+
columns.each do |column|
|
167
|
+
column_number = 0
|
168
|
+
found = false
|
169
|
+
headings.each do |heading|
|
170
|
+
if column == heading
|
171
|
+
value = data[column_number].to_s
|
172
|
+
value = calculate_dynamic_value(value) if value.start_with? 'eval!'
|
173
|
+
result[column] = value
|
174
|
+
found = true
|
175
|
+
break
|
176
|
+
end
|
177
|
+
column_number += 1
|
178
|
+
end
|
179
|
+
raise "Could not find a column named '#{column}' in worksheet #{sheet}" unless found
|
180
|
+
end
|
181
|
+
result
|
182
|
+
end
|
183
|
+
|
184
|
+
def self.read_range_data(file, sheet, rangespec)
|
185
|
+
raise "File #{file} does not exists" unless File.exist?(file)
|
186
|
+
work_book = Spreadsheet.open file
|
187
|
+
work_sheet = work_book.worksheet sheet
|
188
|
+
# get column headings from row 0 of worksheet
|
189
|
+
headings = work_sheet.row(0)
|
190
|
+
column_number = 0
|
191
|
+
found = false
|
192
|
+
headings.each do |heading|
|
193
|
+
if heading == 'ROW_NAME'
|
194
|
+
found = true
|
195
|
+
break
|
196
|
+
end
|
197
|
+
column_number += 1
|
198
|
+
end
|
199
|
+
raise "Could not find a column named ROW_NAME in worksheet #{sheet}" unless found
|
200
|
+
# find cell(s) in ROW_NAME column containing a string that matches the rangespec parameter
|
201
|
+
found = []
|
202
|
+
row_number = 0
|
203
|
+
work_sheet.each do |row|
|
204
|
+
if row[column_number] == rangespec
|
205
|
+
found.push(row_number)
|
206
|
+
elsif !found.empty?
|
207
|
+
break
|
208
|
+
end
|
209
|
+
row_number += 1
|
210
|
+
end
|
211
|
+
raise "Could not find a row named '#{rangespec}' in worksheet #{sheet}" if found.empty?
|
212
|
+
|
213
|
+
result = []
|
214
|
+
found.each do |row|
|
215
|
+
result.push(read_row_data(file, sheet, row))
|
216
|
+
end
|
217
|
+
result
|
218
|
+
end
|
219
|
+
|
220
|
+
private
|
221
|
+
|
222
|
+
def self.calculate_dynamic_value(value)
|
223
|
+
test_value = value.split('!', 2)
|
224
|
+
parameter = test_value[1].split('.', 2)
|
225
|
+
case parameter[0]
|
226
|
+
when 'Date'
|
227
|
+
result = eval("Chronic.parse('#{parameter[1]}')")
|
228
|
+
when 'FormattedDate', 'FormatDate'
|
229
|
+
date_time_params = parameter[1].split(' format! ', 2)
|
230
|
+
date_time = eval("Chronic.parse('#{date_time_params[0].strip}')")
|
231
|
+
result = date_time.to_s.format_date_time("#{date_time_params[1].strip}")
|
232
|
+
else
|
233
|
+
if Faker.constants.include?(parameter[0].to_sym)
|
234
|
+
result = eval("Faker::#{parameter[0]}.#{parameter[1]}")
|
235
|
+
else
|
236
|
+
result = eval(test_value[1])
|
237
|
+
end
|
238
|
+
end
|
239
|
+
result.to_s
|
240
|
+
end
|
241
|
+
end
|
242
|
+
end
|