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,8 @@
1
+ module TestCentricity
2
+ class ListButton < ListElement
3
+ def initialize(name, parent, locator, context, list, proxy = nil)
4
+ super
5
+ @type = :list_button
6
+ end
7
+ end
8
+ end
@@ -0,0 +1,38 @@
1
+ module TestCentricity
2
+ class ListCheckBox < ListElement
3
+ attr_accessor :proxy
4
+
5
+ def initialize(name, parent, locator, context, list, proxy = nil)
6
+ super
7
+ @type = :list_checkbox
8
+ @proxy = proxy
9
+ end
10
+
11
+ def checked?(row)
12
+ obj, = find_list_element(row)
13
+ list_object_not_found_exception(obj, 'List CheckBox', row)
14
+ obj.checked?
15
+ end
16
+
17
+ def set_checkbox_state(row, state)
18
+ obj, = find_list_element(row)
19
+ list_object_not_found_exception(obj, 'List CheckBox', row)
20
+ obj.set(state)
21
+ end
22
+
23
+ def check(row)
24
+ set_checkbox_state(row, true)
25
+ end
26
+
27
+ def uncheck(row)
28
+ set_checkbox_state(row, false)
29
+ end
30
+
31
+ def verify_check_state(row, state, enqueue = false)
32
+ actual = checked?(row)
33
+ enqueue ?
34
+ ExceptionQueue.enqueue_assert_equal(state, actual, "Expected Row #{row} List Checkbox #{object_ref_message}") :
35
+ assert_equal(state, actual, "Expected Row #{row} List Checkbox #{object_ref_message} to be #{state} but found #{actual} instead")
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,61 @@
1
+ module TestCentricity
2
+ class ListElement < UIElement
3
+ attr_accessor :list
4
+ attr_accessor :element_locator
5
+
6
+ def initialize(name, parent, locator, context, list, proxy = nil)
7
+ @name = name
8
+ @parent = parent
9
+ @context = context
10
+ @alt_locator = nil
11
+ @list = list
12
+ @element_locator = locator
13
+
14
+ set_locator_type(@list.get_locator)
15
+
16
+ if locator.nil?
17
+ @locator = list.get_list_row_locator('ROW_SPEC')
18
+ else
19
+ case @locator_type
20
+ when :xpath
21
+ @locator = "#{list.get_list_row_locator('ROW_SPEC')}/#{@element_locator}"
22
+ when :css
23
+ @locator = "#{list.get_list_row_locator('ROW_SPEC')} > #{@element_locator}"
24
+ end
25
+ end
26
+ end
27
+
28
+ def exists?(row)
29
+ obj, = find_list_element(row)
30
+ obj != nil
31
+ end
32
+
33
+ def click(row)
34
+ obj, = find_list_element(row)
35
+ list_object_not_found_exception(obj, @type, row)
36
+ obj.click
37
+ end
38
+
39
+ def get_value(row, visible = true)
40
+ obj, = find_list_element(row, visible)
41
+ list_object_not_found_exception(obj, @type, row)
42
+ case obj.tag_name.downcase
43
+ when 'input', 'select', 'textarea'
44
+ obj.value
45
+ else
46
+ obj.text
47
+ end
48
+ end
49
+
50
+ alias get_caption get_value
51
+
52
+ def find_list_element(row, visible = true)
53
+ set_alt_locator("#{@locator.gsub('ROW_SPEC', row.to_s)}")
54
+ find_element(visible)
55
+ end
56
+
57
+ def list_object_not_found_exception(obj, obj_type, row)
58
+ object_not_found_exception(obj, "Row #{row} #{obj_type}")
59
+ end
60
+ end
61
+ end
@@ -0,0 +1,31 @@
1
+ module TestCentricity
2
+ class ListRadio < ListElement
3
+ attr_accessor :proxy
4
+
5
+ def initialize(name, parent, locator, context, list, proxy = nil)
6
+ super
7
+ @type = :list_radio
8
+ @proxy = proxy
9
+ end
10
+
11
+ def selected?(row)
12
+ obj, = find_list_element(row)
13
+ list_object_not_found_exception(obj, 'List Radio', row)
14
+ obj.checked?
15
+ end
16
+
17
+ def set_selected_state(row, state)
18
+ obj, = find_list_element(row)
19
+ list_object_not_found_exception(obj, 'List Radio', row)
20
+ obj.set(state)
21
+ end
22
+
23
+ def select(row)
24
+ set_selected_state(row, true)
25
+ end
26
+
27
+ def unselect(row)
28
+ set_selected_state(row, false)
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,74 @@
1
+ module TestCentricity
2
+ class Radio < UIElement
3
+ attr_accessor :proxy
4
+
5
+ def initialize(name, parent, locator, context, proxy = nil)
6
+ @name = name
7
+ @parent = parent
8
+ @locator = locator
9
+ @context = context
10
+ @alt_locator = nil
11
+ @proxy = proxy
12
+ @type = :radio
13
+ set_locator_type
14
+ end
15
+
16
+ # Does radio button object exists?
17
+ #
18
+ # @return [Boolean]
19
+ # @example
20
+ # accept_terms_radio.exists?
21
+ #
22
+ def exists?
23
+ obj, = find_object(:all)
24
+ obj != nil
25
+ end
26
+
27
+ # Is radio button selected?
28
+ #
29
+ # @return [Boolean]
30
+ # @example
31
+ # accept_terms_radio.selected?
32
+ #
33
+ def selected?
34
+ obj, = find_element(:all)
35
+ object_not_found_exception(obj, 'Radio')
36
+ obj.checked?
37
+ end
38
+
39
+ # Set the select state of a radio button object.
40
+ #
41
+ # @param state [Boolean] true = selected / false = unselected
42
+ # @example
43
+ # accept_terms_radio.set_selected_state(true)
44
+ #
45
+ def set_selected_state(state)
46
+ obj, = find_element(:all)
47
+ object_not_found_exception(obj, 'Radio')
48
+ invalid_object_type_exception(obj, 'radio')
49
+ if @proxy.nil?
50
+ obj.set(state)
51
+ else
52
+ @proxy.click unless state == obj.checked?
53
+ end
54
+ end
55
+
56
+ # Set the selected state of a radio button object.
57
+ #
58
+ # @example
59
+ # accept_terms_radio.select
60
+ #
61
+ def select
62
+ set_selected_state(true)
63
+ end
64
+
65
+ # Unselect a radio button object.
66
+ #
67
+ # @example
68
+ # accept_terms_radio.unselect
69
+ #
70
+ def unselect
71
+ set_selected_state(false)
72
+ end
73
+ end
74
+ end
@@ -0,0 +1,197 @@
1
+ module TestCentricity
2
+ class SelectList < UIElement
3
+ attr_accessor :list_item
4
+ attr_accessor :selected_item
5
+
6
+ def initialize(name, parent, locator, context)
7
+ super
8
+ @type = :selectlist
9
+ list_spec = {
10
+ :list_item => 'option',
11
+ :selected_item => 'option[selected]'
12
+ }
13
+ define_list_elements(list_spec)
14
+ end
15
+
16
+ def define_list_elements(element_spec)
17
+ element_spec.each do |element, value|
18
+ case element
19
+ when :list_item
20
+ @list_item = value
21
+ when :selected_item
22
+ @selected_item = value
23
+ else
24
+ raise "#{element} is not a recognized selectlist element"
25
+ end
26
+ end
27
+ end
28
+
29
+ # Select the specified option in a select box object. Accepts a String or Hash.
30
+ # Supports standard HTML select objects and Chosen select objects.
31
+ #
32
+ # @param option [String] text of option to select
33
+ # OR
34
+ # @param option [Hash] :value, :index, or :text of option to select
35
+ #
36
+ # @example
37
+ # province_select.choose_option('Alberta')
38
+ # province_select.choose_option(:value => 'AB')
39
+ # state_select.choose_option(:index => 24)
40
+ # state_select.choose_option(:text => 'Maryland')
41
+ #
42
+ def choose_option(option)
43
+ obj, = find_element
44
+ object_not_found_exception(obj, nil)
45
+ obj.click
46
+ if first(:css, "li[class*='active-result']")
47
+ if option.is_a?(Array)
48
+ option.each do |item|
49
+ page.find(:css, "li[class*='active-result']", text: item.strip).click
50
+ end
51
+ else
52
+ if option.is_a?(Hash)
53
+ page.find(:css, "li[class*='active-result']:nth-of-type(#{option[:index]})").click if option.has_key?(:index)
54
+ else
55
+ options = obj.all("li[class*='active-result']").collect(&:text)
56
+ sleep(2) unless options.include?(option)
57
+ first(:css, "li[class*='active-result']", text: option).click
58
+ end
59
+ end
60
+ else
61
+ if option.is_a?(Array)
62
+ option.each do |item|
63
+ select_item(obj, item)
64
+ end
65
+ else
66
+ select_item(obj, option)
67
+ end
68
+ end
69
+ end
70
+
71
+ # Return array of strings of all options in a select box object.
72
+ # Supports standard HTML select objects and Chosen select objects.
73
+ #
74
+ # @return [Array]
75
+ # @example
76
+ # all_colors = color_select.get_options
77
+ #
78
+ def get_options
79
+ obj, = find_element
80
+ object_not_found_exception(obj, nil)
81
+ if first(:css, "li[class*='active-result']")
82
+ obj.all("li[class*='active-result']").collect(&:text)
83
+ else
84
+ obj.all(@list_item).collect(&:text)
85
+ end
86
+ end
87
+
88
+ alias get_list_items get_options
89
+
90
+ # Return the number of options in a select box object.
91
+ # Supports standard HTML select objects and Chosen select objects.
92
+ #
93
+ # @return [Integer]
94
+ # @example
95
+ # num_colors = color_select.get_option_count
96
+ #
97
+ def get_option_count
98
+ obj, = find_element
99
+ object_not_found_exception(obj, nil)
100
+ if first(:css, "li[class*='active-result']")
101
+ obj.all("li[class*='active-result']").count
102
+ else
103
+ obj.all(@list_item).count
104
+ end
105
+ end
106
+
107
+ alias get_item_count get_option_count
108
+
109
+ def verify_options(expected, enqueue = false)
110
+ actual = get_options
111
+ enqueue ?
112
+ ExceptionQueue.enqueue_assert_equal(expected, actual, "Expected list of options in list #{object_ref_message}") :
113
+ assert_equal(expected, actual, "Expected list of options in list #{object_ref_message} to be #{expected} but found #{actual}")
114
+ end
115
+
116
+ # Return text of first selected option in a select box object.
117
+ # Supports standard HTML select objects and Chosen select objects.
118
+ #
119
+ # @return [String]
120
+ # @example
121
+ # current_color = color_select.get_selected_option
122
+ #
123
+ def get_selected_option
124
+ obj, = find_element
125
+ object_not_found_exception(obj, nil)
126
+ if first(:css, "li[class*='active-result']")
127
+ obj.first(:css, "li[class*='result-selected']").text
128
+ else
129
+ obj.first(@selected_item).text
130
+ end
131
+ end
132
+
133
+ alias selected? get_selected_option
134
+
135
+ # Select the specified option in a Siebel OUI select box object.
136
+ #
137
+ # @param option [String] text of option to select
138
+ # @example
139
+ # country_select.choose_siebel_option('Cayman Islands')
140
+ #
141
+ def choose_siebel_option(option)
142
+ Capybara.wait_on_first_by_default = true
143
+ invoke_siebel_popup
144
+ first(:xpath, "//li[@class='ui-menu-item']", :exact => true, :match => :prefer_exact, text: option).click
145
+ end
146
+
147
+ # Return array of strings of all options in a Siebel OUI select box object.
148
+ #
149
+ # @return [Array]
150
+ # @example
151
+ # all_countries = country_select.get_siebel_options
152
+ #
153
+ def get_siebel_options
154
+ invoke_siebel_popup
155
+ sleep(0.5)
156
+ options = page.all(:xpath, "//li[@class='ui-menu-item']").collect(&:text)
157
+ obj, = find_element
158
+ obj.native.send_keys(:escape)
159
+ options
160
+ end
161
+
162
+ def verify_siebel_options(expected, enqueue = false)
163
+ invoke_siebel_popup
164
+ sleep(0.5)
165
+ actual = page.all(:xpath, "//li[@class='ui-menu-item']").collect(&:text)
166
+ enqueue ?
167
+ ExceptionQueue.enqueue_assert_equal(expected, actual, "Expected list of options in list #{object_ref_message}") :
168
+ assert_equal(expected, actual, "Expected list of options in list #{object_ref_message} to be #{expected} but found #{actual}")
169
+ obj, = find_element
170
+ obj.native.send_keys(:escape)
171
+ end
172
+
173
+ # Is Siebel JComboBox set to read-only?
174
+ #
175
+ # @return [Boolean]
176
+ # @example
177
+ # country_select.read_only?
178
+ #
179
+ def read_only?
180
+ obj, = find_element
181
+ object_not_found_exception(obj, nil)
182
+ !obj.native.attribute('readonly')
183
+ end
184
+
185
+ private
186
+
187
+ def select_item(obj, option)
188
+ if option.is_a?(Hash)
189
+ obj.find("option[value='#{option[:value]}']").click if option.has_key?(:value)
190
+ obj.find(:xpath, "option[#{option[:index]}]").select_option if option.has_key?(:index)
191
+ obj.select option[:text] if option.has_key?(:text)
192
+ else
193
+ obj.select option
194
+ end
195
+ end
196
+ end
197
+ end
@@ -0,0 +1,15 @@
1
+ module TestCentricity
2
+ class UIElement
3
+ def invoke_siebel_dialog(popup, seconds = nil)
4
+ invoke_siebel_popup
5
+ timeout = seconds.nil? ? 15 : seconds
6
+ popup.wait_until_exists(timeout)
7
+ end
8
+
9
+ def get_siebel_object_type
10
+ obj, = find_element
11
+ object_not_found_exception(obj, 'Siebel object')
12
+ obj.native.attribute('ot')
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,612 @@
1
+ module TestCentricity
2
+ class Table < UIElement
3
+ attr_accessor :table_body
4
+ attr_accessor :table_section
5
+ attr_accessor :table_row
6
+ attr_accessor :table_column
7
+ attr_accessor :table_header
8
+ attr_accessor :header_row
9
+ attr_accessor :header_column
10
+ attr_accessor :tree_expand
11
+ attr_accessor :tree_collapse
12
+
13
+ def initialize(name, parent, locator, context)
14
+ super
15
+ @type = :table
16
+
17
+ table_spec = { :table_body => 'tbody',
18
+ :table_section => nil,
19
+ :table_row => 'tr',
20
+ :table_column => 'td',
21
+ :table_header => 'thead',
22
+ :header_row => 'tr',
23
+ :header_column => 'th' }
24
+
25
+ case @locator_type
26
+ when :xpath
27
+ table_spec[:tree_expand] = "div/div[contains(@class, 'tree-plus treeclick')]"
28
+ table_spec[:tree_collapse] = "div/div[contains(@class, 'tree-minus treeclick')]"
29
+ when :css
30
+ table_spec[:tree_expand] = "div/div[class*='tree-plus treeclick']"
31
+ table_spec[:tree_collapse] = "div/div[class*='tree-minus treeclick']"
32
+ end
33
+ define_table_elements(table_spec)
34
+ end
35
+
36
+ def define_table_elements(element_spec)
37
+ element_spec.each do |element, value|
38
+ case element
39
+ when :table_body
40
+ @table_body = value
41
+ when :table_section
42
+ @table_section = value
43
+ when :table_row
44
+ @table_row = value
45
+ when :table_column
46
+ @table_column = value
47
+ when :table_header
48
+ @table_header = value
49
+ when :header_row
50
+ @header_row = value
51
+ when :header_column
52
+ @header_column = value
53
+ when :tree_expand
54
+ @tree_expand = value
55
+ when :tree_collapse
56
+ @tree_collapse = value
57
+ else
58
+ raise "#{element} is not a recognized table element"
59
+ end
60
+ end
61
+ end
62
+
63
+ # Return number of rows in a table object.
64
+ #
65
+ # @return [Integer]
66
+ # @example
67
+ # num_rows = list_table.get_row_count
68
+ #
69
+ def get_row_count
70
+ wait_until_exists(5)
71
+ case @locator_type
72
+ when :xpath
73
+ if @table_section.nil?
74
+ page.all(:xpath, "#{@locator}/#{@table_body}/#{@table_row}", :visible => :all).count
75
+ else
76
+ page.all(:xpath, "#{@locator}/#{@table_body}/#{@table_section}", :visible => :all).count
77
+ end
78
+ when :css
79
+ if @table_section.nil?
80
+ page.all(:css, "#{@locator} > #{@table_body} > #{@table_row}", :visible => :all).count
81
+ else
82
+ page.all(:css, "#{@locator} > #{@table_body} > #{@table_section}", :visible => :all).count
83
+ end
84
+ end
85
+ end
86
+
87
+ # Return number of columns in a table object.
88
+ #
89
+ # @return [Integer]
90
+ # @example
91
+ # num_columns = list_table.get_column_count
92
+ #
93
+ def get_column_count
94
+ row_count = get_row_count
95
+ case @locator_type
96
+ when :xpath
97
+ if row_count == 0
98
+ page.all(:xpath, "#{@locator}/#{@table_header}/#{@header_row}/#{@header_column}", :visible => :all).count
99
+ else
100
+ if @table_section.nil?
101
+ row_count == 1 ?
102
+ page.all(:xpath, "#{@locator}/#{@table_body}/#{@table_row}/#{@table_column}", :visible => :all).count :
103
+ page.all(:xpath, "#{@locator}/#{@table_body}/#{@table_row}[2]/#{@table_column}", :visible => :all).count
104
+ else
105
+ row_count == 1 ?
106
+ page.all(:xpath, "#{@locator}/#{@table_body}/#{@table_section}/#{@table_row}/#{@table_column}", :visible => :all).count :
107
+ page.all(:xpath, "#{@locator}/#{@table_body}/#{@table_section}[2]/#{@table_row}/#{@table_column}", :visible => :all).count
108
+ end
109
+ end
110
+ when :css
111
+ if row_count == 0
112
+ page.all(:css, "#{@locator} > #{@table_header} > #{@header_row} > #{@header_column}", :visible => :all).count
113
+ else
114
+ if @table_section.nil?
115
+ row_count == 1 ?
116
+ page.all(:css, "#{@locator} > #{@table_body} > #{@table_row} > #{@table_column}", :visible => :all).count :
117
+ page.all(:css, "#{@locator} > #{@table_body} > #{@table_row}:nth-of-type(2) > #{@table_column}", :visible => :all).count
118
+ else
119
+ row_count == 1 ?
120
+ page.all(:css, "#{@locator} > #{@table_body} > #{@table_section} > #{@table_row} > #{@table_column}", :visible => :all).count :
121
+ page.all(:css, "#{@locator} > #{@table_body} > #{@table_section}:nth-of-type(2) > #{@table_row} > #{@table_column}", :visible => :all).count
122
+ end
123
+ end
124
+ end
125
+ end
126
+
127
+ # Hover over the specified cell in a table object.
128
+ #
129
+ # @param row [Integer] row number
130
+ # @param column [Integer] column number
131
+ # @example
132
+ # list_table.hover_table_cell(2, 6)
133
+ #
134
+ def hover_table_cell(row, column)
135
+ row_count = get_row_count
136
+ raise "Row #{row} exceeds number of rows (#{row_count}) in table #{object_ref_message}" if row > row_count
137
+ column_count = get_column_count
138
+ raise "Column #{column} exceeds number of columns (#{column_count}) in table #{object_ref_message}" if column > column_count
139
+ set_table_cell_locator(row, column)
140
+ hover
141
+ clear_alt_locator
142
+ end
143
+
144
+ # Click in the specified cell in a table object.
145
+ #
146
+ # @param row [Integer] row number
147
+ # @param column [Integer] column number
148
+ # @example
149
+ # list_table.click_table_cell(3, 5)
150
+ #
151
+ def click_table_cell(row, column)
152
+ row_count = get_row_count
153
+ raise "Row #{row} exceeds number of rows (#{row_count}) in table #{object_ref_message}" if row > row_count
154
+ column_count = get_column_count
155
+ raise "Column #{column} exceeds number of columns (#{column_count}) in table #{object_ref_message}" if column > column_count
156
+ set_table_cell_locator(row, column)
157
+ click
158
+ clear_alt_locator
159
+ end
160
+
161
+ # Double-click in the specified cell in a table object.
162
+ #
163
+ # @param row [Integer] row number
164
+ # @param column [Integer] column number
165
+ # @example
166
+ # list_table.double_click_table_cell(3, 5)
167
+ #
168
+ def double_click_table_cell(row, column)
169
+ row_count = get_row_count
170
+ raise "Row #{row} exceeds number of rows (#{row_count}) in table #{object_ref_message}" if row > row_count
171
+ column_count = get_column_count
172
+ raise "Column #{column} exceeds number of columns (#{column_count}) in table #{object_ref_message}" if column > column_count
173
+ set_table_cell_locator(row, column)
174
+ double_click
175
+ clear_alt_locator
176
+ end
177
+
178
+ # Click the link object embedded within the specified cell in a table object.
179
+ #
180
+ # @param row [Integer] row number
181
+ # @param column [Integer] column number
182
+ # @example
183
+ # list_table.click_table_cell_link(3, 1)
184
+ #
185
+ def click_table_cell_link(row, column)
186
+ row_count = get_row_count
187
+ raise "Row #{row} exceeds number of rows (#{row_count}) in table #{object_ref_message}" if row > row_count
188
+ column_count = get_column_count
189
+ raise "Column #{column} exceeds number of columns (#{column_count}) in table #{object_ref_message}" if column > column_count
190
+ set_table_cell_locator(row, column)
191
+ saved_locator = @alt_locator
192
+ case @locator_type
193
+ when :xpath
194
+ set_alt_locator("#{@alt_locator}//a")
195
+ set_alt_locator("#{saved_locator}//span/a") unless exists?
196
+ # if link not present, check for text entry fields and try to dismiss by tabbing out
197
+ unless exists?
198
+ set_alt_locator("#{saved_locator}//input")
199
+ set_alt_locator("#{saved_locator}//textarea") unless exists?
200
+ send_keys(:tab) if exists?
201
+ set_alt_locator("#{saved_locator}//a")
202
+ set_alt_locator("#{saved_locator}//span/a") unless exists?
203
+ send_keys(:tab) unless exists?
204
+ end
205
+ when :css
206
+ set_alt_locator("#{@alt_locator} a")
207
+ set_alt_locator("#{saved_locator} span > a") unless exists?
208
+ # if link not present, check for text entry fields and try to dismiss by tabbing out
209
+ unless exists?
210
+ set_alt_locator("#{saved_locator} input")
211
+ set_alt_locator("#{saved_locator} textarea") unless exists?
212
+ send_keys(:tab) if exists?
213
+ set_alt_locator("#{saved_locator} a")
214
+ set_alt_locator("#{saved_locator} span > a") unless exists?
215
+ send_keys(:tab) unless exists?
216
+ end
217
+ end
218
+ wait_until_exists(1)
219
+ click
220
+ clear_alt_locator
221
+ end
222
+
223
+ def get_table_row(row)
224
+ columns = []
225
+ row_count = get_row_count
226
+ raise "Row #{row} exceeds number of rows (#{row_count}) in table #{object_ref_message}" if row > row_count
227
+ column_count = get_column_count
228
+ (1..column_count).each do |column|
229
+ value = ''
230
+ set_table_cell_locator(row, column)
231
+ saved_locator = @alt_locator
232
+ case @locator_type
233
+ when :xpath
234
+ set_alt_locator("#{saved_locator}//input")
235
+ unless exists?
236
+ set_alt_locator("#{saved_locator}//textarea")
237
+ set_alt_locator(saved_locator) unless exists?
238
+ end
239
+ when :css
240
+ set_alt_locator("#{saved_locator} input")
241
+ unless exists?
242
+ set_alt_locator("#{saved_locator} textarea")
243
+ set_alt_locator(saved_locator) unless exists?
244
+ end
245
+ end
246
+ value = get_value if exists?
247
+ columns.push(value)
248
+ end
249
+ clear_alt_locator
250
+ columns
251
+ end
252
+
253
+ def get_row_data(row)
254
+ row_count = get_row_count
255
+ raise "Row #{row} exceeds number of rows (#{row_count}) in table #{object_ref_message}" if row > row_count
256
+ case @locator_type
257
+ when :xpath
258
+ row > 1 ?
259
+ set_alt_locator("#{@locator}/#{@table_body}/#{@table_row}[#{row}]") :
260
+ set_alt_locator("#{@locator}/#{@table_body}/#{@table_row}")
261
+ when :css
262
+ row > 1 ?
263
+ set_alt_locator("#{@locator} > #{@table_body} > #{@table_row}:nth-of-type(#{row})") :
264
+ set_alt_locator("#{@locator} > #{@table_body} > #{@table_row}")
265
+ end
266
+ value = get_value if exists?
267
+ clear_alt_locator
268
+ value
269
+ end
270
+
271
+ def get_table_column(column)
272
+ rows = []
273
+ column_count = get_column_count
274
+ raise "Column #{column} exceeds number of columns (#{column_count}) in table #{object_ref_message}" if column > column_count
275
+ row_count = get_row_count
276
+ (1..row_count).each do |row|
277
+ value = ''
278
+ set_table_cell_locator(row, column)
279
+ saved_locator = @alt_locator
280
+ case @locator_type
281
+ when :xpath
282
+ set_alt_locator("#{saved_locator}//input")
283
+ unless exists?
284
+ set_alt_locator("#{saved_locator}//textarea")
285
+ set_alt_locator(saved_locator) unless exists?
286
+ end
287
+ when :css
288
+ set_alt_locator("#{saved_locator} input")
289
+ unless exists?
290
+ set_alt_locator("#{saved_locator} textarea")
291
+ set_alt_locator(saved_locator) unless exists?
292
+ end
293
+ end
294
+ value = get_value if exists?
295
+ rows.push(value)
296
+ end
297
+ clear_alt_locator
298
+ rows
299
+ end
300
+
301
+ # Return text contained in specified cell of a table object.
302
+ #
303
+ # @param row [Integer] row number
304
+ # @param column [Integer] column number
305
+ # @return [String] value of table cell
306
+ # @example
307
+ # list_table.get_table_cell(4, 5)
308
+ #
309
+ def get_table_cell(row, column)
310
+ row_count = get_row_count
311
+ raise "Row #{row} exceeds number of rows (#{row_count}) in table #{object_ref_message}" if row > row_count
312
+ column_count = get_column_count
313
+ raise "Column #{column} exceeds number of columns (#{column_count}) in table #{object_ref_message}" if column > column_count
314
+ set_table_cell_locator(row, column)
315
+ saved_locator = @alt_locator
316
+ case @locator_type
317
+ when :xpath
318
+ set_alt_locator("#{saved_locator}//input")
319
+ unless exists?
320
+ set_alt_locator("#{saved_locator}//textarea")
321
+ set_alt_locator(saved_locator) unless exists?
322
+ end
323
+ when :css
324
+ set_alt_locator("#{saved_locator} input")
325
+ unless exists?
326
+ set_alt_locator("#{saved_locator} textarea")
327
+ set_alt_locator(saved_locator) unless exists?
328
+ end
329
+ end
330
+ if exists?
331
+ value = get_value
332
+ else
333
+ puts "Could not find table cell at #{@alt_locator}"
334
+ value = ''
335
+ end
336
+ clear_alt_locator
337
+ value
338
+ end
339
+
340
+ def verify_table_cell(row, column, expected, enqueue = false)
341
+ actual = get_table_cell(row, column)
342
+ enqueue ?
343
+ ExceptionQueue.enqueue_assert_equal(expected.strip, actual.strip, "Expected table #{object_ref_message} row #{row}/column #{column}") :
344
+ assert_equal(expected.strip, actual.strip, "Expected table #{object_ref_message} row #{row}/column #{column} to display '#{expected}' but found '#{actual}'")
345
+ end
346
+
347
+ # Set the value of the specified cell in a table object.
348
+ #
349
+ # @param row [Integer] row number
350
+ # @param column [Integer] column number
351
+ # @param value [String] text to set
352
+ # @example
353
+ # list_table.set_table_cell(3, 1, 'Ontario')
354
+ #
355
+ def set_table_cell(row, column, value)
356
+ row_count = get_row_count
357
+ raise "Row #{row} exceeds number of rows (#{row_count}) in table #{object_ref_message}" if row > row_count
358
+ find_table_cell(row, column)
359
+ find_table_cell(row, column) unless exists?
360
+ set(value)
361
+ clear_alt_locator
362
+ end
363
+
364
+ def get_cell_attribute(row, column, attrib)
365
+ row_count = get_row_count
366
+ raise "Row #{row} exceeds number of rows (#{row_count}) in table #{object_ref_message}" if row > row_count
367
+ column_count = get_column_count
368
+ raise "Column #{column} exceeds number of columns (#{column_count}) in table #{object_ref_message}" if column > column_count
369
+ set_table_cell_locator(row, column)
370
+ result = get_native_attribute(attrib)
371
+ clear_alt_locator
372
+ result
373
+ end
374
+
375
+ def get_row_attribute(row, attrib)
376
+ row_count = get_row_count
377
+ raise "Row #{row} exceeds number of rows (#{row_count}) in table #{object_ref_message}" if row > row_count
378
+ case @locator_type
379
+ when :xpath
380
+ row > 1 ?
381
+ set_alt_locator("#{@locator}/#{@table_body}/#{@table_row}[#{row}]") :
382
+ set_alt_locator("#{@locator}/#{@table_body}/#{@table_row}")
383
+ when :css
384
+ row > 1 ?
385
+ set_alt_locator("#{@locator} > #{@table_body} > #{@table_row}:nth-of-type(#{row})") :
386
+ set_alt_locator("#{@locator} > #{@table_body} > #{@table_row}")
387
+ end
388
+ result = get_native_attribute(attrib)
389
+ clear_alt_locator
390
+ result
391
+ end
392
+
393
+ def find_row_attribute(attrib, search_value)
394
+ (1..get_row_count).each do |row|
395
+ return row if get_row_attribute(row, attrib) == search_value
396
+ end
397
+ nil
398
+ end
399
+
400
+ # Search for the specified text value in the specified row of the table object.
401
+ # Returns the number of the first column that contains the search value.
402
+ #
403
+ # @param row [Integer] row nummber
404
+ # @param search_value [String] value to be searched for
405
+ # @return [Integer] column number of table cell that contains search value
406
+ # @example
407
+ # bom_table.find_in_table_row(4, 'High-speed Framus bolts')
408
+ #
409
+ def find_in_table_row(row, search_value)
410
+ (1..get_column_count).each do |column|
411
+ return column if get_table_cell(row, column) == search_value
412
+ end
413
+ nil
414
+ end
415
+
416
+ # Search for the specified text value in the specified column of the table object.
417
+ # Returns the number of the first row that contains the search value.
418
+ #
419
+ # @param column [Integer] column nummber
420
+ # @param search_value [String] value to be searched for
421
+ # @return [Integer] row number of table cell that contains search value
422
+ # @example
423
+ # playlist_table.find_in_table_column(1, 'Ashes to Ashes')
424
+ #
425
+ def find_in_table_column(column, search_value)
426
+ (1..get_row_count).each do |row|
427
+ return row if get_table_cell(row, column) == search_value
428
+ end
429
+ nil
430
+ end
431
+
432
+ # Populate the specified row of this table object with the associated data from a Hash passed as an
433
+ # argument. Data values must be in the form of a String for textfield and select list controls. For checkbox
434
+ # and radio buttons, data must either be a Boolean or a String that evaluates to a Boolean value (Yes, No, 1,
435
+ # 0, true, false)
436
+ #
437
+ # @param data [Hash] column numbers and associated data to be entered
438
+ # @example
439
+ # data = { 1 => 'Dr.',
440
+ # 2 => 'Evangeline',
441
+ # 3 => 'Devereaux',
442
+ # 4 => 'MD',
443
+ # 5 => 'Family Practice'
444
+ # }
445
+ # clinicians_table.populate_table_row(3, data)
446
+ #
447
+ def populate_table_row(row, data)
448
+ wait_until_exists(2)
449
+ data.each do |column, data_param|
450
+ unless data_param.blank?
451
+ if data_param == '!DELETE'
452
+ set_table_cell(row, column, '')
453
+ else
454
+ set_table_cell(row, column, data_param)
455
+ end
456
+ end
457
+ end
458
+ end
459
+
460
+ # Click in the specified column header in a table object.
461
+ #
462
+ # @param column [Integer] column number
463
+ # @example
464
+ # list_table.click_header_column(3)
465
+ #
466
+ def click_header_column(column)
467
+ column_count = get_column_count
468
+ raise "Column #{column} exceeds number of columns (#{column_count}) in table header #{object_ref_message}" if column > column_count
469
+ case @locator_type
470
+ when :xpath
471
+ set_alt_locator("#{@locator}//#{@table_header}/#{@header_row}/#{@header_column}[#{column}]")
472
+ when :css
473
+ set_alt_locator("#{@locator} #{@table_header} > #{@header_row} > #{@header_column}:nth-of-type(#{column})")
474
+ end
475
+ click if exists?
476
+ clear_alt_locator
477
+ end
478
+
479
+ def get_header_column(column)
480
+ column_count = get_column_count
481
+ raise "Column #{column} exceeds number of columns (#{column_count}) in table header #{object_ref_message}" if column > column_count
482
+ case @locator_type
483
+ when :xpath
484
+ set_alt_locator("#{@locator}//#{@table_header}/#{@header_row}/#{@header_column}[#{column}]")
485
+ when :css
486
+ set_alt_locator("#{@locator} #{@table_header} > #{@header_row} > #{@header_column}:nth-of-type(#{column})")
487
+ end
488
+ value = get_value(:all) if exists?(:all)
489
+ clear_alt_locator
490
+ value
491
+ end
492
+
493
+ def get_header_columns
494
+ columns = []
495
+ column_count = get_column_count
496
+ (1..column_count).each do |column|
497
+ case @locator_type
498
+ when :xpath
499
+ set_alt_locator("#{@locator}//#{@table_header}/#{@header_row}/#{@header_column}[#{column}]")
500
+ when :css
501
+ set_alt_locator("#{@locator} #{@table_header} > #{@header_row} > #{@header_column}:nth-of-type(#{column})")
502
+ end
503
+ columns.push(get_value(:all)) if exists?(:all)
504
+ end
505
+ clear_alt_locator
506
+ columns
507
+ end
508
+
509
+ def is_table_row_expanded?(row, column)
510
+ row_count = get_row_count
511
+ raise "Row #{row} exceeds number of rows (#{row_count}) in table #{object_ref_message}" if row > row_count
512
+ column_count = get_column_count
513
+ raise "Column #{column} exceeds number of columns (#{column_count}) in table #{object_ref_message}" if column > column_count
514
+ set_table_cell_locator(row, column)
515
+ case @locator_type
516
+ when :xpath
517
+ set_alt_locator("#{@alt_locator}/#{@tree_expand}")
518
+ when :css
519
+ set_alt_locator("#{@alt_locator} > #{@tree_expand}")
520
+ end
521
+ expanded = true
522
+ expanded = false if exists?
523
+ clear_alt_locator
524
+ expanded
525
+ end
526
+
527
+ def expand_table_row(row, column)
528
+ unless is_table_row_expanded?(row, column)
529
+ set_table_cell_locator(row, column)
530
+ case @locator_type
531
+ when :xpath
532
+ set_alt_locator("#{@alt_locator}/#{@tree_expand}")
533
+ when :css
534
+ set_alt_locator("#{@alt_locator} > #{@tree_expand}")
535
+ end
536
+ click if exists?
537
+ clear_alt_locator
538
+ end
539
+ end
540
+
541
+ def collapse_table_row(row, column)
542
+ if is_table_row_expanded?(row, column)
543
+ set_table_cell_locator(row, column)
544
+ case @locator_type
545
+ when :xpath
546
+ set_alt_locator("#{@alt_locator}/#{@tree_collapse}")
547
+ when :css
548
+ set_alt_locator("#{@alt_locator} > #{@tree_collapse}")
549
+ end
550
+ click if exists?
551
+ clear_alt_locator
552
+ end
553
+ end
554
+
555
+ def expand_all_table_rows(column)
556
+ row_count = get_row_count
557
+ column_count = get_column_count
558
+ raise "Column #{column} exceeds number of columns (#{column_count}) in table #{object_ref_message}" if column > column_count
559
+ row_count.downto(1) do |row|
560
+ expand_table_row(row, column)
561
+ end
562
+ end
563
+
564
+ def get_table_cell_locator(row, column)
565
+ case @locator_type
566
+ when :xpath
567
+ if @table_section.nil?
568
+ row_spec = "#{@locator}/#{@table_body}/#{@table_row}"
569
+ row_spec = "#{row_spec}[#{row}]"
570
+ else
571
+ row_spec = "#{@locator}/#{@table_body}/#{@table_section}"
572
+ row_spec = "#{row_spec}[#{row}]/#{@table_row}[1]"
573
+ end
574
+ column_spec = "/#{@table_column}[#{column}]"
575
+ when :css
576
+ if @table_section.nil?
577
+ row_spec = "#{@locator} > #{@table_body} > #{@table_row}"
578
+ row_spec = "#{row_spec}:nth-of-type(#{row})"
579
+ else
580
+ row_spec = "#{@locator} > #{@table_body} > #{@table_section}"
581
+ row_spec = "#{row_spec}:nth-of-type(#{row}) > #{@table_row}:nth-of-type(1)"
582
+ end
583
+ column_spec = " > #{@table_column}:nth-of-type(#{column})"
584
+ end
585
+ "#{row_spec}#{column_spec}"
586
+ end
587
+
588
+ private
589
+
590
+ def set_table_cell_locator(row, column)
591
+ set_alt_locator(get_table_cell_locator(row, column))
592
+ end
593
+
594
+ def find_table_cell(row, column)
595
+ set_table_cell_locator(row, column)
596
+ if exists?
597
+ click
598
+ else
599
+ puts "Could not find table cell at #{@alt_locator}"
600
+ end
601
+ saved_locator = @alt_locator
602
+ case @locator_type
603
+ when :xpath
604
+ set_alt_locator("#{saved_locator}//input")
605
+ set_alt_locator("#{saved_locator}//textarea") unless exists?
606
+ when :css
607
+ set_alt_locator("#{saved_locator} input")
608
+ set_alt_locator("#{saved_locator} textarea") unless exists?
609
+ end
610
+ end
611
+ end
612
+ end