caslu

caslu

How to test in LiveSvelte?

Hello everyone :wave:. So i was doing some searches about LiveSvelte project, an awesome project by the way, but i had a question though: What about testing?

So live view comes with a bunch of macros for test, you can assert that a view rendered offline or connected, assert that after click event the view was redirect and much more, but when using live svelte your ui is driven mostly on “Svelte side”, so how would i test the code? Should i just ignore this live view ready to go test infrastructure and do svelte tests ? Have you guys had such experience with this or even know some example project that uses LiveSvelte and has tests?

Hope it was clear enough, thanks mates :saluting_face: :handshake:

Most Liked

Jskalc

Jskalc

Hi, I’m the creator of LiveVue library heavily inspired by LiveSvelte.

I can add 2cents from my side, there are two valid approaches to testing:

  1. Easier, test rendered props passed to svelte component
  2. Harder, proper end to end tests with Wallaby etc.

Approach 2 is kinda obvious, and gives you the most value but with significant initial investment.

But, I wanted to explain a bit more about 1). In LiveSvelte props are rendered simply in data-props attribute of a LiveSvelte root element. So it should be fairly trivial to decode them. Something along the lines (extracted from LiveVue version):

def get_svelte(html, opts) when is_binary(html) do
    if Code.ensure_loaded?(Floki) do
      svelte =
        html
        |> Floki.parse_document!()
        |> Floki.find("[phx-hook='SvelteHook']")
        # TODO - handle cases when there are more than 1 component
        |> List.first()

      %{
        props: Jason.decode!(attr(svelte, "data-props")),
        component: attr(svelte, "data-name"),
        id: attr(svelte, "id"),
        ssr: attr(svelte, "data-ssr") |> String.to_existing_atom(),
        class: attr(svelte, "class")
      }
    else
      raise "Floki is not installed. Add {:floki, \">= 0.30.0\", only: :test} to your dependencies"
    end
  end

Then, you can make assertions on these props, in the same way as you’d be testing a normal LiveView application.

test "test render", %{conn: conn} do
    {:ok, view, html} = live(conn, "/")
    %{props: props} = get_svelte(html)
    assert props["statement"] == "I love Svelte and Vue"

    html = render_hook(view, "randomize", %{}) 
    %{props: props} = get_svelte(html)
    assert props["statement"] == "I love Elixir"
end

This simple approach let’s you test all the updates inside the Live process, and check if rendered props are what you’d expect. Obviously it’s not checking actual rendered HTML, event handlers etc, but often it’s a good tradeoff.

Maybe @woutdp would be willing to incorporate such a helper inside LiveSvelte as well? :wink:

ravecat

ravecat

Thanks for the comment, but I expect the testing to just test the actual html and handlers. Tying tests to framemork attributes is a so-so idea in my opinion

Last Post!

Jskalc

Jskalc

Well, it’s basically a valid way to get up-to-date props of your svelte component. All the rest happens on the client-side.

It already allows you to test your whole view - mounting, handling various events and asserting on props passed down to your svelte component. If you’ll throw SSR to the mix you’ll be able to assert on rendered HTML as well. For some developers this might be a good tradeoff between complexity and brittleness of headless browser tests.

But yeah, that way you won’t be able to test eg button clicks or client-side state. For that you have to use Wallaby or similar, as you’re already doing.

Regarding your issue with “Attempting to reconnect” - this is always rendered by your flash_group core component, just not visible. Then client-side phoenix code shows and hides it on websocket connect and disconnect, like this:

      <.flash
        id="client-error"
        kind={:error}
        title="We can't find the internet"
        phx-disconnected={show(".phx-client-error #client-error")}
        phx-connected={hide("#client-error")}
        hidden
      >
        Attempting to reconnect <.icon name="hero-arrow-path" class="ml-1 h-3 w-3 animate-spin" />
      </.flash>

In other words, it’s always present in HTML returned by your view, as long as you use flash_group in your app.html.heex. Hope this helps :+1:

Where Next?

Popular in Questions Top

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
belgoros
I’m not a pro in using Regex and can’t figure out why the following behaviour happens, especially if we take into account the difference ...
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
WestKeys
Currently suffering from paralysis by [HTTP client] analysis. This is rather unusual in Elixirland as there tends to be consensus on the ...
New
fayddelight
I tried installing elixir 1.11.2 erlang 23.3.4 via asdf in my zsh shell. Enabled the versions locally and globally. When I list them ...
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

nobody
Hi! In PHP: $_SERVER[‘SERVER_ADDR’] - in Elixir? Searched the docs for ip address and the web, no good results. Thanks!
New
JeremM34
Hello, how can I check the Phoenix version ? Thanks !
New
sen
Hi All, I set a environment variables in dev.exs , like below code. when i start server, how can i set the ${enable} value? thanks. d...
New
sergio_101
I am VERY much an elixir newbie. I have taken one elixir course and one phoenix course on Udemy. During that course, I saw the instructor...
New
Patoshizzle
After calling mix ecto.create I get this error: 17:00:32.162 [error] GenServer #PID&lt;0.412.0&gt; terminating ** (Postgrex.Error) FATAL...
New
TunkShif
This post is an instruction guide to help you setup your Neovim for Elixir development from scratch. It includes general information on h...
274 42533 114
New

We're in Beta

About us Mission Statement