Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Discussion: live_select LiveView component testing #37

Open
lockhinator opened this issue Sep 7, 2023 · 2 comments
Open

Discussion: live_select LiveView component testing #37

lockhinator opened this issue Sep 7, 2023 · 2 comments

Comments

@lockhinator
Copy link

First off I would like to say great job on the library, it is extremally useful.

I had a question around testing when being used within a LiveView component. While the directive of phx-target={@myself} works on the actual <.live_select /> element when being used in the live environment, when running this in a test environment the event messages are sent to the parent LiveView.

I in no way think this is a short coming of the library in anyway and understand this is something that still needs to be fleshed out in LiveView testing methodologies but was wondering if anyone has come up with a clever solution for this or if at the moment most are just not testing the live_select component in their views and are instead direct testing their components.

as an example:

Component:

defmodule MyAppWeb.PageLive.FormComponent do
  use MyAppWeb, :live_component

  def render(assigns) do
    ~H"""
      <.simple_form for={@form} id="page-form" phx-target={@myself} phx-change="validate" phx-submit="save">
        <.input field={@form[:name]} type="text" label="Name" />
        <.live_select field={@form[:cities]} phx-target={@myself} placeholder="Search Cities..." mode={:tags} />
        <:actions>
          <.button phx-disable-with="Saving...">Save Cities</.button>
        </:actions>
      <./simple_form>
    """
  end

  ...

  @impl true
  def handle_event("live_select_change", %{"field" => "cities_tags", "text" => text, "id" => live_select_id}, socket) do
    ...
    send_update(LiveSelect.Component, id: live_select_id, options: result)
    {:noreply, socket}
  end
end

Test:

  ... include the helper (with a few minor modifications to selectors) from this lib since it makes life much easier

  test "can save cities", %{conn: conn} do
    {:ok, new_live, _html} = live(conn, ~p"/cities/new")

    type(new_live, "ala",
        component: "#cities_live_select_component",
        field: "cities_tags"
      )

    select_nth_option(new_live, 1,
        method: :key,
        component: "#cities_live_select_component"
      )

    assert new_live
             |> form("#page-form",
               cause: %{
                 "name" => "A Fake Title Name"
               }
             )
             |> render_submit()
  end

This results in the following error which you won't get in when using this from the browser:
Assume MyAppWeb.PageLive is the LiveView which is hosting this in modal or something similar.

  ** (UndefinedFunctionError) function MyAppWeb.PageLive.handle_event/3 is undefined or private

If anyone has any ideas on how to test in the scenario or any pointers it would be very much appreciated.

@lockhinator lockhinator changed the title Discussion: live_select LiveView Component Testing Discussion: live_select LiveView component testing Sep 7, 2023
@maxmarcon
Copy link
Owner

I in no way think this is a short coming of the library in anyway and understand this is something that still needs to be fleshed out in LiveView testing methodologies but was wondering if anyone has come up with a clever solution for this

LiveView test functions (such as render_click) honor the phx-change attribute. This is not the problem here.

Are the type and select_nth_option functions I see in your code the same functions I use in my test suite? If so, you probably see the error when calling type. type needs to know which component it should pass the live_select_change event to.

Try to pass the parent to type:

type(new_live, "ala",
        component: "#cities_live_select_component",
        parent: "#page-form",
        field: "cities_tags"
      )

But beware that you need a phx-hook (name doesn't matter) set in #page-form for this to work, because type uses a render_hook internally.

More importantly, these functions are not a public API and you're not supposed to be using them unless you're working on the LiveSelect code itself.

Which leads me to the most important question: what are you testing here? It seems to me that you're testing live_select component itself, which you shouldn't and don't need to (it's already tested).

A minor point:

 assert new_live
             |> form("#page-form",
               cause: %{
                 "name" => "A Fake Title Name"
               }
             )
             |> render_submit()

This assertion is meaningless and will always pass

@pau-riosa
Copy link

pau-riosa commented Jan 18, 2024

It seems I encounter this one. I have a question

When live-select is inside the component, how can I test the I have selected the option/s that I've search?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants