germsvel / phoenix_test

PhoenixTest provides a unified way of writing feature tests -- regardless of whether you're testing LiveView pages or static (non-LiveView) pages.
https://hex.pm/packages/phoenix_test
MIT License
171 stars 22 forks source link

Error when hidden field is updated by server #105

Closed totaltrash closed 2 weeks ago

totaltrash commented 2 months ago

I'm getting an error when updating a second field in a nested form:

session
# This works
|> fill_in("First Name", with: "Some")
# This fails:
|> fill_in("Last Name", with: "Contact")
** (ArgumentError) value for hidden "form[involved][0][_touched]" must be one of ["_form_type,_persistent_id,_touched,contact,involved_how"], got: "_form_type,_touched,contact"
code: |> fill_in("Last Name", with: "Contact")
     stacktrace:
       (phoenix_live_view 0.20.17) lib/phoenix_live_view/test/live_view_test.ex:1102: Phoenix.LiveViewTest.call/2
       (phoenix_test 0.3.1) lib/phoenix_test/live.ex:172: PhoenixTest.Live.fill_form/4
       test/features/enquiry_test.exs:32: (test)
totaltrash commented 2 months ago

The _touched field is populated by inputs_for and I've been unable to replicate this with a test unfortunately.

I'm not sure if this is PhoenixTest issue... but I can work around the issue with unwrap and filling the form manually. But, it's kinda weird it's only happening on the second field getting filled in (regardless of what order the fill_ins occur)

totaltrash commented 2 months ago

I've reproduced the issue here: https://github.com/totaltrash/phoenix_test_playground.

The issue isn't about nested forms, it's about hidden fields that are updated during a phx-change event. The pertinent bits are:

https://github.com/totaltrash/phoenix_test_playground/blob/master/test/my_app_web/features/smoke_test.exs

  test "admin can create user", %{conn: conn} do
    conn
    |> visit("/users/new")
    |> fill_in("Name", with: "Aragorn") # <- this works fine
    |> fill_in("Email", with: "aragorn@gondormail.com") # <- this fails
    |> click_button("Save")
    |> assert_has("table", text: "Aragorn")
  end

The second form change fails with:

** (ArgumentError) value for hidden "user[secret]" must be one of ["z"], got: ""
code: |> fill_in("Email", with: "aragorn@gondormail.com")
     stacktrace:
       (phoenix_live_view 1.0.0-rc.6) lib/phoenix_live_view/test/live_view_test.ex:1102: Phoenix.LiveViewTest.call/2
       (phoenix_test 0.3.1) lib/phoenix_test/live.ex:121: PhoenixTest.Live.fill_form/4
       test/my_app_web/features/smoke_test.exs:8: (test)

Which appears to be LiveViewTest complaining about changing the value of a hidden as if it was a normal text field (not through the hidden_fields in render_change)

The hidden field is changed here:

https://github.com/totaltrash/phoenix_test_playground/blob/38ca2a4a0825cf2eb655b8194760c5319eff3de7/lib/my_app_web/live/user_live/form_component.ex#L45

I think PhoenixTest is building the form data correctly the first form change (passing the hidden field to render_change), but on the second fill_in, it's just adding the hidden field to the rest of the params

germsvel commented 2 months ago

@totaltrash I'm not sure I understand the problem enough to reproduce it. I see in the playground you shared (thanks for sharing that by the way!) that the form has a hidden "Secret" field with that you seem to update in the validate handle event.

But I don't really get what you're trying to accomplish or how to reproduce this. Any more info you can provide?

totaltrash commented 2 months ago

Yeah hopefully!

So, I noticed the issue originally with a nested form that was built using AshPhoenix.Form. AshPhoenix.Form implements Phoenix.HTML.FormData and adds a couple of fields to the form that are rendered by inputs_for as hidden fields. One of these fields are used to track which nested forms have been updated during the lifecycle of the form (_touched). As I was filling in the form with phoenix_test, an argument error would occur (which appears to be an error Phoenix.LiveViewTest raises when you attempt to set a value on a hidden field in a test).

The playground I shared reproduces the error without the AshPhoenix dependency. Basically, any change to a hidden field on phx-change fails - but only on the second attempt at filling in a field (the first attempt works fine because the hidden field has not yet been changed).

Note, the test in the playground doesn't itself try to update a hidden field, the change is happening on the server.

germsvel commented 2 weeks ago

@totaltrash sorry for the delay here. Thanks so much for the phoenix playground! I see now where we're having issues... but now I have to figure out how to solve it. Just wanted to let you know I'm looking into it.