Filament.Test (filament v0.4.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 blur event on the element matching selector. Finds the phx-blur attribute, dispatches the handler, flushes state updates, re-renders. Returns {:ok, updated_view} or {:error, reason}.

Like blur/2 but returns the view directly, raising on error.

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

Like change/3 but returns the view directly, raising on error.

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}.

Like click/2 but returns the view directly, raising on error.

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.

Like key_down/2,3 but returns the view directly, raising on error.

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

Like mount/3 but returns the view directly.

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}.

Like submit/3 but returns the view directly, raising on error.

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

blur(view, selector)

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

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

blur!(view, selector)

@spec blur!(t(), String.t()) :: t()

Like blur/2 but returns the view directly, raising on error.

change(view, selector, params)

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

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

change!(view, selector, params)

@spec change!(t(), String.t(), map()) :: t()

Like change/3 but returns the view directly, raising on error.

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}.

click!(view, selector)

@spec click!(t(), String.t()) :: t()

Like click/2 but returns the view directly, raising on error.

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.

key_down(view, key_or_selector, opts_or_key \\ [])

@spec key_down(t(), String.t(), keyword()) :: {:ok, t()} | {:error, term()}
@spec key_down(t(), String.t(), String.t()) :: {:ok, t()} | {:error, term()}

Simulate a keydown event.

Two forms:

  • key_down(view, key, opts \\ []) — window-level (on_key). Finds the first phx-hook="FilamentKey" element and dispatches with modifier opts: ctrl: true, shift: true, alt: true, meta: true.

  • key_down(view, selector, key) — element-scoped (on_keydown). Finds the element matching selector, dispatches with %{"key" => key}.

Both flush state updates and re-render. Return {:ok, updated_view} or {:error, reason}.

key_down!(view, key_or_selector, opts_or_key \\ [])

@spec key_down!(t(), String.t(), keyword()) :: t()
@spec key_down!(t(), String.t(), String.t()) :: t()

Like key_down/2,3 but returns the view directly, raising on error.

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}]

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

@spec mount!(module(), map(), keyword()) :: t()

Like mount/3 but returns the view directly.

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}.

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

@spec submit!(t(), String.t(), map()) :: t()

Like submit/3 but returns the view directly, raising on error.

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.