Softknobs
Hi,
I cannot figure out how to test some LiveComponents simulating the actual events that would be sent by the user.
In my case, the LiveComponent is not visible when the parent LiveView is rendered. I guess this is where the problem lies but it is required. To test my Liveview, I do:
{:ok, view, html} = live(conn, "/myview")
Doing the action to show the LiveComponent works:
render_click(view, "show", %{"param1" => "value1", "param2" => "value2"})
but I can only test the initial state of the LiveComponent because render_click only renders the html.
For that mater, I can’t use find_child to get the LiveComponent view because it is always nil:
find_child(view, "component_id") # returns nil
So I cannot send other render_* events to the LiveComponent.
It other LiveComponents I created, I used send to change the state in the parent view. This did work fine but in this case the rendering of LiveComponent is not handled in the same way and it would feel wrong to add an handle_info only for testing.
The last thing I looked into is render_component. Again, render_component seems to only render a definite state of the LiveComponent and that is not what I am looking for. Sure, testing that all different component states render what is expected is fine but there is no guarantee that the user actions on the UI set the component in the right state. Moreover, such tests would be hard to maintain: I want to test what is rendered when the user makes some actions, no mater what the implementation is (ie. the assigns state).
There are also other solutions like rendering the LiveComponent and hidding it with css but I am not confortable doing such design decisions only to solve testing problems.
I may not be familiar with all the tools available for testing and maybe I am missing something, that’s why I am asking for help here… Thanks!
Trending in Questions
Other Trending Topics
Categories:
Sub Categories:
Forums
Popular Tags
- #ecto
- #liveview
- #troubleshooting
- #learning-elixir
- #library
- #deployment
- #erlang
- #testing
- #genserver
- #mix
- #absinthe
- #remote-other
- #otp
- #plug
- #how-to-question
- #macros
- #postgres
- #elixirconf
- #channels
- #exunit
- #discussion
- #code-sync
- #podcasts
- #javascript
- #onsite
- #dialyzer
- #docker
- #authentication
- #umbrella
- #full-time-contract
- #podcasts-by-brainlid
- #ecto-query
- #ai
- #elixirconf-us
- #blog-post
- #elixir-ls
- #phoenix_html
- #iex
- #graphql
- #genstage
- #websockets
- #supervisor
- #advent-of-code
- #distillery
- #processes
- #api
- #forms
- #hex
- #security
- #metaprogramming










Showing Posts 1 to 10- Show Best Posts
- Show All (oldest first)
- Show All (newest first)
phasnox
I have a similar problem where I want to test a nested live_view that does not mount in router.(with mount :not_mounted_in_router)
I guess those are the caveats of the bleeding edge (sigh)
shamanime
What is your exact issue and what approach are you taking?
Recent LV updates have improved a lot the test tooling.
Here’s a snippet to test LV with components that aren’t available at initial rendering:
phasnox
Hey @shamanime !
Here is what I have:
A “normal” get view like this:
routex.ex
In some_view.html.eex template
sidebar_view_live.ex
So 2 questions:
Thanks for taking the time man!
shamanime
1: Instead of using
liveto “mount” your LV in testing you can use live_isolated/3.2: The snippet I wrote in the other post should work. After you mount your menu LV you can interact with it using the
elementandrender_helpers to reproduce the steps taken for the component to display and to interact with it. This will work as an integration test: you won’t update the LV assigns directly, instead you’ll mimic what the user does and assert that your LV/Component is updating correctly.So basically after your router renders and mounts the LV you’ll end with this structure:
When you use
live_isolatedyou’ll get only this chunk:And then you can interact with it by passing CSS selectors to
elementand using therender_functions to trigger events in your LV and components.phasnox
@shamanime What about multi-step actions?
Lets say I want to test something like this:
The problem is I have the live component hidden, and only shown after the user clicks the menu opener.
shamanime
The
render_helpers returns HTML so they can’t be piped toelement, you need to do it step by step like this:Softknobs
Thanks @shamanime for your input. I haven’t had the occasion to write tests in LV 0.13 yet but it looks the original problem remains.
As @phasnox mentionned the requirement here is to test a nested LiveComponent.
Your last example pinpoints my original problem. The problem is that
#filter-inputdoes not exist in theviewbecause it is only rendered when#menu_openeris clicked. @phasnox last example shows exactly what we are trying to test but that can’t be done because, as you mention it,render_returns HTML and not aviewthat could be used to do additionnalrender_clickcalls.There is no way to get a
viewstruct that would be the result of therender_clickon#menu_opener. Hereviewonly contains original code of the LiveView.Since
live/2only works for LiveViews, as doeslive_isolated/3, they cannot be used to test LiveComponents. And there seems to be no way to test UI events on LiveComponents outside of a LiveView.At this point it looks that it is not possible to test LiveComponents by simulating the user actions on LiveComponents that are not available when the LiveView is created.
shamanime
Hello!
There are no issues testing live components. My snippet shows how to test them.
I work with an app that has this exact issue you’re describing and I am able to test the component.
Have you tried adding tests as I mentioned?
You need to get them to show by interacting with your LiveView and from there you interact with your component.
Let me expand it so you are sure I understand what you’re saying:
shamanime
To make this more clear I’ve setup a repo here: GitHub - shamanime/phx_live_component_test: Sample app to show how to test live components. · GitHub
It is a fresh Phoenix app created with
--livewith one LiveView that conditionally displays/renders a component.I’ve used the same snipped I posted here to test the component: Add LV with conditional component and test LV interaction · shamanime/phx_live_component_test@a3b600b · GitHub
Softknobs
Thanks for the detailed answer @shamanime. To be honest, I did not try the example you gave because it was equivalent to what I was doing, without success, before posting this two months ago.
I don’t have the exact code that caused the initial problem anymore and I upgraded my LV version several times since then. Anyway, it would make no sense trying to reproduce the problem now when your solution does work with current LiveView version.
Thanks for taking the time to answer.