mirror of
https://github.com/openfoodfoundation/openfoodnetwork
synced 2026-01-25 20:46:48 +00:00
The way we add items to the cart will change. Encapsulating that code in a common place will make the mobile ux work clearer and avoid merge conflicts. The waiting for background requests has also been improved and made more consistent which should make these specs more reliable.
173 lines
5.0 KiB
Ruby
173 lines
5.0 KiB
Ruby
module WebHelper
|
|
def self.included(base)
|
|
base.extend ClassMethods
|
|
end
|
|
|
|
module ClassMethods
|
|
# By default, Capybara uses a 30 s wait time, which is more reliable for CI, but too slow
|
|
# for TDD. Use this to make tests fail fast. Usage:
|
|
#
|
|
# describe "foo" do
|
|
# use_short_wait
|
|
# ...
|
|
# end
|
|
def use_short_wait(seconds = 2)
|
|
around { |example| Capybara.using_wait_time(seconds) { example.run } }
|
|
end
|
|
end
|
|
|
|
def have_input(name, opts = {})
|
|
selector = "[name='#{name}']"
|
|
selector += "[placeholder='#{opts[:placeholder]}']" if opts.key? :placeholder
|
|
|
|
element = page.all(selector).first
|
|
expect(element.value).to eq(opts[:with]) if element && opts.key?(:with)
|
|
|
|
have_selector selector
|
|
end
|
|
|
|
def fill_in_fields(field_values)
|
|
field_values.each do |key, value|
|
|
begin
|
|
fill_in key, with: value
|
|
rescue Capybara::ElementNotFound
|
|
find_field(key).select(value)
|
|
end
|
|
end
|
|
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', visible: false).text(:all).strip
|
|
end
|
|
|
|
def handle_js_confirm(accept = true)
|
|
page.execute_script "window.confirm = function(msg) { return #{!!accept}; }"
|
|
yield
|
|
end
|
|
|
|
def visit_delete(url)
|
|
response = Capybara.current_session.driver.delete url
|
|
click_link 'redirected' if response.status == 302
|
|
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
|
|
|
|
# Fetch the content of a script block
|
|
# eg. script_content with: 'my-script.com'
|
|
# Returns nil if not found
|
|
# Raises an exception if multiple matching blocks are found
|
|
def script_content(opts = {})
|
|
elems = page.all('script', visible: false)
|
|
|
|
elems = elems.to_a.select { |e| e.text(:all).include? opts[:with] } if opts[:with]
|
|
|
|
if elems.none?
|
|
nil
|
|
elsif elems.many?
|
|
raise "Multiple results returned for script_content"
|
|
else
|
|
elems.first.text(:all)
|
|
end
|
|
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 select2_select(value, options)
|
|
id = options[:from]
|
|
options[:from] = "#s2id_#{id}"
|
|
targetted_select2(value, options)
|
|
end
|
|
|
|
# Support having different texts to search for and to click in the select2
|
|
# field.
|
|
#
|
|
# This overrides the method in Spree.
|
|
def targetted_select2_search(value, options)
|
|
page.execute_script %{$('#{options[:from]}').select2('open')}
|
|
page.execute_script "$('#{options[:dropdown_css]} input.select2-input').val('#{value}').trigger('keyup-change');"
|
|
select_select2_result(options[:select_text] || value)
|
|
end
|
|
|
|
def multi_select2_select(value, options)
|
|
find("#s2id_#{options[:from]}").find('ul li.select2-search-field').click
|
|
select_select2_result(value)
|
|
end
|
|
|
|
def open_select2(selector)
|
|
page.execute_script "jQuery('#{selector}').select2('open');"
|
|
end
|
|
|
|
def close_select2(selector)
|
|
page.execute_script "jQuery('#{selector}').select2('close');"
|
|
end
|
|
|
|
def select2_search_async(value, options)
|
|
id = find_label_by_text(options[:from])
|
|
options[:from] = "#s2id_#{id}"
|
|
targetted_select2_search_async(value, options)
|
|
end
|
|
|
|
def targetted_select2_search_async(value, options)
|
|
page.execute_script %{$('#{options[:from]}').select2('open')}
|
|
page.execute_script "$('#{options[:dropdown_css]} input.select2-input').val('#{value}').trigger('keyup-change');"
|
|
select_select2_result_async(value)
|
|
end
|
|
|
|
def select_select2_result_async(value)
|
|
while page.has_selector? "div.select2-searching"
|
|
return if page.has_selector? "div.select2-no-results"
|
|
|
|
sleep 0.2
|
|
end
|
|
page.execute_script(%{$("div.select2-result-label:contains('#{value}')").mouseup()})
|
|
end
|
|
|
|
def accept_js_alert
|
|
page.driver.browser.switch_to.alert.accept
|
|
end
|
|
|
|
def angular_http_requests_finished(controller = nil)
|
|
page.evaluate_script("#{angular_scope(controller)}.injector().get('$http').pendingRequests.length == 0")
|
|
end
|
|
|
|
def request_monitor_finished(controller = nil)
|
|
page.evaluate_script("#{angular_scope(controller)}.scope().RequestMonitor.loading == false")
|
|
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
|
|
|
|
def wait_for_ajax
|
|
wait_until { page.evaluate_script("$.active") == 0 }
|
|
end
|
|
end
|