live_select
live_select copied to clipboard
Change form fields from hidden to text for liveview testing ease of use
I can't use the normal liveview testing functions when using this library because of the hidden inputs. I would have to modify all my tests to populate the form field in a different way when using live_select. If we make the form fields type text and add a hidden class to them, then the tests will work without modification.
Example, I have a form that is using the live_select component for an org_id on a user:
In current library state with hidden form fields:
create_attrs = %{
org_id: 1,
first_name: "John",
last_name: "Doe",
email: "[email protected]",
phone_number: "1234567890"
}
assert index_live
|> form("#user-form", user: Map.delete(create_attrs, :org_id))
|> render_submit(%{user: %{org_id: create_attrs[:org_id]}})
Using my PR, we can keep the tests the way they come using phoenix generators:
create_attrs = %{
org_id: 1,
first_name: "John",
last_name: "Doe",
email: "[email protected]",
phone_number: "1234567890"
}
assert index_live
|> form("#user-form", user: create_attrs)
|> render_submit()
Hi and thanks for giving some thought to this. Having to account for a hidden input is in fact not ideal when writing tests, I agree.
However, your solution only works for folks who use tailwindcss and have a hidden class defined. For all the others the text input will be visible, which we don't want.
One could use inline css to hide the input, but inline css is forbidden under certain CSP settings.
I'm open to suggestions on alternative ways to make this work. So far, I haven't thought much about it to be honest.
Thanks
workaround to make your test work without having to pass hidden inputs' values separately:
create_attrs = %{
org_id: 1,
first_name: "John",
last_name: "Doe",
email: "[email protected]",
phone_number: "1234567890"
}
Phoenix.LiveView.send_update(
view.pid, # live = your test's live view, returned by Phoenix.LiveViewTest.live/2
LiveSelect.Component,
%{id: live_select_id, value: create_attrs.org_id}
# `live_select_id` is the id of your live select input component
# (you can pass it explicitly, otherwise, one is generated automatically from form + field name)
)
assert index_live
|> form("#user-form", user: create_attrs)
|> render_submit()
The call to Phoenix.LiveView.send_update/3 simulates the user interaction by programmatically set the selection in the LiveSelect component.
Maybe still not ideal, but I think it's the best we can do if we want to keep our tests within LV/Elixir (i.e. not running JS in an e2e test)