mirror of
https://github.com/openfoodfoundation/openfoodnetwork
synced 2026-01-26 20:56:48 +00:00
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.
135 lines
4.3 KiB
Ruby
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
|