phoenixframework / phoenix_live_view

Rich, real-time user experiences with server-rendered HTML
https://hex.pm/packages/phoenix_live_view
MIT License
6.12k stars 917 forks source link

phx-update="append" property in nested liveview fails in tests #566

Closed ADolhov closed 4 years ago

ADolhov commented 4 years ago

Environment

Elixir 1.9.1 (compiled with Erlang/OTP 22)

Actual behavior

nested liveview with phx-update="append" property in container and rendered via live_render from parent liveview template works as expected on dev, but fails in parent liveview test with phx-update append/prepend containers require an ID error on render_click action, despite container has an ID (without phx-update="append" property test passes)

         ** (ArgumentError) phx-update append/prepend containers require an ID
             (phoenix_live_view) lib/phoenix_live_view/test/dom.ex:245: Phoenix.LiveViewTest.DOM.phx_update_children/2
             (phoenix_live_view) lib/phoenix_live_view/test/dom.ex:192: Phoenix.LiveViewTest.DOM.apply_phx_update/3
             (floki) lib/floki/traversal.ex:7: Floki.Traversal.traverse_and_update/2
             (floki) lib/floki/traversal.ex:9: Floki.Traversal.traverse_and_update/2
             (phoenix_live_view) lib/phoenix_live_view/test/dom.ex:145: Phoenix.LiveViewTest.DOM.patch_id/3
             (phoenix_live_view) lib/phoenix_live_view/test/client_proxy.ex:353: Phoenix.LiveViewTest.ClientProxy.patch_view/3
             (phoenix_live_view) lib/phoenix_live_view/test/client_proxy.ex:493: anonymous fn/5 in Phoenix.LiveViewTest.ClientProxy.recursive_detect_added_or_removed_children/3
             (elixir) lib/enum.ex:1948: Enum."-reduce/3-lists^foldl/2-0-"/3
             (phoenix_live_view) lib/phoenix_live_view/test/client_proxy.ex:443: Phoenix.LiveViewTest.ClientProxy.detect_added_or_removed_children/3
             (phoenix_live_view) lib/phoenix_live_view/test/client_proxy.ex:412: Phoenix.LiveViewTest.ClientProxy.render_reply/3
             (phoenix_live_view) lib/phoenix_live_view/test/client_proxy.ex:219: Phoenix.LiveViewTest.ClientProxy.handle_info/2
             (stdlib) gen_server.erl:637: :gen_server.try_dispatch/4
             (stdlib) gen_server.erl:711: :gen_server.handle_msg/6
             (stdlib) proc_lib.erl:249: :proc_lib.init_p_do_apply/3

Expected behavior

tests should pass

josevalim commented 4 years ago

Can you please provide a sample application or a failing test to our suite that reproduces the error? It would make our lives much much easier, thank you!

ADolhov commented 4 years ago

okie, will try to

snewcomer commented 4 years ago

I have one. Been hanging my head on this one for too long so thank you for the issue! ;)

https://github.com/snewcomer/live-comment/blob/master/test/live_comment_web/live/comment_test.exs

ADolhov commented 4 years ago

thanks guys, you are the best!

ADolhov commented 4 years ago

i realized, that Phoenix.LiveView live_render within parent view template simply doesnt render nested view in tests (using Phoenix.LiveViewTest isolated_live), only creates the container for nested view template

snewcomer commented 4 years ago

https://github.com/phoenixframework/phoenix_live_view/commit/234c1108429c86cd9a6057fdac2aaf7de62deba7

This was a small reproduction I started on as well with DOM.patch_id

chrismccord commented 4 years ago

Fixed on master. @snewcomer @ADolhov please give it a try and report back. Thanks!

pojiro commented 4 years ago

I had same problem in tests, but now it works with master branch. Thanks!

StanBright commented 4 years ago

I've been wrestling with issue for some time now and cannot come up with a working version. I'm using the latest version of LiveView as of today - 0.14.5.

This is the relevant code in ".html.leex":

  <%= content_tag(:ul, id: "messages", phx_update: "append") do %>
    <%= for msg <- @messages do %>
      <li id="<%= msg.id %>">
        <strong><%= msg.user %></strong>:
        <%= msg.text %>
      </li>
    <% end %>
  <% end %>

It works as expected in Dev, yet fails in tests with:

setting phx-update to "append" requires setting an ID on each child. No ID was found on:

             (phoenix_live_view 0.14.5) lib/phoenix_live_view/test/dom.ex:336: anonymous fn/3 in Phoenix.LiveViewTest.DOM.apply_phx_update_children_id/2

The test code is:

test "default mount, sending and receiving a message", %{conn: conn} do
    {:ok, view, html} = live(conn, "/chat")
    assert html =~ "No messages yet"

    message = %Message{text: "Alf loves cats", user: "John", id: :os.system_time()}
    send(view.pid, {:message, message})
    assert render(view) =~ "Alf loves cats"
end

Do you think I'm missing something in the test setup?