Files
openfoodnetwork/spec/support/request/web_helper.rb
Gaetan Craig-Riou 98545741e6 Add tomselect_select helper
When using `tomselect_search_and_select` and searching isn't really
required it leaves the dropdown option open. It can then cause problem
when trying to interact with other element in the page. This happens
because clicking on the chosen option happena before the searching
finishes.
We can now use `tomselect_select` when searching is not actually
required.
It should not be a problem when search is required, as capybara will
wait for the option to appear on the page before clicking.
2024-01-24 14:47:21 +11:00

135 lines
4.3 KiB
Ruby

# frozen_string_literal: true
module WebHelper
def have_input(name, opts = {})
selector = "[name='#{name}']"
selector += "[placeholder='#{opts[:placeholder]}']" if opts.key? :placeholder
visible = opts.key?(:visible) ? opts[:visible] : true
element = page.all(selector, visible:).first
expect(element.value).to eq(opts[:with]) if element && opts.key?(:with)
have_selector selector, visible:
end
def select_by_value(value, options = {})
from = options.delete :from
page.find_by(id: from).find("option[value='#{value}']").select_option
end
def flash_message
find('.flash .msg', visible: false).text(:all).strip
end
def handle_js_confirm(accept = true)
page.execute_script "window.confirm = function(msg) { return #{!!accept}; }"
yield
end
def set_i18n_locale(locale = 'en')
page.execute_script("I18n.locale = '#{locale}'")
end
def get_i18n_locale
page.evaluate_script("I18n.locale;")
end
def get_i18n_translation(key = nil)
page.evaluate_script("I18n.t('#{key}');")
end
# http://www.elabs.se/blog/53-why-wait_until-was-removed-from-capybara
# Do not use this without good reason. Capybara's built-in waiting is very effective.
def wait_until(secs = nil)
require "timeout"
Timeout.timeout(secs || Capybara.default_max_wait_time) do
sleep(0.1) until value = yield
value
end
end
def within_row(num, &)
within("table.index tbody tr:nth-child(#{num})", &)
end
def select2_select(value, options)
open_select2("#s2id_#{options[:from]}")
if options[:search]
page.find(:xpath, '//body')
.find(:css, '.select2-drop-active input.select2-input, ' \
'.select2-dropdown-open input.select2-input')
.set(value)
end
page.find(:xpath, '//body')
.find(:css, '.select2-drop-active .select2-result-label',
text: options[:select_text] || value)
.click
expect(page).to have_select2 options[:from], selected: options[:select_text] || value
end
def open_select2(selector)
page.find(selector).scroll_to(page.find(selector))
.find(:css, '.select2-choice, .select2-search-field').click
end
def close_select2
# A click outside the select2 container should close it
page.find(:css, 'body').click
end
def click_on_select2(value, options)
find("#s2id_#{options[:from]}").click
find(:css, ".select2-result-label", text: options[:select_text] || value).click
end
def tomselect_open(field_name)
page.find("##{field_name}-ts-control").click
end
def tomselect_multiselect(value, options)
tomselect_wrapper = page.find("[name='#{options[:from]}']").sibling(".ts-wrapper")
tomselect_wrapper.find(".ts-control").click
tomselect_wrapper.find(:css, '.ts-dropdown.multi .ts-dropdown-content .option',
text: value).click
end
def tomselect_search_and_select(value, options)
tomselect_wrapper = page.find("[name='#{options[:from]}']").sibling(".ts-wrapper")
tomselect_wrapper.find(".ts-control").click
# Use send_keys as setting the value directly doesn't trigger the search
tomselect_wrapper.find(:css, '.ts-dropdown input.dropdown-input').send_keys(value)
tomselect_wrapper.find(:css, '.ts-dropdown .ts-dropdown-content .option', text: value).click
end
def tomselect_select(value, options)
tomselect_wrapper = page.find("[name='#{options[:from]}']").sibling(".ts-wrapper")
tomselect_wrapper.find(".ts-control").click
tomselect_wrapper.find(:css, '.ts-dropdown .ts-dropdown-content .option', text: value).click
end
def request_monitor_finished(controller = nil)
page.evaluate_script("#{angular_scope(controller)}.scope().RequestMonitor.loading == false")
end
def fill_in_tag(tag_name, selector = "tags-input .tags input")
expect(page).to have_selector selector
find(:css, selector).click
find(:css, selector).set "#{tag_name}\n"
expect(page).to have_selector ".tag-list .tag-item span", text: tag_name
end
private
# Takes an optional angular controller name eg: "LineItemsCtrl",
# otherwise finds the first object in the DOM with an angular scope
def angular_scope(controller = nil)
element = controller ? "[ng-controller=#{controller}]" : '.ng-scope'
"angular.element(document.querySelector('#{element}'))"
end
end