Filament.Test (filament v0.2.1)

Copy Markdown

Rung 2 test API for Filament components.

Mount a component in isolation, drive it with simulated events, assert on rendered HTML. No WebSocket required.

Example:

import Filament.Test

{:ok, stub} = Filament.Test.Stub.start(fn _ -> %{count: 0} end)

{:ok, view} = mount(Counter, %{server: stub})
assert render_text(view) =~ "Count: 0"

{:ok, view} = click(view, "button")
assert render_text(view) =~ "Count: 1"

Summary

Functions

Simulate a click on the element matching selector. Finds the phx-click attribute, dispatches the event handler, flushes resulting state updates, and re-renders. Returns {:ok, updated_view} or {:error, reason}.

Assert that assertion_fn.() returns a truthy value within timeout milliseconds. Retries every interval ms. Raises ExUnit.AssertionError on timeout.

Return true if the element matching selector has CSS class class_name. Raises if selector matches no elements.

Mount component with props. Returns {:ok, view} or {:error, reason}.

Return the rendered HTML as a plain string (with HTML tags stripped).

Simulate a form submission on the element matching selector with params. Finds the phx-submit attribute on the form, dispatches the handler with params, flushes state updates, re-renders. Returns {:ok, updated_view} or {:error, reason}.

Drain pending filament messages and re-render the view. Useful after pushing to an observable stub from outside the component.

Types

t()

@type t() :: %Filament.Test{
  component: module(),
  fiber_tree: map(),
  owner_pid: pid(),
  props: map(),
  rendered: Phoenix.LiveView.Rendered.t(),
  rendered_html: String.t(),
  stubs: %{required(term()) => pid()}
}

Functions

click(view, selector)

@spec click(t(), selector :: String.t()) :: {:ok, t()} | {:error, term()}

Simulate a click on the element matching selector. Finds the phx-click attribute, dispatches the event handler, flushes resulting state updates, and re-renders. Returns {:ok, updated_view} or {:error, reason}.

eventually(assertion_fn, opts \\ [])

@spec eventually(assertion_fn :: (-> term()), opts :: keyword()) :: :ok

Assert that assertion_fn.() returns a truthy value within timeout milliseconds. Retries every interval ms. Raises ExUnit.AssertionError on timeout.

The assertion function must be a zero-arity function. For assertions that need to first call update/1, include that call inside the fn and use the returned view for the assertion:

Filament.Test.eventually(fn ->
  view = Filament.Test.update(view)
  render_text(view) =~ "Count: 5"
end, timeout: 500)

has_class?(test, selector, class_name)

@spec has_class?(t(), selector :: String.t(), class_name :: String.t()) :: boolean()

Return true if the element matching selector has CSS class class_name. Raises if selector matches no elements.

mount(component, props, opts \\ [])

@spec mount(component :: module(), props :: map(), opts :: keyword()) ::
  {:ok, t()} | {:error, term()}

Mount component with props. Returns {:ok, view} or {:error, reason}.

Options:

  • :stub — list of {server_identity, stub_fn} pairs (see Filament.Test.Stub). Example: stub: [{CartServer, fn _req -> %{items: []} end}]

render_text(test)

@spec render_text(t()) :: String.t()

Return the rendered HTML as a plain string (with HTML tags stripped).

submit(view, selector, params \\ %{})

@spec submit(t(), selector :: String.t(), params :: map()) ::
  {:ok, t()} | {:error, term()}

Simulate a form submission on the element matching selector with params. Finds the phx-submit attribute on the form, dispatches the handler with params, flushes state updates, re-renders. Returns {:ok, updated_view} or {:error, reason}.

update(view)

@spec update(t()) :: t()

Drain pending filament messages and re-render the view. Useful after pushing to an observable stub from outside the component.