# Mirage
[](https://hex.pm/packages/mirage)
[](https://hexdocs.pm/mirage)
Browserless page and component testing library for
the [Hologram](http://hologram.page) framework.
## About
Mirage allows for browserless testing of hologram pages and components. Its API
is very similar to that of
[`PhoenixTest`](https://hex.pm/packages/phoenix_test).
Here is a quick example:
```elixir
test "it works" do
MyApp.HomePage
|> visit(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
```
You can also test components in isolation:
```elixir
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
```
Mirage works by initializing page and component modules directly and "faking"
events to call `action` and `command` calls behind the scenes. It's similar to
doing:
```elixir
page = Counter.init(%{count: 0}, %Hologram.Component{}, %Hologram.Server{})
page = Counter.action(:count, %{}, page)
assert page.state.count == 1
```
only Mirage allows you to interact with the Hologram's virtual DOM.
## JavaScript testing
Note that Mirage does not handle JavaScript. Of course, with Hologram being an
isomorphic framework, we write most of our JavaScript in Elixir anyway, so
Mirage can take you really far. However, if you need to test any JS-interop
features you will need to write those tests in
[Wallaby](https://hex.pm/packages/wallaby) or
[PlaywrightEx](https://hex.pm/packages/playwright_ex).
## Installation
```elixir
def deps do
[
{:mirage, "~> 0.0.1", only: :test, runtime: false},
]
end
```
To use Mirage, just `import` it into your tests:
```elixir
defmodule MyApp.MyTest do
use ExUnit.Case
import Mirage
test "it works" do
MyApp.HomePage
|> visit()
# ...
end
end
```
Or use a custom case:
```elixir
defmodule MyApp.FeatureCase do
use ExUnit.CaseTemplate
using do
quote do
import Mirage
end
end
end
defmodule MyApp.MyTest do
use MyApp.FeatureCase
# ...
end
```
## I'm Mr. Meeseeks, look at me!
This project contains code adapted from
[meeseeks](https://hex.pm/packages/meeseeks) specifically for parsing CSS
selectors. See [lib/mirage/css.ex](lib/mirage/css.ex).
## Note on AI-use
This library is currently super-alpha. It was made with heavy LLM assistance as
it's something that has been blocking progress on another project of mine.
I have not finished the full vetting process yet.