filip-rybczynski

filip-rybczynski

Testing patch navigation triggered by the Phoenix link component in LiveViewTest

Hello!

I’m still a newcomer to Elixir and Phoenix, I’ve only started using them early this year. So asking kindly for understanding if the question I ask turns out to be trivial :sweat_smile:

The app I’m now working on in my project has several buttons which serve as links to patch the current LiveView (which results in UI changes, e.g. tab change in a menu). In its simplest form, the pattern is as follows:

<.link patch={~p(/users/#{@id}/edit)}>
  <.button>
    Edit
  </.button>
</.link>

The issue I’m currently facing is how to properly test such components - specifically, how to test that pressing this link will result in a patch as expected. Basically, I’d like to test the following series of events: (1) open view → (2) assert some html → (3) click link → (4) assert patch → (5) assert some different html. So step #3 is where I’m currently stuck at.

render_click won’t do in this case, since the Phoenix.Component.link/1 component does not have a phx-click attribute. Looking through the Phoenix.LiveViewTest documentation, I didn’t find anything that seems to work specifically for links.

Of course, the two less-than-satisfying options that come to mind now are:

  1. Not test interacting with the link directly and just simulate the resulting patch with render_patch/2 (seems like this reduces test reliability since the patch link is dynamic, dependent on assigns)
  2. Replace all instances of the above pattern with regular buttons with phx-click, and trigger the patch in the event handler (much better option from test reliability perspective, but modifying app code solely for testing purposes is probably not ideal, unless necessary)

But before I go with either option I wanted to ask here - is there any way to test patch navigations triggered by Phoenix link components in LiveViewTest that I’m missing?

Marked As Solved

sodapopcan

sodapopcan

Hello and welcome to Elixir Forum!

render_click should absolutely work on a <.link> component. Are you using element first?

lv
|> element("#my-link")
|> render_click()

assert_patch(lv, ~p"/users/#{@id}/edit")

assert render(lv) =~ "some html"

Also, just in case you weren’t aware, assuming you have a @user assign you don’t need to bother assigning @id as well, you can pass an Ecto struct to verified routes and it knows to use its id:

patch={~p(/users/#{@user}/edit)}

Also Liked

filip-rybczynski

filip-rybczynski

Hey, thanks for your response!

You are absolutely correct. I wrote this post because I kept getting a (paraphrasing) “element does not have phx-click attribute” error, but apparently it was because I had an issue with my selector in element - I used a straightforward id this time and now it works!

Of course, now that it works I noticed that there is the below clear paragraph in the docs:

If the element does not have a phx-click attribute but it is a link (the <a> tag), the link will be followed accordingly

So if I just read a bit more, I’d realize the issue was somewhere else, and not with render-click. Lesson for the future, I guess. Thanks for taking the time to help out!

As to your second point - I simplified the code snippet, we use @user.id, but I was actually unaware of the option of passing an Ecto struct to verified routes. I’d like to read more about it, is this what you’re referring to? Phoenix.Param — Phoenix v1.8.8

sodapopcan

sodapopcan

Yep! Derive Phoenix.Param to use another field. It’s legit to do @user.id too but it does make refactoring much easier if you ever want to switch to @user.slug or something.

Last Post!

sodapopcan

sodapopcan

Yep! Derive Phoenix.Param to use another field. It’s legit to do @user.id too but it does make refactoring much easier if you ever want to switch to @user.slug or something.

Where Next?

Popular in Questions Top

rms.mrcs
Hi, I need to transform a list of numbers into a map where the keys are the indexes and the values are the original values of the list. ...
New
vegabook
I’m brand new to Phoenix and I have stripped one of the demo applications to the bone. I just want to get an svg up on the screen. Here i...
New
vonH
In asking this question I am more interested about the expressiveness of the language itself and less concerned about the availability of...
New
Emily
I have VueJS GUIs with the project generated using Webpack. I have Elixir modules that will need to be used by the VueJS GUIs. I forese...
New
shijith.k
I am trying to start a new phoenix project with elixir 1.9, but mix phx.new does not work. It says that ** (Mix) The task "phx.new" could...
New
siddhant3030
Hi, I have to write a raw query for one of my project. But till now I have used ecto queries and don’t have much experience writing raw ...
New
svb
Hi! Currently I want to submit a form by pressing the Enter key. However, since my input field is of type “textarea” this is just adds a...
New

Other popular topics Top

vertexbuffer
Hello, can anybody help here..? I have a list of players and I what to delete an element, but every for loop the list is reverting to ori...
New
grych
Hi folks, Few months ago I have announced the proof-of-concept of the library to manipulate the browsers DOM objects directly from Elixi...
639 54006 488
New
Qqwy
Original source of discussion: This topic on the Pragmatic Programmers’ Functional Web Development with Elixir, OTP, and Phoenix forum. ...
New
JakeBecker
TL;DR: I’ve just released an implementation of Microsoft’s IDE-independent Language Server Protocol for Elixir. It adds language support ...
1144 54921 245
New
gshaw
What is the idiomatic way of matching for not nil in Elixir? E.g., First way: defp halt_if_not_signed_in(conn, signed_in_account) when...
New
SoCreat
i’m a new one to elixir which editor can i use vs code? or atom? Thanks! :smiley:
New

We're in Beta

About us Mission Statement