Module: Avo::TestHelpers
Instance Method Summary collapse
- #accept_custom_alert(&block) ⇒ Object
-
#add_tag(field:, tag:) ⇒ Object
Example usage: expect(add_tag(field: :tags, tag: "one")).to eq ["one"] add_tag(field: :tags, tag: "two").
- #check_select_all ⇒ Object
- #click_global_search_input ⇒ Object
- #click_on_sidebar_item(label) ⇒ Object
-
#click_row_action(record, control:) ⇒ Object
Clicks a row control action (destroy, detach, edit, etc.) for a given record.
- #click_tab(tab_name = "", within_target: nil, **args) ⇒ Object
- #close_picker ⇒ Object
- #empty_dash ⇒ Object
- #first_tab_group ⇒ Object
-
#grid_field_wrapper(record_id:) ⇒ Object
Finds the wrapper element on the index grid view type for the given record id Example usage: grid_field_wrapper(record_id: 5).
-
#has_and_belongs_to_many_field_wrapper(id:, view: :show) ⇒ Object
Finds the table on the show view for the given has_and_belongs_to_many field id and view Example usage: has_and_belongs_to_many_field_wrapper(id: :users) has_and_belongs_to_many_field_wrapper(id: :users, view: :edit).
-
#has_many_field_wrapper(id:, view: :show) ⇒ Object
Finds the table on the show view for the given has_many field id and view Example usage: has_many_field_wrapper(id: :users) has_many_field_wrapper(id: :users, view: :edit).
-
#has_one_field_wrapper(id:, view: :show) ⇒ Object
Finds the table on the show view for the given has_one field id and view Example usage: has_one_field_wrapper(id: :users) has_one_field_wrapper(id: :users, view: :edit).
-
#index_field_label(id:) ⇒ Object
Finds the label element on the index view for the given field id Example usage: index_field_label(id: "name").
-
#index_field_value(id:, record_id:, type: nil) ⇒ Object
Finds the value element on the index view for the given field id Example usage: index_field_value(id: "name", record_id: 2).
-
#index_field_wrapper(id:, record_id:, type: nil) ⇒ Object
Finds the wrapper element on the index view for the given field id and type, and associated with the given record id Example usage: index_field_wrapper(id: "name", type: "text", record_id: 2) index_field_wrapper(id: "name", record_id: 2).
-
#open_panel_action(action_name:, list: "Actions") ⇒ Object
Click on the action from the panel (index and show above the table) Pass list: nil to run a standalone action (found by data-action-name / action name, not link text) Pass list: "List name" if list is not the default "Actions" Example usage: open_panel_action(action_name: "Dummy action") open_panel_action(list: nil, action_name: "Release fish") open_panel_action(list: "Runnables", action_name: "Release fish").
- #open_picker ⇒ Object
-
#open_row_action(record_id:, action_name:, list: "Actions") ⇒ Object
Open the action from the record_id row Pass list: nil to run a standalone row action (matched by action name, not visible label) Pass list: "List name" if list is not the default "Actions" Example usage: open_row_action(action_name: "Dummy action") open_row_action(list: nil, action_name: "Release fish") open_row_action(list: "Runnables", action_name: "Release fish").
-
#remove_tag(field:, tag:) ⇒ Object
Example usage: expect(remove_tag(field: :tags, tag: "one")).to eq ["three"] remove_tag(field: :tags, tag: "one").
-
#run_action ⇒ Object
Click on submit action button if dialog is open.
-
#save ⇒ Object
Save a record and wait for the page to load For most cases
.clickworks Sometimes other element may be overlapping the button so the.trigger("click")solves the issue Trigger can't be used by default because it breaks on some feature specs. - #second_tab_group ⇒ Object
-
#select_first_result_in_search ⇒ Object
TODO: this will make sense only on global search Should use the click_global_search_input or click_resource_search_input method to open the search box first and optionaly write_in_search.
- #set_picker_dates(input, *dates) ⇒ Object
- #set_picker_day(date) ⇒ Object
- #set_picker_hour(value) ⇒ Object
- #set_picker_minute(value) ⇒ Object
- #set_picker_second(value) ⇒ Object
- #set_picker_text_input(value) ⇒ Object
- #set_picker_time(input, hour:, minute: 0, second: 0) ⇒ Object
-
#show_field_label(id:) ⇒ Object
Finds the label element on the show view for the given field id Example usage: show_field_label(id: "name").
-
#show_field_value(id:, type: nil) ⇒ Object
Finds the value element on the show view for the given field id Example usage: show_field_value(id: "name").
-
#show_field_wrapper(id:, type: nil) ⇒ Object
Finds the wrapper element on the show view for the given field id and type Example usage: show_field_wrapper(id: "name", type: "text") show_field_wrapper(id: "name").
- #tab_group(index = 0) ⇒ Object
-
#tag_suggestions(field:, input:) ⇒ Object
Example usage: expect(tag_suggestions(field: :tags, input: "")).to eq ["one", "two", "three"] expect(tag_suggestions(field: :tags, input: "t")).to eq ["two", "three"].
-
#tags(field:) ⇒ Object
Example usage: expect(tags(field: :tags)).to eq ["one", "two", "three"] expect(tags(field: :tags)).to eq [].
- #third_tab_group ⇒ Object
- #toggle_collapsable(section) ⇒ Object
- #type ⇒ Object
- #write_in_global_search(input) ⇒ Object
-
#write_in_search(input) ⇒ Object
Should use the click_global_search_input or click_resource_search_input method to open the search box first.
Methods included from WaitForLoaded
#wait_for_action_dialog_to_disappear, #wait_for_body_class_missing, #wait_for_element_missing, #wait_for_element_present, #wait_for_loaded, #wait_for_path_to_be, #wait_for_route_loaded, #wait_for_route_loading, #wait_for_search_loaded, #wait_for_search_to_dissapear, #wait_for_tag_suggestions_to_appear, #wait_for_tag_to_appear, #wait_for_tag_to_disappear, #wait_for_turbo_frame_id, #wait_for_turbo_frame_src, #wait_for_turbo_loaded
Instance Method Details
#accept_custom_alert(&block) ⇒ Object
341 342 343 344 |
# File 'lib/avo/test_helpers.rb', line 341 def accept_custom_alert(&block) block.call find('#turbo-confirm button[value="confirm"]').click end |
#add_tag(field:, tag:) ⇒ Object
Example usage:
expect(add_tag(field: :tags, tag: "one")).to eq ["one"]
add_tag(field: :tags, tag: "two")
274 275 276 277 278 279 280 281 282 283 284 |
# File 'lib/avo/test_helpers.rb', line 274 def add_tag(field:, tag:) # Find the input field for the specified field and click it find("[data-field-id='#{field}'] [data-slot='value'] [role='textbox']").click # Enter the specified tag into the input field type tag, :return wait_for_tag_to_appear(tag) # Return an array of the current tags (field: field) end |
#check_select_all ⇒ Object
263 264 265 |
# File 'lib/avo/test_helpers.rb', line 263 def check_select_all find("input[type='checkbox'][name='Select all'][data-action='input->item-select-all#toggle']").set(true) end |
#click_global_search_input ⇒ Object
96 97 98 |
# File 'lib/avo/test_helpers.rb', line 96 def click_global_search_input page.find("[data-global-search-target='input']").click end |
#click_on_sidebar_item(label) ⇒ Object
178 179 180 181 182 |
# File 'lib/avo/test_helpers.rb', line 178 def (label) within do click_on label end end |
#click_row_action(record, control:) ⇒ Object
Clicks a row control action (destroy, detach, edit, etc.) for a given record. Works for both grid view (actions behind a popover trigger) and table view (flat inline actions).
348 349 350 351 352 353 354 355 356 357 358 |
# File 'lib/avo/test_helpers.rb', line 348 def click_row_action(record, control:) row = find("[data-record-id='#{record.to_param}']") if row.has_css?(".grid-card__actions-row button[popovertarget]", wait: 0) row.find(".grid-card__actions-row button[popovertarget]").click end within(row) do find("a[data-control='#{control}'][data-resource-id='#{record.to_param}']").click end end |
#click_tab(tab_name = "", within_target: nil, **args) ⇒ Object
145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 |
# File 'lib/avo/test_helpers.rb', line 145 def click_tab(tab_name = "", within_target: nil, **args) tab_container_selector = '[data-controller="tabs"] [role="tablist"]' if within_target.present? within within_target do within find(tab_container_selector) do find_link(tab_name).trigger("click") end end else within find(tab_container_selector) do find_link(tab_name).trigger("click") end end wait_for_loaded end |
#close_picker ⇒ Object
227 228 229 230 |
# File 'lib/avo/test_helpers.rb', line 227 def close_picker all(".header__title").first.trigger("click") sleep 0.3 end |
#empty_dash ⇒ Object
92 93 94 |
# File 'lib/avo/test_helpers.rb', line 92 def empty_dash "—" end |
#first_tab_group ⇒ Object
166 167 168 |
# File 'lib/avo/test_helpers.rb', line 166 def first_tab_group tab_group 0 end |
#grid_field_wrapper(record_id:) ⇒ Object
Finds the wrapper element on the index grid view type for the given record id Example usage:
grid_field_wrapper(record_id: 5)
22 23 24 |
# File 'lib/avo/test_helpers.rb', line 22 def grid_field_wrapper(record_id:) find("[data-component-name='avo/index/grid_item_component'][data-resource-id='#{record_id}']") end |
#has_and_belongs_to_many_field_wrapper(id:, view: :show) ⇒ Object
Finds the table on the show view for the given has_and_belongs_to_many field id and view Example usage:
has_and_belongs_to_many_field_wrapper(id: :users)
has_and_belongs_to_many_field_wrapper(id: :users, view: :edit)
52 53 54 |
# File 'lib/avo/test_helpers.rb', line 52 def has_and_belongs_to_many_field_wrapper(id:, view: :show) (id: id, relation: :has_and_belongs_to_many, view: view) end |
#has_many_field_wrapper(id:, view: :show) ⇒ Object
Finds the table on the show view for the given has_many field id and view Example usage:
has_many_field_wrapper(id: :users)
has_many_field_wrapper(id: :users, view: :edit)
44 45 46 |
# File 'lib/avo/test_helpers.rb', line 44 def has_many_field_wrapper(id:, view: :show) (id: id, relation: :has_many, view: view) end |
#has_one_field_wrapper(id:, view: :show) ⇒ Object
Finds the table on the show view for the given has_one field id and view Example usage:
has_one_field_wrapper(id: :users)
has_one_field_wrapper(id: :users, view: :edit)
60 61 62 |
# File 'lib/avo/test_helpers.rb', line 60 def has_one_field_wrapper(id:, view: :show) (id: id, relation: :has_one, view: view) end |
#index_field_label(id:) ⇒ Object
Finds the label element on the index view for the given field id Example usage:
index_field_label(id: "name")
67 68 69 |
# File 'lib/avo/test_helpers.rb', line 67 def index_field_label(id:) find("[data-component-name='avo/partials/table_header'] [data-table-header-field-id='#{id}']").text end |
#index_field_value(id:, record_id:, type: nil) ⇒ Object
Finds the value element on the index view for the given field id Example usage:
index_field_value(id: "name", record_id: 2)
81 82 83 |
# File 'lib/avo/test_helpers.rb', line 81 def index_field_value(id:, record_id:, type: nil) index_field_wrapper(id: id, record_id: record_id, type: type).text end |
#index_field_wrapper(id:, record_id:, type: nil) ⇒ Object
Finds the wrapper element on the index view for the given field id and type, and associated with the given record id Example usage:
index_field_wrapper(id: "name", type: "text", record_id: 2)
index_field_wrapper(id: "name", record_id: 2)
9 10 11 12 13 14 15 16 17 |
# File 'lib/avo/test_helpers.rb', line 9 def index_field_wrapper(id:, record_id:, type: nil) base_data = "#{row(record_id)} [data-field-id='#{id}']" if type.present? find("#{base_data}[data-resource-index-target='#{wrapper_name_for(id: id, type: type)}']") else find(base_data) end end |
#open_panel_action(action_name:, list: "Actions") ⇒ Object
Click on the action from the panel (index and show above the table) Pass list: nil to run a standalone action (found by data-action-name / action name, not link text) Pass list: "List name" if list is not the default "Actions" Example usage:
open_panel_action(action_name: "Dummy action")
open_panel_action(list: nil, action_name: "Release fish")
open_panel_action(list: "Runnables", action_name: "Release fish")
239 240 241 |
# File 'lib/avo/test_helpers.rb', line 239 def open_panel_action(action_name:, list: "Actions") open_action(action_name: action_name, list: list, context: first(".header__controls")) end |
#open_picker ⇒ Object
223 224 225 |
# File 'lib/avo/test_helpers.rb', line 223 def open_picker text_input.click end |
#open_row_action(record_id:, action_name:, list: "Actions") ⇒ Object
Open the action from the record_id row Pass list: nil to run a standalone row action (matched by action name, not visible label) Pass list: "List name" if list is not the default "Actions" Example usage:
open_row_action(action_name: "Dummy action")
open_row_action(list: nil, action_name: "Release fish")
open_row_action(list: "Runnables", action_name: "Release fish")
250 251 252 |
# File 'lib/avo/test_helpers.rb', line 250 def open_row_action(record_id:, action_name:, list: "Actions") open_action(action_name: action_name, list: list, context: row(record_id)) end |
#remove_tag(field:, tag:) ⇒ Object
Example usage:
expect(remove_tag(field: :tags, tag: "one")).to eq ["three"]
remove_tag(field: :tags, tag: "one")
289 290 291 292 293 294 295 296 297 298 299 300 |
# File 'lib/avo/test_helpers.rb', line 289 def remove_tag(field:, tag:) # Within the specified field within("[data-field-id='#{field}'] [data-slot='value']") do # Find the tag with the specified text and click the remove button for the tag page.find(".tagify__tag", text: tag).find(".tagify__tag__removeBtn").click wait_for_tag_to_disappear(tag) end # Return an array of the current tags (field: field) end |
#run_action ⇒ Object
Click on submit action button if dialog is open
255 256 257 258 259 260 261 |
# File 'lib/avo/test_helpers.rb', line 255 def run_action within(find("[role='dialog']")) do find("[data-target='submit_action']").click end wait_for_action_dialog_to_disappear end |
#save ⇒ Object
Save a record and wait for the page to load
For most cases .click works
Sometimes other element may be overlapping the button so the .trigger("click") solves the issue
Trigger can't be used by default because it breaks on some feature specs
136 137 138 139 140 141 142 143 |
# File 'lib/avo/test_helpers.rb', line 136 def save = find("button.button", text: "Save") .click rescue Capybara::Cuprite::MouseEventFailed .trigger("click") ensure wait_for_loaded end |
#second_tab_group ⇒ Object
170 171 172 |
# File 'lib/avo/test_helpers.rb', line 170 def second_tab_group tab_group 1 end |
#select_first_result_in_search ⇒ Object
TODO: this will make sense only on global search Should use the click_global_search_input or click_resource_search_input method to open the search box first and optionaly write_in_search. Example usage:
open_search_box(:users) # opens the search box for the "users" resource
write_in_search("John Doe")
select_first_result_in_search
123 124 125 126 127 128 129 130 |
# File 'lib/avo/test_helpers.rb', line 123 def select_first_result_in_search type :down, :enter rescue find(".aa-Input").send_keys :arrow_down find(".aa-Input").send_keys :enter ensure wait_for_search_loaded end |
#set_picker_dates(input, *dates) ⇒ Object
189 190 191 192 193 194 195 |
# File 'lib/avo/test_helpers.rb', line 189 def set_picker_dates(input, *dates) page.execute_script( "arguments[0]._flatpickr.setDate(arguments[1], true)", input.native, (dates.length == 1) ? dates.first : dates ) end |
#set_picker_day(date) ⇒ Object
184 185 186 187 |
# File 'lib/avo/test_helpers.rb', line 184 def set_picker_day(date) find(".flatpickr-day[aria-label=\"#{date}\"]").click sleep 0.2 end |
#set_picker_hour(value) ⇒ Object
205 206 207 |
# File 'lib/avo/test_helpers.rb', line 205 def set_picker_hour(value) find(".flatpickr-hour").set(value) end |
#set_picker_minute(value) ⇒ Object
209 210 211 |
# File 'lib/avo/test_helpers.rb', line 209 def set_picker_minute(value) find(".flatpickr-minute").set(value) end |
#set_picker_second(value) ⇒ Object
213 214 215 |
# File 'lib/avo/test_helpers.rb', line 213 def set_picker_second(value) find(".flatpickr-second").set(value) end |
#set_picker_text_input(value) ⇒ Object
217 218 219 220 221 |
# File 'lib/avo/test_helpers.rb', line 217 def set_picker_text_input(value) element = find("input.form-control[type='text']") # Set value without firing input/change events page.execute_script("arguments[0].value = arguments[1]", element.native, value) end |
#set_picker_time(input, hour:, minute: 0, second: 0) ⇒ Object
197 198 199 200 201 202 203 |
# File 'lib/avo/test_helpers.rb', line 197 def set_picker_time(input, hour:, minute: 0, second: 0) page.execute_script( "arguments[0]._flatpickr.setDate(arguments[1], true)", input.native, "#{hour}:#{minute}:#{second}" ) end |
#show_field_label(id:) ⇒ Object
Finds the label element on the show view for the given field id Example usage:
show_field_label(id: "name")
74 75 76 |
# File 'lib/avo/test_helpers.rb', line 74 def show_field_label(id:) within(show_field_wrapper(id: id)) { find("[data-slot='label']").text } end |
#show_field_value(id:, type: nil) ⇒ Object
Finds the value element on the show view for the given field id Example usage:
show_field_value(id: "name")
88 89 90 |
# File 'lib/avo/test_helpers.rb', line 88 def show_field_value(id:, type: nil) within(show_field_wrapper(id: id, type: type)) { find("[data-slot='value']").text } end |
#show_field_wrapper(id:, type: nil) ⇒ Object
Finds the wrapper element on the show view for the given field id and type Example usage:
show_field_wrapper(id: "name", type: "text")
show_field_wrapper(id: "name")
30 31 32 33 34 35 36 37 38 |
# File 'lib/avo/test_helpers.rb', line 30 def show_field_wrapper(id:, type: nil) base_data = "[data-field-id='#{id}']" if type.present? find("#{base_data}[data-resource-show-target='#{wrapper_name_for(id: id, type: type)}']") else find(base_data) end end |
#tab_group(index = 0) ⇒ Object
162 163 164 |
# File 'lib/avo/test_helpers.rb', line 162 def tab_group(index = 0) find_all('[data-controller="tabs"]')[index] end |
#tag_suggestions(field:, input:) ⇒ Object
Example usage:
expect(tag_suggestions(field: :tags, input: "")).to eq ["one", "two", "three"]
expect(tag_suggestions(field: :tags, input: "t")).to eq ["two", "three"]
314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 |
# File 'lib/avo/test_helpers.rb', line 314 def tag_suggestions(field:, input:) # Find the input field for the specified tag field input_area = find("[data-field-id='#{field}'] [data-slot='value'] [role='textbox']") # If the input argument is present, enter it into the input field # Else, set input to "open" than to " " to trigger dropdown if input.present? input_area.set(input) else input_area.set("open") input_area.set(" ") end wait_for_tag_suggestions_to_appear # Find all elements with class 'tagify_dropdown_item' within the dropdown # Map the elements to their 'label' attribute values and return the array of labels page.all(".tagify__dropdown__item").map { |element| element[:label] } end |
#tags(field:) ⇒ Object
Example usage:
expect((field: :tags)).to eq ["one", "two", "three"]
expect((field: :tags)).to eq []
305 306 307 308 309 |
# File 'lib/avo/test_helpers.rb', line 305 def (field:) # Find all elements with class 'tagify__tag' # Map the elements to text and return the array of texts page.all(".tagify__tag").map(&:text) end |
#third_tab_group ⇒ Object
174 175 176 |
# File 'lib/avo/test_helpers.rb', line 174 def third_tab_group tab_group 3 end |
#toggle_collapsable(section) ⇒ Object
267 268 269 |
# File 'lib/avo/test_helpers.rb', line 267 def toggle_collapsable(section) find("[data-action='click->menu#triggerCollapse'][data-menu-key-param*='main_menu.#{section.underscore}'] svg").click end |
#type ⇒ Object
333 334 335 336 337 338 339 |
# File 'lib/avo/test_helpers.rb', line 333 def type(...) if page.driver.browser.respond_to?(:keyboard) page.driver.browser.keyboard.type(...) else page.send_keys(...) end end |
#write_in_global_search(input) ⇒ Object
113 114 115 |
# File 'lib/avo/test_helpers.rb', line 113 def write_in_global_search(input) page.find("[data-global-search-target='input']").set(input) end |
#write_in_search(input) ⇒ Object
Should use the click_global_search_input or click_resource_search_input method to open the search box first. Example usage:
open_search_box(:users)
within(has_and_belongs_to_many_field_wrapper(id: :users)) {
click_resource_search_input # opens the search box for the "users" resource
write_in_search("Bob")
}
107 108 109 110 111 |
# File 'lib/avo/test_helpers.rb', line 107 def write_in_search(input) # Use xpath to find outside of within context if any find('[data-resource-search-target="input"]').set(input) wait_for_search_loaded end |