I’m trying to test in a LiveViewTest
that an input field is cleared after form submission.
There is only one text input that doesn’t need validation so I’m not bothering with a changeset (though I do still notice this problem with a changeset) and am controlling the field like so:
#...
def mount(_params, _session, socket) do
# ...
{:ok, assign(socket, :message_content, ""}
end
def render(assigns) do
~H"""
<.simple_form let={f} for={:message} ... phx-change="update-input-text" phx-submit="save">
<.input field={{f, :content}} value={@input_text} />
<button>Submit</button>
</.simple_form>
"""
end
def handle_event("update-input-text", %{"message" => message_params}, socket) do
{:noreply, assign(socket, :message_content, message_params["content"]}
end
def handle_event("save", %{"message" => message_params}, socket) do
# ...
# successful submit:
{:noreply, assign(socket, :message_content, "")}
end
# ...
Then I have this test (this is all simplified—I’m using better selectors and whatnot):
test "clears output after sending messages", %{conn: conn, room: room} do
{:ok, lv, _html} = live(conn, ~p"/chat/#{room}")
lv
|> form("form", %{"message" => %{"content" => "Some message"}})
|> render_submit()
refute lv
|> element("input")
|> render() =~ "Some message"
end
The problem is is that if I change the "save"
handler to simply return {:noreply, socket}
(ie, it’s no longer resetting the message_content
assign,) the test still passes. I certainly confirmed in the browser that this is not what’s happening—the text stays in the box. Possibly weirder still is that if I change that line to {:noreply, assign(socket, :message_content, "Some message"}
then the test picks that up and fails.
I’ve also tried this with “raw” <form>
and <input>
elements and it’s the same deal.
It’s my understanding that render_submit/2
simply triggers the phx-submit
action for the form. Anyone know what’s going on here?