Testing: "no push command found within JS commands"

Question:

Can I create a live view test using JS.patch/1 without having to push an event to the server, in the same way as the phoenix component’s <link patch={@patch} /> seems to do?

More details below.

Using:

Phoenix 1.7 (components generated at 1.7rc1)

Example:

# In my heex template - JS is used on <option> and <a> tag's phx-click attribute.
<.my_component class="example" on_select={JS.patch(@path)} />

# In my test
assert index_live |> element(".example a") |> render_click() =~ "Title"

I am doing it this way because my component generates a menu with a link (desktop) and a select option (mobile) which need to work the same way - so the JS is used on both.

Outcome of test: “[error] … no push command found within JS commands …”

Updated Example:

# In my heex template
<.my_component on_select={JS.patch(@path) |> JS.push("some_event")} />

Outcome of test: genserver crashes because I am not handling the event.

I understand why this is not working and what live view can and cannot test.

However, <.link patch={@path} /> seems to work without sending an event to the server.

# phoenix_live_view/lib/phoenix_component.ex, line: 2483
# ...
  def link(%{patch: to} = assigns) when is_binary(to) do
    ~H"""
    <a
      href={@patch}
      data-phx-link="patch"
      data-phx-link-state={if @replace, do: "replace", else: "push"}
      {@rest}
    ><%= render_slot(@inner_block) %></a>
    """
  end
# ...

It seems like the data- attributes are only being used in javascript. But the same render_click test used above seems to be able to understand the patch. Is there any way to replicate this using the JS module?

Thanks in advance and thanks to everyone involved in creating this awesome framework!

4 Likes

Did you come up with anything for this that you might be able to share?

1 Like