testcentricity_web 0.2.2

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,241 @@
1
+ require 'time'
2
+ require 'chronic'
3
+ require 'faker'
4
+ require 'spreadsheet'
5
+
6
+
7
+ module TestCentricity
8
+
9
+ XL_PRIMARY_DATA_PATH ||= 'features/test_data/'
10
+ XL_PRIMARY_DATA_FILE ||= "#{XL_PRIMARY_DATA_PATH}data.xls"
11
+
12
+
13
+ class Excel_Data
14
+ @mru = {}
15
+
16
+ def self.get_environment_data_file
17
+ environment = ENV['TEST_ENVIRONMENT']
18
+ "#{XL_PRIMARY_DATA_PATH}#{environment}_data.xls"
19
+ end
20
+
21
+ def self.worksheet_exists?(file, sheet)
22
+ exists = false
23
+ work_book = Spreadsheet.open file
24
+ worksheets = work_book.worksheets
25
+ worksheets.each do |worksheet|
26
+ if worksheet.name == sheet
27
+ exists = true
28
+ break
29
+ end
30
+ end
31
+ exists
32
+ end
33
+
34
+ def self.rowspec_exists?(file, sheet, rowspec)
35
+ exists = false
36
+ if worksheet_exists?(file, sheet)
37
+ work_book = Spreadsheet.open file
38
+ work_sheet = work_book.worksheet sheet
39
+ # get column headings from row 0 of worksheet
40
+ headings = work_sheet.row(0)
41
+ # if rowspec is a string then we have to find a matching row name
42
+ if rowspec.is_a? String
43
+ column_number = 0
44
+ exists = false
45
+ headings.each do |heading|
46
+ if heading == 'ROW_NAME'
47
+ exists = true
48
+ break
49
+ end
50
+ column_number += 1
51
+ end
52
+ raise "Could not find a column named ROW_NAME in worksheet #{sheet}" unless exists
53
+ # find first cell in ROW_NAME column containing a string that matches the rowspec parameter
54
+ exists = false
55
+ row_number = 0
56
+ work_sheet.each do |row|
57
+ if row[column_number] == rowspec
58
+ exists = true
59
+ break
60
+ end
61
+ row_number += 1
62
+ end
63
+ end
64
+ end
65
+ exists
66
+ end
67
+
68
+ def self.read_row_from_pool(file, sheet, rowspec, columns = nil)
69
+ work_book = Spreadsheet.open file
70
+ work_sheet = work_book.worksheet sheet
71
+
72
+ pool_spec_key = "#{sheet}:#{rowspec}"
73
+ if @mru.key?(pool_spec_key)
74
+ pool_spec = @mru[pool_spec_key]
75
+ row_start = pool_spec[:start_row]
76
+ row_end = pool_spec[:num_rows]
77
+ pool_rows = (row_start..row_start + row_end - 1).to_a
78
+ mru_rows = pool_spec[:used_rows]
79
+ new_row = pool_rows.sample.to_i
80
+ if mru_rows.size == pool_spec[:num_rows]
81
+ mru_rows = [new_row]
82
+ else
83
+ while mru_rows.include?(new_row)
84
+ new_row = pool_rows.sample.to_i
85
+ end
86
+ mru_rows.push(new_row)
87
+ mru_rows.sort!
88
+ end
89
+
90
+ pool_spec = {
91
+ :start_row => row_start,
92
+ :num_rows => row_end,
93
+ :used_rows => mru_rows
94
+ }
95
+ else
96
+ # get column headings from row 0 of worksheet
97
+ headings = work_sheet.row(0)
98
+ column_number = 0
99
+ found = false
100
+ headings.each do |heading|
101
+ if heading == 'ROW_NAME'
102
+ found = true
103
+ break
104
+ end
105
+ column_number += 1
106
+ end
107
+ raise "Could not find a column named ROW_NAME in worksheet #{sheet}" unless found
108
+ # find cell(s) in ROW_NAME column containing a string that matches the rowspec parameter
109
+ found = []
110
+ row_number = 0
111
+ work_sheet.each do |row|
112
+ if row[column_number] == rowspec
113
+ found.push(row_number)
114
+ elsif !found.empty?
115
+ break
116
+ end
117
+ row_number += 1
118
+ end
119
+ raise "Could not find a row named '#{rowspec}' in worksheet #{sheet}" if found.empty?
120
+
121
+ new_row = found.sample.to_i
122
+ pool_spec = {
123
+ :start_row => found[0],
124
+ :num_rows => found.size,
125
+ :used_rows => [new_row]
126
+ }
127
+ end
128
+ @mru[pool_spec_key] = pool_spec
129
+
130
+ read_row_data(file, sheet, new_row, columns)
131
+ end
132
+
133
+ def self.read_row_data(file, sheet, rowspec, columns = nil)
134
+ work_book = Spreadsheet.open file
135
+ work_sheet = work_book.worksheet sheet
136
+ # get column headings from row 0 of worksheet
137
+ headings = work_sheet.row(0)
138
+ # if rowspec is a string then we have to find a matching row name
139
+ if rowspec.is_a? String
140
+ column_number = 0
141
+ found = false
142
+ headings.each do |heading|
143
+ if heading == 'ROW_NAME'
144
+ found = true
145
+ break
146
+ end
147
+ column_number += 1
148
+ end
149
+ raise "Could not find a column named ROW_NAME in worksheet #{sheet}" unless found
150
+ # find first cell in ROW_NAME column containing a string that matches the rowspec parameter
151
+ found = false
152
+ row_number = 0
153
+ work_sheet.each do |row|
154
+ if row[column_number] == rowspec
155
+ found = true
156
+ break
157
+ end
158
+ row_number += 1
159
+ end
160
+ raise "Could not find a row named '#{rowspec}' in worksheet #{sheet}" unless found
161
+ data = work_sheet.row(row_number)
162
+ # if rowspec is a number then ensure that it doesn't exceed the number of available rows
163
+ elsif rowspec.is_a? Numeric
164
+ raise "Row # #{rowspec} is greater than number of rows in worksheet #{sheet}" if rowspec > work_sheet.last_row_index
165
+ data = work_sheet.row(rowspec)
166
+ end
167
+
168
+ # if no columns have been specified, return all columns
169
+ columns = headings if columns == nil
170
+ # create results hash table
171
+ result = Hash.new
172
+ columns.each do |column|
173
+ column_number = 0
174
+ found = false
175
+ headings.each do |heading|
176
+ if column == heading
177
+ value = data[column_number].to_s
178
+ value = calculate_dynamic_value(value) if value.start_with? 'eval!'
179
+ result[column] = value
180
+ found = true
181
+ break
182
+ end
183
+ column_number += 1
184
+ end
185
+ raise "Could not find a column named '#{column}' in worksheet #{sheet}" unless found
186
+ end
187
+ result
188
+ end
189
+
190
+ def self.read_range_data(file, sheet, rangespec)
191
+ work_book = Spreadsheet.open file
192
+ work_sheet = work_book.worksheet sheet
193
+ # get column headings from row 0 of worksheet
194
+ headings = work_sheet.row(0)
195
+ column_number = 0
196
+ found = false
197
+ headings.each do |heading|
198
+ if heading == 'ROW_NAME'
199
+ found = true
200
+ break
201
+ end
202
+ column_number += 1
203
+ end
204
+ raise "Could not find a column named ROW_NAME in worksheet #{sheet}" unless found
205
+ # find cell(s) in ROW_NAME column containing a string that matches the rangespec parameter
206
+ found = []
207
+ row_number = 0
208
+ work_sheet.each do |row|
209
+ if row[column_number] == rangespec
210
+ found.push(row_number)
211
+ elsif !found.empty?
212
+ break
213
+ end
214
+ row_number += 1
215
+ end
216
+ raise "Could not find a row named '#{rangespec}' in worksheet #{sheet}" if found.empty?
217
+
218
+ result = []
219
+ found.each do |row|
220
+ result.push(read_row_data(file, sheet, row))
221
+ end
222
+ result
223
+ end
224
+
225
+ private
226
+
227
+ def self.calculate_dynamic_value(value)
228
+ test_value = value.split('!', 2)
229
+ parameter = test_value[1].split('.', 2)
230
+ case parameter[0]
231
+ when 'Address', 'Business', 'Code', 'Company', 'PhoneNumber', 'Number', 'Name', 'Internet', 'Lorem', 'Commerce', 'Hacker'
232
+ result = eval("Faker::#{parameter[0]}.#{parameter[1]}")
233
+ when 'Date'
234
+ result = eval("Chronic.parse('#{parameter[1]}')")
235
+ else
236
+ result = eval(test_value[1])
237
+ end
238
+ result.to_s
239
+ end
240
+ end
241
+ end
@@ -0,0 +1,29 @@
1
+ module TestCentricity
2
+ class ExceptionQueue
3
+ @error_queue
4
+
5
+ def self.enqueue_assert_equal(expected, actual, error_message)
6
+ unless expected == actual
7
+ @error_queue = "#{@error_queue}#{error_message} to be\n #{expected}\nbut found\n #{actual}\n\n"
8
+ screen_shot_and_save_page(nil)
9
+ end
10
+ end
11
+
12
+ def self.enqueue_assert_not_equal(expected, actual, error_message)
13
+ unless expected != actual
14
+ @error_queue = "#{@error_queue}#{error_message} to not be equal to #{expected}\n\n"
15
+ screen_shot_and_save_page(nil)
16
+ end
17
+ end
18
+
19
+ def self.enqueue_exception(error_message)
20
+ @error_queue = "#{@error_queue}#{error_message}\n\n"
21
+ end
22
+
23
+ def self.post_exceptions
24
+ raise @error_queue unless @error_queue.nil?
25
+ ensure
26
+ @error_queue = nil
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,147 @@
1
+ module TestCentricity
2
+ class PageObject
3
+ include Capybara::DSL
4
+ include Capybara::Node::Matchers
5
+ include RSpec::Matchers
6
+ include Test::Unit::Assertions
7
+
8
+ def self.trait(trait_name, &block)
9
+ define_method(trait_name.to_s, &block)
10
+ end
11
+
12
+ def self.element(element_name, locator)
13
+ class_eval(%Q(def #{element_name.to_s};@#{element_name.to_s} ||= TestCentricity::UIElement.new(self, "#{locator}", :page, nil);end))
14
+ end
15
+
16
+ def self.button(element_name, locator)
17
+ class_eval(%Q(def #{element_name.to_s};@#{element_name.to_s} ||= TestCentricity::UIElement.new(self, "#{locator}", :page, :button);end))
18
+ end
19
+
20
+ def self.textfield(element_name, locator)
21
+ class_eval(%Q(def #{element_name.to_s};@#{element_name.to_s} ||= TestCentricity::UIElement.new(self, "#{locator}", :page, :textfield);end))
22
+ end
23
+
24
+ def self.checkbox(element_name, locator)
25
+ class_eval(%Q(def #{element_name.to_s};@#{element_name.to_s} ||= TestCentricity::UIElement.new(self, "#{locator}", :page, :checkbox);end))
26
+ end
27
+
28
+ def self.label(element_name, locator)
29
+ class_eval(%Q(def #{element_name.to_s};@#{element_name.to_s} ||= TestCentricity::UIElement.new(self, "#{locator}", :page, :label);end))
30
+ end
31
+
32
+ def self.link(element_name, locator)
33
+ class_eval(%Q(def #{element_name.to_s};@#{element_name.to_s} ||= TestCentricity::UIElement.new(self, "#{locator}", :page, :link);end))
34
+ end
35
+
36
+ def self.table(element_name, locator)
37
+ class_eval(%Q(def #{element_name.to_s};@#{element_name.to_s} ||= TestCentricity::UIElement.new(self, "#{locator}", :page, :table);end))
38
+ end
39
+
40
+ def self.section(section_name, class_name, locator = nil)
41
+ class_eval(%Q(def #{section_name.to_s};@#{section_name.to_s} ||= #{class_name.to_s}.new(self, "#{locator}", :page);end))
42
+ end
43
+
44
+ def open_portal
45
+ environment = Environ.current
46
+ (environment.hostname.length > 0) ?
47
+ url = "#{environment.hostname}/#{environment.base_url}#{environment.append}" :
48
+ url = "#{environment.base_url}#{environment.append}"
49
+ if environment.user_id.length > 0 && environment.password.length > 0
50
+ visit "#{environment.protocol}://#{environment.user_id}:#{environment.password}@#{url}"
51
+ else
52
+ visit "#{environment.protocol}://#{url}"
53
+ end
54
+ Environ.set_portal_state(:open)
55
+ end
56
+
57
+ def verify_page_exists
58
+ unless page.has_selector?(page_locator)
59
+ body_class = find(:xpath, '//body')[:class]
60
+ error_message = "Expected page to have selector '#{page_locator}' but found '#{body_class}' instead.\nURL of page loaded = #{URI.parse(current_url)}"
61
+ raise error_message
62
+ end
63
+ end
64
+
65
+ def navigate_to; end
66
+
67
+ def verify_page_ui; end
68
+
69
+ def load_page
70
+ return if exists?
71
+ if defined?(page_url) && !page_url.nil?
72
+ visit page_url
73
+ begin
74
+ page.driver.browser.switch_to.alert.accept
75
+ rescue => e
76
+ end unless Environ.browser == :safari || Environ.browser == :ie || Environ.is_device?
77
+ else
78
+ navigate_to
79
+ end
80
+ verify_page_exists
81
+ PageManager.set_current_page(self)
82
+ end
83
+
84
+ def take_screen_shot(page_name, context)
85
+ save_page_screen_shot(page_name, context)
86
+ end
87
+
88
+ def verify_page_contains(content)
89
+ raise "Expected page to have content '#{content}'" unless page.has_content?(:visible, content)
90
+ end
91
+
92
+ def exists?
93
+ saved_wait_time = Capybara.default_max_wait_time
94
+ Capybara.default_max_wait_time = 0.1
95
+ tries ||= 2
96
+ attributes = [:id, :css, :xpath]
97
+ type = attributes[tries]
98
+ obj = page.find(type, page_locator)
99
+ obj != nil
100
+ rescue
101
+ Capybara.default_max_wait_time = saved_wait_time
102
+ retry if (tries -= 1) > 0
103
+ false
104
+ ensure
105
+ Capybara.default_max_wait_time = saved_wait_time
106
+ end
107
+
108
+ def secure?
109
+ !current_url.match(/^https/).nil?
110
+ end
111
+
112
+ def verify_ui_states(ui_states)
113
+ ui_states.each do | ui_object, object_states |
114
+ object_states.each do | property, state |
115
+ case property
116
+ when :exists
117
+ actual = ui_object.exists?
118
+ when :enabled
119
+ actual = ui_object.enabled?
120
+ when :visible
121
+ actual = ui_object.visible?
122
+ when :readonly
123
+ actual = ui_object.read_only?
124
+ when :checked
125
+ actual = ui_object.checked?
126
+ when :value
127
+ actual = ui_object.get_value
128
+ when :maxlength
129
+ actual = ui_object.get_max_length
130
+ when :options
131
+ actual = ui_object.get_options
132
+ when :siebel_options
133
+ actual = ui_object.get_siebel_options
134
+ else
135
+ if property.to_s.start_with? ('cell_')
136
+ cell = property.to_s.gsub('cell_', '')
137
+ cell = cell.split('_')
138
+ actual = ui_object.get_table_cell(cell[0].to_i, cell[1].to_i)
139
+ end
140
+ end
141
+ ExceptionQueue.enqueue_assert_equal(state, actual, "Expected #{ui_object.get_locator} #{property.to_s} property")
142
+ end
143
+ end
144
+ ExceptionQueue.post_exceptions
145
+ end
146
+ end
147
+ end
@@ -0,0 +1,161 @@
1
+ module TestCentricity
2
+ class PageSection
3
+ include Capybara::DSL
4
+ include Capybara::Node::Matchers
5
+ include RSpec::Matchers
6
+ include Test::Unit::Assertions
7
+
8
+ attr_reader :locator, :context
9
+ attr_accessor :parent
10
+
11
+ def self.trait(trait_name, &block)
12
+ define_method(trait_name.to_s, &block)
13
+ end
14
+
15
+ def initialize(parent, locator, context)
16
+ @parent = parent
17
+ @locator = locator
18
+ @context = context
19
+ end
20
+
21
+ def self.element(element_name, locator)
22
+ class_eval(%Q(def #{element_name.to_s};@#{element_name.to_s} ||= TestCentricity::UIElement.new(self, "#{locator}", :section, nil);end))
23
+ end
24
+
25
+ def self.button(element_name, locator)
26
+ class_eval(%Q(def #{element_name.to_s};@#{element_name.to_s} ||= TestCentricity::UIElement.new(self, "#{locator}", :section, :button);end))
27
+ end
28
+
29
+ def self.textfield(element_name, locator)
30
+ class_eval(%Q(def #{element_name.to_s};@#{element_name.to_s} ||= TestCentricity::UIElement.new(self, "#{locator}", :section, :textfield);end))
31
+ end
32
+
33
+ def self.checkbox(element_name, locator)
34
+ class_eval(%Q(def #{element_name.to_s};@#{element_name.to_s} ||= TestCentricity::UIElement.new(self, "#{locator}", :section, :checkbox);end))
35
+ end
36
+
37
+ def self.label(element_name, locator)
38
+ class_eval(%Q(def #{element_name.to_s};@#{element_name.to_s} ||= TestCentricity::UIElement.new(self, "#{locator}", :section, :label);end))
39
+ end
40
+
41
+ def self.link(element_name, locator)
42
+ class_eval(%Q(def #{element_name.to_s};@#{element_name.to_s} ||= TestCentricity::UIElement.new(self, "#{locator}", :section, :link);end))
43
+ end
44
+
45
+ def self.table(element_name, locator)
46
+ class_eval(%Q(def #{element_name.to_s};@#{element_name.to_s} ||= TestCentricity::UIElement.new(self, "#{locator}", :section, :table);end))
47
+ end
48
+
49
+ def self.section(section_name, class_name, locator = nil)
50
+ class_eval(%Q(def #{section_name.to_s};@#{section_name.to_s} ||= #{class_name.to_s}.new(self, "#{locator}", :section);end))
51
+ end
52
+
53
+ def get_locator
54
+ (@locator.empty? && defined?(section_locator)) ? locator = section_locator : locator = @locator
55
+ (@context == :section && !@parent.nil? && !@parent.get_locator.nil?) ? "#{@parent.get_locator}#{locator}" : locator
56
+ end
57
+
58
+ def set_parent(parent)
59
+ @parent = parent
60
+ end
61
+
62
+ def exists?
63
+ section, _ = find_section
64
+ section != nil
65
+ end
66
+
67
+ def visible?
68
+ section, type = find_section
69
+ exists = section
70
+ invisible = false
71
+ if type == :css
72
+ Capybara.using_wait_time 0.1 do
73
+ # is section itself hidden with .ui-helper-hidden class?
74
+ self_hidden = page.has_css?("#{@locator}.ui-helper-hidden")
75
+ # is parent of section hidden, thus hiding the section?
76
+ parent_hidden = page.has_css?(".ui-helper-hidden > #{@locator}")
77
+ # is grandparent of section, or any other ancestor, hidden?
78
+ other_ancestor_hidden = page.has_css?(".ui-helper-hidden * #{@locator}")
79
+ # if any of the above conditions are true, then section is invisible
80
+ invisible = self_hidden || parent_hidden || other_ancestor_hidden
81
+ end
82
+ end
83
+ # the section is visible if it exists and it is not invisible
84
+ (exists && !invisible) ? true : false
85
+ end
86
+
87
+ def hidden?
88
+ not visible?
89
+ end
90
+
91
+ def wait_until_exists(seconds)
92
+ timeout = seconds.nil? ? Capybara.default_max_wait_time : seconds
93
+ wait = Selenium::WebDriver::Wait.new(timeout: timeout)
94
+ wait.until { exists? }
95
+ rescue
96
+ raise "Could not find section #{get_locator} after #{timeout} seconds" unless exists?
97
+ end
98
+
99
+ def wait_until_gone(seconds)
100
+ timeout = seconds.nil? ? Capybara.default_max_wait_time : seconds
101
+ wait = Selenium::WebDriver::Wait.new(timeout: timeout)
102
+ wait.until { !exists? }
103
+ rescue
104
+ raise "Section #{get_locator} remained visible after #{timeout} seconds" if exists?
105
+ end
106
+
107
+ def verify_ui_states(ui_states)
108
+ ui_states.each do | ui_object, object_states |
109
+ object_states.each do | property, state |
110
+ case property
111
+ when :exists
112
+ actual = ui_object.exists?
113
+ when :enabled
114
+ actual = ui_object.enabled?
115
+ when :visible
116
+ actual = ui_object.visible?
117
+ when :readonly
118
+ actual = ui_object.read_only?
119
+ when :checked
120
+ actual = ui_object.checked?
121
+ when :value
122
+ actual = ui_object.get_value
123
+ when :maxlength
124
+ actual = ui_object.get_max_length
125
+ when :options
126
+ actual = ui_object.get_options
127
+ when :siebel_options
128
+ actual = ui_object.get_siebel_options
129
+ else
130
+ if property.to_s.start_with? ('cell_')
131
+ cell = property.to_s.gsub('cell_', '')
132
+ cell = cell.split('_')
133
+ actual = ui_object.get_table_cell(cell[0].to_i, cell[1].to_i)
134
+ end
135
+ end
136
+ ExceptionQueue.enqueue_assert_equal(state, actual, "Expected #{ui_object.get_locator} #{property.to_s} property")
137
+ end
138
+ end
139
+ ExceptionQueue.post_exceptions
140
+ end
141
+
142
+ private
143
+
144
+ def find_section
145
+ locator = get_locator
146
+ saved_wait_time = Capybara.default_max_wait_time
147
+ Capybara.default_max_wait_time = 0.1
148
+ tries ||= 4
149
+ attributes = [:text, :name, :id, :css, :xpath]
150
+ type = attributes[tries]
151
+ obj = page.find(type, locator)
152
+ [obj, type]
153
+ rescue
154
+ Capybara.default_max_wait_time = saved_wait_time
155
+ retry if (tries -= 1) > 0
156
+ [nil, nil]
157
+ ensure
158
+ Capybara.default_max_wait_time = saved_wait_time
159
+ end
160
+ end
161
+ end