Using LiveViewTest to assert element with Alpine.js

I’m using both Alpine and LiveView in my project and I’m in the process of writing a test to check if an element has an attribute value of style=display: none;

The particular element has an Alpine directive of x-show attached to it, which should toggle the display.

# page template snippet
<div x-data="{ isShowable: <%= check_showable() %> }">
    <div x-show="isShowable"
       <button>MyButton</button>
    </div>
</div>

What I am finding is that in my test, even when isShowable is evaluated to false, the button does not have style=display: none; attached. I’ve checked this by parsing the rendered HTML using Floki.

However, if I launch my app and inspect my page in a browser, that style is applied.

# test assertion
{:ok, view, _html} = live(conn, "/page")
assert view
       |> element("div[x-show='isShowable'][style='display: none;']")
       |> has_element?()

Wondering if this is expected behaviour when using LiveViewTest and if I am missing something.

Invoking the live/2 test function does not launch a browser instance or have the ability to execute any javascript (which includes alpinejs)

This is one of the reasons to use JS sparingly as it makes integration testing more complex. Liveviews can be tested without the implementation detail of a websocket connection etc. But the moment alpine or any other js is involved - the approach you have demonstrated does not include those interactions.

If you want your test to be representative of a users browser you need to use something like Hound — hound v1.1.1 (hexdocs.pm) that runs integration tests in a headless browser.

1 Like

Thanks for the quick reply. I was afraid of this, but suspected that this was a limitation of LiveViewTest.
I’ll check out hound, thanks for the suggestion

wallaby is another option - wallaby v0.28.0 (hexdocs.pm)