Now that I’ve used this in anger for a week, I’d like to introduce 0.1.0 of Mirage, a browerless testing framework for Hologram pages and components.
I still consider this library highly experimental, so please see “goals” below.
Motivation
There are a few things about LiveView that I love equally and one of those things is LiveViewTest. As a solo dev and avid TDD’r, I often start with a LiveView test and work my way down. Having something akin to a full browser test finish in milliseconds was one of the experiences that got me addicted to LiveView.
I’ve recently become extremely enamoured with Hologram and wanted a similar experience. With Hologram being isomorphic, it lends itself to getting even closer to that “almost a real browser test” than LiveView! Mirage aims to provide a similar experience and does so with an API similar to that of PhoenixTest.
Goals
This is my first heavily LLM-assisted library and would basically not exist (yet) without them. I’ve still put many, many hours into this, learning about Hologram internals, and deciding how this should work. This contains pieces that are everywhere from hand-written to totally vibed (though it’s mostly in-between those). Hologram is a very young framework, and it’s not (yet) written in a way that easily facilitates easily writing a library like Mirage. For that reason, Mirage not only contains code copied directly from Hologram, it has a high level re-implementation of Hologram’s client side Runtime in Elixir. While this is somewhat sustainable thanks to LLMs, it’s certainly not ideal.
Therefore, I would like to make it clear that, at least for now, Mirage is meant for the Hologram community to experiment with this type of testing library and figure out if it’s something we really want and what it should ultimately look/feel like. I know Bart would eventually like an e2e solution built into Hologram, but I ultimately want browerless more than anything, so I really wanted to start exploring it now.
Notes
I announced Mirage last week in the Hologram Discord. If anyone has taken it for a test drive yet, be aware that there is a significant breaking change in 0.1.0.
Examples
defmodule MyApp.HomePageTest do
use ExUnit.Case, async: true
use Mirage.Page
test "sign up", %{server: server} do
server
|> visit(MyApp.HomePage, my_param: "some-param")
|> click_link("Sign-up")
|> fill_in("Name", with: "Bender Bending Rodríguez")
|> fill_in("Password", with: "wanna-kill-all-humans?")
|> click_button("Submit")
|> assert_page(MyApp.WelcomePage)
|> assert_has("p", "Welcome, Bender!")
end
end
You can also test components in isolation:
defmodule MyApp.Components.PoplarTrackerTest do
use ExUnit.Case, async: true
use Mirage.Component
test "it counts" do
~HOLO"""
<MyApp.Components.PoplarTracker cid="counter" eaten={0}>
<p>{@user.name} eats too many poplars.</p>
</MyApp.Components.PoplarTracker>
"""
|> mount({MyApp, user: current_user})
|> click_button("Eat a poplar")
|> assert_has("p", "Number of poplars eaten: 1")
end
end
Get it!
- hex.pm
- github






















