The table compares Fluffy's Phoenix and Playwright backends within the boundaries described below.

  • equivalent — matching behavior verified against Playwright;
  • structural subset — supports HTML-represented state, with browser-only behavior excluded;
  • - — unavailable or not applicable.
FeaturePhoenixPlaywright
Frame locators and traversal-equivalent
Documented CSS locator subsetequivalentequivalent
Text, label, and attribute locatorsequivalentequivalent
Structural role and accessible-name subsetstructural subsetequivalent
DOM assertions and strictnessequivalentequivalent
Page title assertionsequivalentequivalent
Indeterminate checkbox/radio DOM property-equivalent
Focus, blur, and focus assertions-equivalent
Structural element actionsstructural subsetequivalent
Visits, reloads, links, redirects, cookies, and HTTP formsequivalentequivalent
Phoenix.HTML data-method/data-to actionsstructural subsetequivalent
LiveView events, patches, navigation, and structural action retryequivalentequivalent
LiveView form-change delivery and timingstructural subsetequivalent
Declarative LiveView keyboard eventsstructural subsetequivalent
Supported mutable form state and ordered submissionequivalentequivalent
Enter implicit form submission-equivalent
Native constraint validation-equivalent
Specialized scalar input valuesstructural subsetequivalent
Computed style, layout, and browser accessibility tree-equivalent
Downloadsequivalentequivalent
Named pages and new tabs-equivalent
Browser history navigation-equivalent
Browser cookie helpers and storage-state export-equivalent
Hover, drag-and-drop, and sequential typing-equivalent
Dialogs, frame navigation, and browser request/response events-equivalent
Active-page JavaScript evaluation-equivalent
JavaScript-owned DOM and default actions-equivalent
Native invalid, submit, and formdata event ordering-equivalent
Hard-wrapped textarea, object, and custom-element entries-equivalent
Per-test sessions, cleanup, and Ecto sandbox propagationequivalentequivalent
Regex URL matchingequivalentequivalent
Structured path, query, and fragment URL matchingequivalentequivalent
Typed file selection and supported upload lifecycleequivalentequivalent
Script-opened file chooser events-equivalent

Boundaries

When to choose Playwright

Use Playwright for computed style, layout, browser accessibility, native validation, arbitrary JavaScript, and browser network events. Phoenix operates on parsed HTML and mutable form state. Even Phoenix checks structural visibility; see Visibility and DOM presence for the distinction from browser rendering and DOM absence.

LiveView timing and keyboard events

LiveView eagerly dispatches each applicable form-control phx-change and ignores phx-debounce/phx-throttle scheduling, including phx-debounce="blur". Phoenix does not model focus; its change delivery is independent of focus. Use Playwright for delay, blur-only delivery, coalescing, cancellation, and throttle suppression.

Fluffy.press/4 has a driver-specific contract:

  • Static: unsupported; raises Fluffy.CapabilityError for every key.
  • LiveView: passes the supplied key unchanged to LiveViewTest keydown/keyup handlers bound to the selected element. This includes window bindings on that element, without discovering handlers elsewhere in the document. LiveViewTest supplies event values and targeting. Fluffy does not apply phx-key filters, translate keys or modifier combinations, synthesize field values, or simulate focus movement, editing, activation, or implicit submission. An element with no keyboard binding raises. Callers supply the intended key value.
  • Playwright: native browser key presses, including default actions and Playwright modifier syntax.

Filling contenteditable elements requires Playwright. Static and LiveView fill input and textarea controls; they do not emulate editing element text.

Focus and client state

Fluffy.Playwright.focus/3, Fluffy.Playwright.blur/3, and focus assertions require Playwright. Static and LiveView do not track or simulate focus.

On a changed LiveView render, local text values adopt the rendered value, except during phx-trigger-action handoff. Unchanged document renders preserve local values. Changes are detected across the document, not per control, so an unrelated update can discard local text. Checkbox/radio state survives while the rendered checked attribute is unchanged. Selected options survive while the option signature is unchanged; files survive while the matched control remains a file input. Use Playwright for focused input protection and exact browser patch behavior.

LiveView document and patch boundaries

LiveView locators and actions see the current Phoenix.LiveViewTest.View, not the surrounding dead layout. Use Phoenix.ConnTest for initial outer-layout HTML assertions or Playwright for full-document interactions. LiveView Fluffy.unwrap/2 receives only the View.

Tabs, windows, and iframes

The Playwright backend exposes page handles for browser tabs and popup windows. All public page-management helpers live in Fluffy.Playwright and reject Phoenix sessions. Phoenix retains one current document internally; use shared page URL, title, and status assertions to inspect it. Fluffy.Playwright.new_page/1 returns a handle; Fluffy.Playwright.switch_page/2 selects it for subsequent actions. Use frame locators to query iframe contents with Playwright. Page switching does not select an iframe, and frame locators do not change the active page.

Static and LiveView can query the iframe element in their current markup, but do not load its src or parse its srcdoc as a child document. They do not flatten iframe contents into the parent document or ignore frame boundaries: executing a frame-traversing query raises Fluffy.CapabilityError. Visit the embedded route directly to test it independently with Phoenix; use Playwright to test the embedding behavior. See Pages, popups, and frames for how pages, browser contexts, and frames relate.

Browser baseline

Fluffy verifies compatibility against pinned Chromium. Firefox and WebKit are available through Playwright but are not covered by Fluffy's conformance suite.

Phoenix.HTML actions and dialogs

For a Static or LiveView target with data-confirm, Fluffy.click/2 ignores the attribute and continues with the normal structural action. It does not create, inspect, accept, or dismiss a browser dialog; use Playwright whenever the prompt or its cancellation path is part of the assertion. Both in-process drivers model the pinned Phoenix.HTML data-method/data-to hidden-form action for plain elements, including links and buttons. Custom phoenix.link.click listeners, cancellation, and competing LiveView actions remain browser-only.

Forms and files

Static and LiveView bypass native validation and retain specialized scalar input values as supplied strings. Use Playwright for validation events and blocking, browser sanitization/defaults, and custom or form-associated elements.

Native reset-button behavior requires Playwright. Static and LiveView clicks do not restore form defaults or clear file selections. LiveView reset buttons with phx-click still dispatch their server event.

File selection supports bounded local paths and typed in-memory payloads, ordered multiple selection, clearing, and ordinary multipart forms, including empty-file entries. Managed LiveView uploads support validation, progress, cancellation, replacement, auto-upload, and submission.

Native picker UI, external uploaders, directories, drag-and-drop, and arbitrary FileList mutation are unsupported. Fluffy.Event.file_chooser/1 requires Playwright because application JavaScript opens the chooser.

Native escape hatch

Fluffy.unwrap/2 exposes driver-specific APIs: Plug.Conn, Phoenix.LiveViewTest.View, or Fluffy.Playwright.Handle. Use the shared event and page APIs for lifecycle operations. See Native escape hatch for callback behavior.