testcentricity 2.3.13

Sign up to get free protection for your applications and to get access to all the features.
Files changed (64) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +11 -0
  3. data/.rspec +3 -0
  4. data/.ruby-gemset +1 -0
  5. data/.ruby-version +1 -0
  6. data/Gemfile +6 -0
  7. data/Gemfile.lock +93 -0
  8. data/LICENSE.txt +28 -0
  9. data/README.md +1634 -0
  10. data/Rakefile +1 -0
  11. data/bin/console +14 -0
  12. data/bin/setup +8 -0
  13. data/lib/devices/devices.yml +344 -0
  14. data/lib/testcentricity.rb +144 -0
  15. data/lib/testcentricity/app_core/appium_connect_helper.rb +154 -0
  16. data/lib/testcentricity/app_core/appium_server.rb +69 -0
  17. data/lib/testcentricity/app_core/screen_objects_helper.rb +180 -0
  18. data/lib/testcentricity/app_core/screen_sections_helper.rb +332 -0
  19. data/lib/testcentricity/app_elements/app_element_helper.rb +293 -0
  20. data/lib/testcentricity/app_elements/button.rb +8 -0
  21. data/lib/testcentricity/app_elements/checkbox.rb +20 -0
  22. data/lib/testcentricity/app_elements/label.rb +8 -0
  23. data/lib/testcentricity/app_elements/list.rb +25 -0
  24. data/lib/testcentricity/app_elements/switch.rb +20 -0
  25. data/lib/testcentricity/app_elements/textfield.rb +12 -0
  26. data/lib/testcentricity/browser_helper.rb +174 -0
  27. data/lib/testcentricity/data_objects/data_objects_helper.rb +78 -0
  28. data/lib/testcentricity/data_objects/environment.rb +281 -0
  29. data/lib/testcentricity/data_objects/excel_helper.rb +242 -0
  30. data/lib/testcentricity/exception_queue_helper.rb +51 -0
  31. data/lib/testcentricity/utility_helpers.rb +28 -0
  32. data/lib/testcentricity/version.rb +3 -0
  33. data/lib/testcentricity/web_core/drag_drop_helper.rb +15 -0
  34. data/lib/testcentricity/web_core/page_objects_helper.rb +669 -0
  35. data/lib/testcentricity/web_core/page_sections_helper.rb +866 -0
  36. data/lib/testcentricity/web_core/webdriver_helper.rb +579 -0
  37. data/lib/testcentricity/web_elements/button.rb +8 -0
  38. data/lib/testcentricity/web_elements/cell_button.rb +8 -0
  39. data/lib/testcentricity/web_elements/cell_checkbox.rb +38 -0
  40. data/lib/testcentricity/web_elements/cell_element.rb +69 -0
  41. data/lib/testcentricity/web_elements/cell_image.rb +8 -0
  42. data/lib/testcentricity/web_elements/cell_radio.rb +31 -0
  43. data/lib/testcentricity/web_elements/checkbox.rb +100 -0
  44. data/lib/testcentricity/web_elements/file_field.rb +45 -0
  45. data/lib/testcentricity/web_elements/image.rb +34 -0
  46. data/lib/testcentricity/web_elements/label.rb +8 -0
  47. data/lib/testcentricity/web_elements/link.rb +8 -0
  48. data/lib/testcentricity/web_elements/list.rb +73 -0
  49. data/lib/testcentricity/web_elements/list_button.rb +8 -0
  50. data/lib/testcentricity/web_elements/list_checkbox.rb +38 -0
  51. data/lib/testcentricity/web_elements/list_element.rb +61 -0
  52. data/lib/testcentricity/web_elements/list_radio.rb +31 -0
  53. data/lib/testcentricity/web_elements/radio.rb +74 -0
  54. data/lib/testcentricity/web_elements/select_list.rb +197 -0
  55. data/lib/testcentricity/web_elements/siebel_open_ui_helper.rb +15 -0
  56. data/lib/testcentricity/web_elements/table.rb +612 -0
  57. data/lib/testcentricity/web_elements/textfield.rb +114 -0
  58. data/lib/testcentricity/web_elements/ui_elements_helper.rb +502 -0
  59. data/lib/testcentricity/world_extensions.rb +26 -0
  60. data/my_templates/default/method_details/setup.rb +3 -0
  61. data/spec/spec_helper.rb +14 -0
  62. data/spec/testcentricity_spec.rb +9 -0
  63. data/testcentricity.gemspec +47 -0
  64. 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