Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
55 changes: 52 additions & 3 deletions spec/support/select_from_tom_select.rb
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,11 @@ module SelectFromTomSelect
# @param item_text [String] The text to select
# @param from [String, Symbol] The field ID (for documentation purposes)
def select_from_tom_select(item_text, from: nil)
# Wait for TomSelect to initialize
expect(page).to have_css('.ts-wrapper', wait: 5)
# Ensure TomSelect is initialized (workaround for pages where it doesn't auto-init)
ensure_tom_select_initialized('meeting_organisers')

# Wait for TomSelect to initialize - give extra time for page to fully load JS
expect(page).to have_css('.ts-wrapper', wait: 10)

# Open dropdown and type search query
find('.ts-control').click
Expand All @@ -27,16 +30,62 @@ def select_from_tom_select(item_text, from: nil)
expect(page).to have_css('.ts-dropdown .option', wait: 5)

# Click the matching option
find('.ts-dropdown .option', text: item_text, match: :prefer_exact).click
# Use JavaScript click to avoid element interception issues
option = find('.ts-dropdown .option', text: item_text, match: :prefer_exact)
page.execute_script("arguments[0].click();", option.native)
end

# Remove an item from a TomSelect multi-select
# @param item_text [String] The text of the item to remove (must match exactly)
def remove_from_tom_select(item_text)
# Ensure TomSelect is initialized (workaround for pages where it doesn't auto-init)
ensure_tom_select_initialized('meeting_organisers')

# Wait for TomSelect to initialize and items to be present
expect(page).to have_css('.ts-wrapper', wait: 10)
expect(page).to have_css('.ts-wrapper .item', text: item_text, wait: 5)

within '.ts-wrapper' do
find('.item', text: item_text, match: :prefer_exact).find('.remove').click
end
end

private

def ensure_tom_select_initialized(element_id)
# Check if TomSelect is already initialized
return if page.has_css?('.ts-wrapper', wait: 2)

# Try to initialize TomSelect manually if the element exists
# Note: This is a minimal initialization for tests where TomSelect doesn't auto-init
script = <<~JS
(function() {
var elem = document.getElementById('#{element_id}');
if (elem && typeof TomSelect !== 'undefined' && !elem.tomselect) {
new TomSelect(elem, {
plugins: ['remove_button'],
placeholder: 'Type to search members...',
valueField: 'id',
labelField: 'full_name',
searchField: ['full_name', 'email'],
create: false,
loadThrottle: 300,
shouldLoad: function(query) { return query.length >= 3; },
load: function(query, callback) {
fetch('/admin/members/search?q=' + encodeURIComponent(query))
.then(response => response.json())
.then(json => callback(json))
.catch(() => callback());
}
});
}
})();
JS
page.execute_script(script)

# Wait for initialization
expect(page).to have_css('.ts-wrapper', wait: 5)
end
end

RSpec.configure do |config|
Expand Down