Replies: 5 comments 14 replies
-
OK, continuing to answer my own questions.... If you do want to do it via Javascript, I discovered that the the tom-select object is available on the property So in straight Javascript, you can do something like:
So, translated to ruby capybara and rspec, one approach: # ./spec/support/rspec_helper/tom_select.rb
module RspecHelper
module TomSelect
# A helper for Capyabara tests that need to set values from a tom-select.js input.
#
# This is a really hacky approach using execute_javascript, but it works. Not sure if there's
# a better way, we could try actually interacting with the on-screen tom-select-provided UI,
# but we're taking the easy way out for now.
#
# @param option_id can be the `id` value of an option in the select, OR for select multiple inputs,
# can be an array of such IDs.
#
# @example tom_select("#select_id", option_id: "2")
# @example tom_select("#select_id", option_id: ["2", "10"]) # `multiple` input.
def tom_select(select_selector, option_id:)
js_str = %Q(document.querySelector("#{select_selector}").tomselect.setValue(#{option_id.inspect}))
execute_script(js_str)
end
end
end # spec_helper.rb
require './spec/test_support/rspec_helper/tom_select'
config.include RspecHelper::TomSelect, type: :system So... this works! Using Capybara/selinium The other way to do it, that would be more "legit" Capybara/selinium, would be to try to write your script to actually interact with the on-screen UI provided by tom-select. If anyone happens to see this and has done that, please share what worked. Or curious if anyone has an opinion the best way to do this. |
Beta Was this translation helpful? Give feedback.
-
Thanks for sharing your learnings! Because it requires knowledge of some of the inner workings of tom-select, it would be better in the long run to create helpers and custom matchers, similar to what select2 has: https://github.com/Hirurg103/capybara_select2 (for example). As far as I can tell, still nothing like this exists yet. Hopefully someone (maybe myself) will get to do it one day... |
Beta Was this translation helpful? Give feedback.
-
For anyone landing here because this stopped working, check out f5218a7 and set the refresh timeout to 0. |
Beta Was this translation helpful? Give feedback.
-
There is also a simpler way to fill it with recent capybara: |
Beta Was this translation helpful? Give feedback.
-
This is what worked for me: class ApplicationSystemTestCase < ActionDispatch::SystemTestCase
...
setup do
Capybara.app_host = "http://localhost" # so auth cookies are passed with fetch request vs. 127.0.0.1
end
def tom_select(value, from:)
fill_in(from, with: value, visible: false).send_keys(:return)
first('.ts-dropdown .ts-dropdown-content .option', text: /#{Regexp.quote(value)}/i).click
end
...
end Also, I set refreshThrottle and loadThrottle to zero in test env |
Beta Was this translation helpful? Give feedback.
-
I do automated testing with capybara (Rails app). I think similar issues would occur using other uses of selenium, but can't say.
Does anyone have a good solution to automating interaction with a tom-select-covered input?
Googling around, there are various solutions offered for
selectize
... of various quality, some of them seem wrong, or outdated and no longer work with contemporary selenium, which looks like it's gotten pickier about forbiding interaction with non-visible elements.Some of them might not exactly apply to tom-select anymore even if they might work for selectize. Some of them seem to use the selectize JQuery-style API to use Javascript to set a value for the selectize input, like
selectNode.selectize.setValue
... that I don't think there's an equivalent way for Javascript to get acess to the tom-select object from a select node?With all the reasons a given solution found on google might not work... I am going through what I can find to try to figure out what might work, but was wondering if anyone had already figured it out and had a good solution.
Beta Was this translation helpful? Give feedback.
All reactions