Fluffy
Phoenix feature tests. Three drivers, one Playwright-shaped API.
Fluffy runs tests through ConnTest, LiveViewTest, or a real browser. Its in-process drivers are checked against Playwright, grounding their behavior in browser reality.
Coming from PhoenixTest? Fluffy adds strict, composable locators, per-test backend selection within one module, and Playwright-style assertion retries and action waiting. See the differences →
start_session(:phoenix)
|> visit("/creatures")
|> fill(by_label("Name"), "Basilisk")
|> click(by_role(:button, name: "Register"))
|> expect(by_role(:heading, name: "Basilisk") |> to_be_visible())
|> expect(Page.to_have_url("/creatures/basilisk"))
Getting started
Add the dependency:
# mix.exs
defp deps do
[
{:fluffy, "~> 0.2.0", only: :test}
]
end
Configure the endpoint:
# config/test.exs
config :fluffy, endpoint: MyAppWeb.Endpoint
Every Fluffy test establishes a lifecycle scope and imports the shared API:
use ExUnit.Case, async: true
import Fluffy
import Fluffy.Expect
import Fluffy.Locator
alias Fluffy.Page
setup context do
Fluffy.Test.setup(context)
end
Start with start_session(:phoenix) for in-process Static and LiveView tests.
Use start_session(:playwright) when a test needs a real browser. See
Installation and runtime for Playwright and Ecto sandbox
setup, then Usage for writing tests and a shared FluffyCase.
Migrating from PhoenixTest
The pipeline stays familiar; actions and expectations use composable locators:
| PhoenixTest | Fluffy |
|---|---|
fill_in("Name", with: "Basilisk") |
fill(by_label("Name", exact: true), "Basilisk") |
click_button("Register") |
click(by_role(:button, name: "Register")) |
assert_path("/creatures") |
expect(Page.to_have_url(path: "/creatures")) |
See Migrating from PhoenixTest for the full translation table and behavior differences.
Beyond page interactions
Capture downloads, open new tabs, handle dialogs, and observe network events with Fluffy's event API. See Advanced events and pages for examples and the Capability matrix for what each backend supports.
Guides
- Installation and runtime — endpoint, browser, and Ecto sandbox setup
- Usage — locators, actions, expectations, backend choice, and diagnostics
- Advanced events and pages — downloads, tabs, navigation, dialogs, and network events
- Migrating from PhoenixTest — an alternate starting point for existing PhoenixTest suites
- Capability matrix — backend differences and limitations
Developing Fluffy
The project pins the current local-development toolchain in .tool-versions.
Fluffy's compatibility floor remains Elixir 1.18 and Node.js 20; development
also requires pnpm 11.19.0 and PostgreSQL. From a clean checkout:
mix setup
mix test
Run the ordinary local gate—Styler-backed formatting, warnings-as-errors compilation, strict Credo, and the test suite—with:
mix check
Add test-environment Dialyzer analysis with:
mix quality
License
Fluffy is released under the MIT License.