### Test with Setup Data
Source: https://github.com/germsvel/phoenix_test/blob/main/_autodocs/examples.md
Demonstrates setting up test data before running a test. The `setup` block inserts a user and makes it available to the test function.
```elixir
defmodule MyAppWeb.UserTest do
use MyAppWeb.FeatureCase
setup do
user = insert(:user, name: "Aragorn", email: "aragorn@dunedain.com")
{:ok, user: user}
end
test "can view user profile", %{user: user} do
conn
|> visit("/users/#{user.id}")
|> assert_has("h1", "Aragorn")
|> assert_has(".email", "aragorn@dunedain.com")
end
end
```
--------------------------------
### Simple Navigation Example
Source: https://github.com/germsvel/phoenix_test/blob/main/_autodocs/examples.md
Tests navigation by visiting the homepage, clicking a link, and asserting the new path and heading.
```elixir
test "navigate to users page" do
conn
|> visit("/")
|> click_link("Users")
|> assert_path("/users")
|> assert_has("h1", "Users")
end
```
--------------------------------
### PhoenixTest.Live.build/1
Source: https://github.com/germsvel/phoenix_test/blob/main/_autodocs/session-structure.md
Creates a new Live session by starting a LiveView and watcher. This is the entry point for testing LiveView pages.
```APIDOC
## PhoenixTest.Live.build/1
### Description
Creates a new Live session by starting a LiveView and watcher.
### Method
`build/1`
### Parameters
#### Path Parameters
None
#### Query Parameters
None
#### Request Body
None
### Request Example
None
### Response
#### Success Response
- **session** (PhoenixTest.Live.t()) - A new Live session struct.
### Response Example
None
```
--------------------------------
### Pipeable Design Example
Source: https://github.com/germsvel/phoenix_test/blob/main/_autodocs/overview.md
Demonstrates the pipeable design of PhoenixTest functions for simulating user interactions and assertions.
```elixir
conn
|> visit("/users")
|> fill_in("Name", with: "Aragorn")
|> click_button("Create")
|> assert_has(".user", "Aragorn")
```
--------------------------------
### Build Live Session
Source: https://github.com/germsvel/phoenix_test/blob/main/_autodocs/session-structure.md
Creates a new Live session by initiating a LiveView and its associated watcher. Use this to start testing a LiveView page.
```elixir
def build(conn :: Plug.Conn.t()) :: PhoenixTest.Live.t()
```
--------------------------------
### PhoenixTest.Operation Example
Source: https://github.com/germsvel/phoenix_test/blob/main/_autodocs/types-and-structures.md
An example of an Operation structure representing a button click. The 'html' field would contain the parsed HTML content after the operation.
```elixir
%PhoenixTest.Operation{
type: :click_button,
html: #LazyHTML<...> # Parsed HTML after button click
}
```
--------------------------------
### PhoenixTest.ActiveForm Example State
Source: https://github.com/germsvel/phoenix_test/blob/main/_autodocs/types-and-structures.md
An example of how to initialize and represent the state of an ActiveForm. This includes the form's CSS selector and its associated data.
```elixir
%PhoenixTest.ActiveForm{
selector: "#user-form",
data: %{
"name" => "Aragorn",
"email" => "aragorn@dunedain.com",
"role" => "admin"
}
}
```
--------------------------------
### Form Data Structure Example
Source: https://github.com/germsvel/phoenix_test/blob/main/_autodocs/form-elements.md
Illustrates the structure of form data, which is a map with field names as keys and their corresponding values.
```elixir
# FormData is a map with field names as keys and field values as values
# Example: %{"name" => "Aragorn", "email" => "aragorn@dunedain.com"}
```
--------------------------------
### LiveView Interaction with PhoenixTest Helpers
Source: https://github.com/germsvel/phoenix_test/blob/main/README.md
This example shows how to interact with LiveView elements, render a click, and assert on the resulting HTML using LiveView's testing helpers.
```elixir
{:ok, view, _html} = live(conn, ~p"/")
html =
view
|> element("#greet-guest")
|> render_click()
assert html =~ "Hello, guest!"
```
--------------------------------
### Testing Complex User Registration Flow
Source: https://github.com/germsvel/phoenix_test/blob/main/_autodocs/advanced-features.md
Organize multi-step operations like user registration into logical chunks. This example demonstrates filling forms, submitting, and asserting success messages.
```elixir
test "user registration flow" do
conn
|> visit("/register")
|> fill_in("Email", with: "user@example.com")
|> fill_in("Password", with: "secret123")
|> check("I agree to terms")
|> click_button("Register")
|> assert_has(".alert", "Confirmation email sent")
# Later, verify confirmation worked
visit(conn, "/")
|> assert_has(".alert", "Account confirmed")
end
```
--------------------------------
### Visit Any Page in PhoenixTest
Source: https://github.com/germsvel/phoenix_test/blob/main/_autodocs/connection-handlers.md
Use the `visit/2` function to navigate to any page. This function automatically handles both static and LiveView pages, simplifying test setup.
```elixir
session = conn |> visit("/any-page")
```
--------------------------------
### Elixir Function Signature Example
Source: https://github.com/germsvel/phoenix_test/blob/main/_autodocs/README.md
This snippet shows the expected format for a full function signature with types in the documentation. It includes parameter types and return types.
```elixir
# Full function signature with types
def function_name(param :: Type) :: ReturnType
```
--------------------------------
### Refutation Example
Source: https://github.com/germsvel/phoenix_test/blob/main/_autodocs/examples.md
Asserts that an element is NOT present on the page after an action, such as deletion. Verifies that an item has been successfully removed.
```elixir
test "deleted item is gone" do
post = insert(:post)
conn
|> visit("/posts")
|> click_link("Delete")
|> confirm_delete()
|> refute_has(".post", post.title)
end
```
--------------------------------
### Testing Editing Existing User Data
Source: https://github.com/germsvel/phoenix_test/blob/main/_autodocs/advanced-features.md
This example shows how to test the editing of existing user data. It involves visiting an edit page, asserting pre-filled values, modifying them, and verifying the update.
```elixir
test "can edit existing user" do
user = insert(:user, name: "Aragorn")
conn
|> visit("/users/#{user.id}/edit")
|> assert_has("input", value: "Aragorn", label: "Name")
|> fill_in("Name", with: "Elessar")
|> click_button("Save")
|> assert_has(".success", "User updated")
end
```
--------------------------------
### Scope Selector Example
Source: https://github.com/germsvel/phoenix_test/blob/main/_autodocs/connection-handlers.md
Demonstrates how to combine a CSS selector with a scope. Use this when you need to target elements within a specific part of the HTML document during tests.
```elixir
scope_selector("button", :none) # "button"
scope_selector("button", "#form") # "#form button"
scope_selector("a", ".section") # ".section a"
```
--------------------------------
### Set Operation Example
Source: https://github.com/germsvel/phoenix_test/blob/main/_autodocs/connection-handlers.md
Updates the session's current operation tracking. This is useful for logging or asserting the type of action performed during a test.
```elixir
set_operation(session, :visit)
set_operation(session, :click_link, "
Click me")
```
--------------------------------
### build/1
Source: https://github.com/germsvel/phoenix_test/blob/main/_autodocs/session-structure.md
Creates a new Static session from a Plug.Conn struct. This is the entry point for interacting with static pages.
```APIDOC
## build/1
### Description
Creates a new Static session from a connection.
### Method
`build`
### Parameters
#### Path Parameters
None
#### Query Parameters
None
#### Request Body
None
### Parameters
- **conn** (Plug.Conn.t()) - The Plug connection object to create the session from.
```
--------------------------------
### Get Current Path
Source: https://github.com/germsvel/phoenix_test/blob/main/_autodocs/session-structure.md
Retrieves the current URL path from the Static session.
```elixir
def current_path(session :: PhoenixTest.Static.t()) :: String.t()
```
--------------------------------
### Run a Benchmark
Source: https://github.com/germsvel/phoenix_test/blob/main/bench/README.md
Execute a benchmark file using the MIX_ENV=test environment. This ensures benchmarks have access to the testing LiveView application.
```bash
MIX_ENV=test mix run
```
```bash
MIX_ENV=test mix run bench/assertions.exs
```
--------------------------------
### Submit Form on Static or LiveView Page
Source: https://github.com/germsvel/phoenix_test/blob/main/_autodocs/connection-handlers.md
This snippet demonstrates submitting a form on either a static or LiveView page. It shows how to visit a page, fill in form fields, select an option, click a submit button, and assert the expected outcome.
```elixir
conn
|> visit("/form-page")
|> fill_in("Name", with: "Aragorn")
|> select("Race", option: "Human")
|> click_button("Submit")
|> assert_has(".success", "Created!")
```
--------------------------------
### Get HTML Element Attribute
Source: https://github.com/germsvel/phoenix_test/blob/main/_autodocs/types-and-structures.md
Retrieves a specific attribute value from an HTML element using `Html.attribute/2`.
```elixir
# Get attribute
href = Html.attribute(element, "href")
```
--------------------------------
### Build Static Session
Source: https://github.com/germsvel/phoenix_test/blob/main/_autodocs/session-structure.md
Creates a new Static session by initializing it with a Plug.Conn struct.
```elixir
def build(conn :: Plug.Conn.t()) :: PhoenixTest.Static.t()
```
--------------------------------
### Get Form Field Names
Source: https://github.com/germsvel/phoenix_test/blob/main/_autodocs/form-elements.md
Retrieves a list of all form field names present within a given form element.
```elixir
def form_element_names(form :: PhoenixTest.Element.Form.t()) :: [String.t()]
```
--------------------------------
### Get Configured Endpoint from Connection
Source: https://github.com/germsvel/phoenix_test/blob/main/_autodocs/connection-handlers.md
Retrieves the configured Phoenix endpoint module from a connection struct. Returns nil if no endpoint is configured.
```elixir
EndpointHelpers.get_endpoint(conn)
```
--------------------------------
### Testing Complete User Flow with Fixtures
Source: https://github.com/germsvel/phoenix_test/blob/main/_autodocs/advanced-features.md
This snippet demonstrates testing a complete user flow using fixtures defined in a `FeatureCase`. It includes navigation, form submission, and asserting success.
```elixir
defmodule MyAppWeb.FeatureTest do
use MyAppWeb.FeatureCase
test "complete user flow" do
# Test setup via fixtures in FeatureCase
conn
|> visit("/")
|> follow_user_flow()
|> assert_success()
end
defp follow_user_flow(session) do
session
|> click_link("Sign Up")
|> fill_user_form()
|> submit_and_verify()
end
end
```
--------------------------------
### LiveView Navigation Between Pages
Source: https://github.com/germsvel/phoenix_test/blob/main/_autodocs/examples.md
Demonstrates how to perform navigation to a different LiveView page using `click_link`. Asserts the new URL and the presence of expected content on the destination page.
```elixir
test "live navigation to different page" do
conn
|> visit("/live/home")
|> click_link("Go to Details")
|> assert_path("/live/details")
|> assert_has("h1", "Details Page")
end
```
--------------------------------
### Get First Matching Element with LazyHTML
Source: https://github.com/germsvel/phoenix_test/blob/main/_autodocs/html-query-utilities.md
Retrieve the first element that matches a CSS selector. This is useful when you only need the initial occurrence of a pattern.
```elixir
html |> Html.all(".post") |> Enum.at(0)
```
--------------------------------
### visit/2
Source: https://github.com/germsvel/phoenix_test/blob/main/_autodocs/protocol-driver.md
Creates a new session and navigates to the specified path. Automatically detects whether the page is a LiveView and uses the appropriate handler.
```APIDOC
## visit/2
### Description
Creates a new session and navigates to the specified path. Automatically detects whether the page is a LiveView and uses the appropriate handler.
### Function Signature
`def visit(initial_struct :: Plug.Conn.t() | session, path :: String.t()) :: session`
### Parameters
#### Path Parameters
- **initial_struct** (Plug.Conn.t() | session) - Required - The initial connection or session to use.
- **path** (String.t()) - Required - The path to navigate to.
### Implemented by:
- `PhoenixTest.Live.visit/2`
- `PhoenixTest.Static.visit/2`
```
--------------------------------
### Get Configured Endpoint (Raises on Not Found)
Source: https://github.com/germsvel/phoenix_test/blob/main/_autodocs/connection-handlers.md
Retrieves the configured Phoenix endpoint module from a connection struct. Raises a RuntimeError if the endpoint is not configured.
```elixir
EndpointHelpers.get_endpoint!(conn)
```
--------------------------------
### Navigate to a Path with PhoenixTest
Source: https://github.com/germsvel/phoenix_test/blob/main/_autodocs/api-main-functions.md
Entrypoint to create a session for navigating Phoenix applications. It handles both LiveView and static pages. Ensure the endpoint is configured on the connection before use.
```elixir
def visit(conn :: Plug.Conn.t() | session, path :: String.t()) :: session
```
```elixir
session = conn |> visit("/")
session = session |> visit("/about")
```
--------------------------------
### Wildcard Path Matching in Navigation
Source: https://github.com/germsvel/phoenix_test/blob/main/_autodocs/examples.md
Demonstrates using wildcard path matching for navigation. The '*' in the path matches any user ID.
```elixir
test "viewing user details" do
user = insert(:user, name: "Legolas")
conn
|> visit("/users")
|> click_link("Legolas")
|> assert_path("/users/*/details") # * matches any ID
|> assert_has("h1", "Legolas")
end
```
--------------------------------
### PhoenixTest.Driver.visit/2
Source: https://github.com/germsvel/phoenix_test/blob/main/_autodocs/protocol-driver.md
Creates a new session and navigates to the specified path. Automatically detects whether the page is a LiveView and uses the appropriate handler.
```elixir
def visit(initial_struct :: Plug.Conn.t() | session, path :: String.t()) :: session
```
--------------------------------
### LazyHTML Get First Element
Source: https://github.com/germsvel/phoenix_test/blob/main/_autodocs/types-and-structures.md
Shows how to retrieve the first element that matches a CSS selector from a LazyHTML structure using Enum.at/2 with an index of 0.
```elixir
# Get first element
html |> Html.all(".item") |> Enum.at(0)
```
--------------------------------
### Get Current Live Session Path
Source: https://github.com/germsvel/phoenix_test/blob/main/_autodocs/session-structure.md
Retrieves the current URL path of the Live session. This function is essential for verifying navigation within the LiveView.
```elixir
def current_path(session :: PhoenixTest.Live.t()) :: String.t()
```
--------------------------------
### Visit a Static Page Connection
Source: https://github.com/germsvel/phoenix_test/blob/main/_autodocs/connection-handlers.md
Creates a static page session by making an HTTP request. Delegates to LiveView handling if a LiveView is present, otherwise returns a static session. Use for testing non-LiveView pages.
```Elixir
def visit(conn :: Plug.Conn.t(), path :: String.t()) :: session
```
--------------------------------
### Handler Detection Logic
Source: https://github.com/germsvel/phoenix_test/blob/main/_autodocs/protocol-driver.md
This snippet shows how the main `visit/2` function detects whether the connection is a LiveView or a static page and delegates to the appropriate builder function.
```elixir
def visit(conn, path) do
case EndpointHelpers.live(conn) do
{:ok, view, _html} -> PhoenixTest.Live.build(view)
:not_live_view -> PhoenixTest.Static.build(conn)
end
end
```
--------------------------------
### Simple Form Submission
Source: https://github.com/germsvel/phoenix_test/blob/main/_autodocs/examples.md
Tests a simple form submission to create a new user. It fills in fields and clicks the create button.
```elixir
test "create user" do
conn
|> visit("/users/new")
|> fill_in("Name", with: "Gimli")
|> fill_in("Email", with: "gimli@khazaddum.com")
|> click_button("Create User")
|> assert_path("/users")
|> assert_has(".alert-success", "User created")
|> assert_has("tr", "Gimli")
end
```
--------------------------------
### visit/2
Source: https://github.com/germsvel/phoenix_test/blob/main/_autodocs/connection-handlers.md
Creates a static page session by making an HTTP request. It checks the response type and either delegates to LiveView handling or returns a static session.
```APIDOC
## visit/2
### Description
Creates a static page session by making an HTTP request and checking the response type. If the response contains a LiveView, delegates to `PhoenixTest.Live.build/1`. Otherwise returns a `PhoenixTest.Static.t()` session.
### Method
Not applicable (Elixir function)
### Parameters
#### Path Parameters
None
#### Query Parameters
None
#### Request Body
None
### Request Example
```elixir
# Example usage:
# session = PhoenixTest.ConnHandler.visit(conn, "/users")
```
### Response
#### Success Response
Returns `PhoenixTest.Live.t() | PhoenixTest.Static.t()` — The appropriate session type.
#### Response Example
```elixir
# Example return value:
# %PhoenixTest.Static{...} or %PhoenixTest.Live{...}
```
```
--------------------------------
### LazyHTML Get Specific Index Element
Source: https://github.com/germsvel/phoenix_test/blob/main/_autodocs/types-and-structures.md
Illustrates how to access an element at a specific index within a collection of elements matching a CSS selector using Enum.at/2.
```elixir
# Get specific index
html |> Html.all(".item") |> Enum.at(2)
```
--------------------------------
### unwrap/2
Source: https://github.com/germsvel/phoenix_test/blob/main/_autodocs/protocol-driver.md
Provides access to the underlying native structure for advanced operations. It can be used with LiveView sessions to receive a Phoenix.LiveViewTest view and must return the result of a `render_*` action, or with Static sessions to receive a Plug.Conn.t() and return a Plug.Conn.t().
```APIDOC
## unwrap/2
### Description
Provides access to the underlying native structure for advanced operations.
### Signature
```elixir
def unwrap(session, fun :: function()) :: session
```
### Parameters
#### Path Parameters
- **session** (Phoenix.LiveViewTest | Plug.Conn.t()) - The current session.
- **fun** (function()) - The function to apply to the underlying native structure.
### Returns
- **session** (Phoenix.LiveViewTest | Plug.Conn.t()) - The modified session.
```
--------------------------------
### Get Raw HTML of an Element
Source: https://github.com/germsvel/phoenix_test/blob/main/_autodocs/html-query-utilities.md
Use `raw/1` to retrieve the original HTML string of a given element. This is useful for inspecting or manipulating the element's HTML structure directly.
```Elixir
def raw(element :: LazyHTML.t()) :: String.t()
# Example usage would typically involve an element obtained from Html.all/2
```
--------------------------------
### Check Hidden Fields in Phoenix LiveView Forms
Source: https://github.com/germsvel/phoenix_test/blob/main/_autodocs/examples.md
Verify that hidden input fields are correctly included in the form's HTML. This example checks for the presence and count of inputs with `type='hidden'`.
```elixir
test "form includes hidden fields" do
conn
|> visit("/form")
|> unwrap(fn view_or_conn ->
case view_or_conn do
%PhoenixTest.Live{current_operation: op} ->
# Check if hidden input exists
op.html
|> Html.all("input[type='hidden']")
|> Enum.count()
%PhoenixTest.Static{current_operation: op} ->
# Same for static
op.html
|> Html.all("input[type='hidden']")
|> Enum.count()
end
end)
end
```
--------------------------------
### Delegation Pattern for Driver Methods
Source: https://github.com/germsvel/phoenix_test/blob/main/_autodocs/protocol-driver.md
Demonstrates the use of `defdelegate` to delegate common driver methods like `click_link` and `click_button` to a `Driver` module.
```elixir
defdelegate click_link(session, text), to: Driver
defdelegate click_button(session, text), to: Driver
```
--------------------------------
### LiveView Asynchronous Data Loading
Source: https://github.com/germsvel/phoenix_test/blob/main/_autodocs/examples.md
Illustrates handling asynchronous data loading in LiveView. It asserts the presence of a loading indicator and then waits for the actual data to appear.
```elixir
test "data loads asynchronously" do
conn
|> visit("/live/async-data")
|> assert_has(".loading")
|> assert_has(".data-item", "Item 1", timeout: 1000) # Wait for async load
end
```
--------------------------------
### Get Specific Index Element with LazyHTML
Source: https://github.com/germsvel/phoenix_test/blob/main/_autodocs/html-query-utilities.md
Access an element at a specific 0-based index within the results of a CSS selector query. Ensure the index is within the bounds of the found elements.
```elixir
html |> Html.all(".post") |> Enum.at(1)
```
--------------------------------
### Filter LazyHTML Elements by Text Content
Source: https://github.com/germsvel/phoenix_test/blob/main/_autodocs/html-query-utilities.md
Filter a collection of HTML elements based on their text content. This example filters elements containing the word 'important' after selecting all elements with the '.post' class.
```elixir
html
|> Html.all(".post")
|> Enum.filter(&Html.element_text(&1) =~ "important")
```
--------------------------------
### Test Form Validation Errors in Phoenix LiveView
Source: https://github.com/germsvel/phoenix_test/blob/main/_autodocs/examples.md
Simulate user input that should trigger validation errors and assert that the correct error messages are displayed. This example tests for a blank 'Name' field.
```elixir
test "shows validation errors" do
conn
|> visit("/users/new")
|> fill_in("Name", with: "") # Empty name
|> click_button("Create")
|> assert_has(".error", "Name can't be blank")
end
```
--------------------------------
### Open Browser with Custom Function
Source: https://github.com/germsvel/phoenix_test/blob/main/_autodocs/protocol-driver.md
Opens the browser with a custom function to generate the HTML content to display.
```elixir
def open_browser(session, open_fun :: function()) :: session
```
--------------------------------
### Test User Creation Flow with PhoenixTest
Source: https://github.com/germsvel/phoenix_test/blob/main/README.md
This snippet demonstrates a typical user flow involving navigation, form submission, and assertion on a static page using PhoenixTest.
```elixir
test "admin can create a user", %{conn: conn} do
conn
|> visit("/")
|> click_link("Users")
|> fill_in("Name", with: "Aragorn")
|> click_button("Create")
|> assert_has(".user", "Aragorn")
end
```
--------------------------------
### Static Page Testing with Controller Testing
Source: https://github.com/germsvel/phoenix_test/blob/main/README.md
This snippet illustrates traditional controller testing for static pages, fetching a page and asserting on its HTML response.
```elixir
conn = get(conn, ~p"/greet_page")
assert html_response(conn, 200) =~ "Hello, guest!"
```
--------------------------------
### open_browser/1
Source: https://github.com/germsvel/phoenix_test/blob/main/_autodocs/protocol-driver.md
Opens the browser with the current HTML, useful for debugging.
```APIDOC
## open_browser/1
### Description
Opens the browser with the current HTML for debugging purposes.
### Signature
```elixir
def open_browser(session) :: session
```
### Parameters
#### Path Parameters
- **session** (any) - The current session.
### Returns
- **session** (any) - The session.
```
--------------------------------
### Form with Select Option
Source: https://github.com/germsvel/phoenix_test/blob/main/_autodocs/examples.md
Demonstrates selecting an option from a dropdown (select) element in a form.
```elixir
test "create post with category" do
conn
|> visit("/posts/new")
|> fill_in("Title", with: "Elvish Lore")
|> select("Category", option: "Mythology")
|> click_button("Create")
|> assert_has(".post", "Elvish Lore")
end
```
--------------------------------
### Render LiveView with EndpointHelpers.live/1
Source: https://github.com/germsvel/phoenix_test/blob/main/_autodocs/connection-handlers.md
Attempts to render a page as a LiveView using Phoenix.LiveViewTest. Use this when you need to differentiate between LiveView and static page rendering in your tests.
```elixir
case EndpointHelpers.live(conn) do
{:ok, view, html} -> handle_live_view(view, html)
:not_live_view -> handle_static_page(conn)
end
```
--------------------------------
### PhoenixTest.FileDownload Struct
Source: https://github.com/germsvel/phoenix_test/blob/main/_autodocs/types-and-structures.md
Defines the structure for representing a downloaded file, including its MIME type, name, and content. Used with the assert_download/2 function.
```elixir
defstruct [
:mime_type, # String.t() - Content-Type header value
:name, # String.t() - filename from Content-Disposition
:content # binary() - file content
]
```
--------------------------------
### Submit form with `submit` helper
Source: https://github.com/germsvel/phoenix_test/blob/main/upgrade_guides.md
Use the `submit/1` helper to emulate pressing Enter or submitting a form without explicitly clicking a submit button. This replaces the functionality of the older `submit_form/3`.
```elixir
session
|> fill_in("Name", with: "Aragorn")
|> check("Admin")
|> select("Arnor", from: "Countries")
|> submit()
```
--------------------------------
### assert_path/3
Source: https://github.com/germsvel/phoenix_test/blob/main/_autodocs/api-assertions.md
Asserts the current path with optional query parameters and a timeout for async LiveView operations.
```APIDOC
## assert_path/3
### Description
Assert current path with optional query parameters and timeout.
### Method
Elixir Function
### Parameters
#### Path Parameters
- **session** (session) - Required - Current test session
- **path** (String.t()) - Required - Expected path
- **opts** (Keyword.t()) - Required - Options keyword list
#### Options
- **query_params** (Map) - Optional - Query parameters to match exactly (e.g., %{name: "frodo"})
- **timeout** (Integer (ms)) - Optional - Timeout for async LiveView operations
### Returns
- **session** (session) - The session unchanged if assertion passes
### Example
```elixir
# Assert path with query params
session
|> visit("/users?name=frodo")
|> assert_path("/users", query_params: %{name: "frodo"})
# Assert path after async LiveView operation
session
|> visit("/live/async_page")
|> click_button("Async patch!")
|> assert_path("/live/async_page", query_params: %{patched: "true"}, timeout: 250)
```
```
--------------------------------
### Increment Counter with LiveView
Source: https://github.com/germsvel/phoenix_test/blob/main/_autodocs/examples.md
Demonstrates a basic LiveView counter that increments on button clicks. Asserts the displayed count after each click.
```elixir
test "counter increments" do
conn
|> visit("/live/counter")
|> assert_has(".count", "0")
|> click_button("Increment")
|> assert_has(".count", "1")
|> click_button("Increment")
|> assert_has(".count", "2")
end
```
--------------------------------
### Assert Path with Query Parameters and Timeout
Source: https://github.com/germsvel/phoenix_test/blob/main/_autodocs/api-assertions.md
Use `assert_path/3` to assert the path, optionally matching specific query parameters or setting a timeout for LiveView operations.
```elixir
# Assert path with query params
session
|> visit("/users?name=frodo")
|> assert_path("/users", query_params: %{name: "frodo"})
# Assert path after async LiveView operation
session
|> visit("/live/async_page")
|> click_button("Async patch!")
|> assert_path("/live/async_page", query_params: %{patched: "true"}, timeout: 250)
```
--------------------------------
### Protocol Implementation for LiveView Handler
Source: https://github.com/germsvel/phoenix_test/blob/main/_autodocs/protocol-driver.md
Provides the specific implementation of the `PhoenixTest.Driver` protocol for the `PhoenixTest.Live` handler.
```elixir
defimpl PhoenixTest.Driver, for: PhoenixTest.Live do
def click_link(session, text) do
# LiveView-specific implementation
end
end
```
--------------------------------
### live/1
Source: https://github.com/germsvel/phoenix_test/blob/main/_autodocs/connection-handlers.md
Attempts to render a page as a LiveView using Phoenix.LiveViewTest. It returns an {:ok, view, html} tuple if the page is a LiveView, otherwise it returns :not_live_view.
```APIDOC
## live/1
### Description
Attempts to render a page as a LiveView using Phoenix.LiveViewTest.
### Method
N/A (Function Call)
### Parameters
#### Path Parameters
N/A
#### Query Parameters
N/A
#### Request Body
N/A
### Request Example
```elixir
case EndpointHelpers.live(conn) do
{:ok, view, html} -> handle_live_view(view, html)
:not_live_view -> handle_static_page(conn)
end
```
### Response
#### Success Response
- `{:ok, view, html}` — If the page is a LiveView
- `:not_live_view` — If the page is not a LiveView
```
--------------------------------
### Build Link Locator
Source: https://github.com/germsvel/phoenix_test/blob/main/_autodocs/html-query-utilities.md
Use this function to create a locator for finding links by their text content. It returns a locator object.
```elixir
def link(opts :: Keyword.t()) :: PhoenixTest.Locators.t()
Builds a locator for finding links by text.
Parameters:
| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| opts | Keyword.t() | Yes | Options keyword list |
Options:
| Option | Type | Description |
|--------|------|-------------|
| text | String.t() | Link text to match |
Returns: `PhoenixTest.Locators.t()` — A locator
```
--------------------------------
### assert_download/2
Source: https://github.com/germsvel/phoenix_test/blob/main/_autodocs/api-assertions.md
Assert helper to verify a file download. Only supports downloads with HTTP response header `Content-Type: attachment; filename=...`.
```APIDOC
## assert_download/2
### Description
Assert helper to verify a file download. Only supports downloads with HTTP response header `Content-Type: attachment; filename=...`.
### Parameters
#### Path Parameters
- **session** (session) - Required - Current test session
- **file_name** (String.t() or function()) - Required - Expected filename or assertion function
### Returns
- **session** (session) - The session unchanged if download assertion passes
### Throws
- **ExUnit.AssertionError** - No download detected or filename mismatch
### Example
```elixir
# Assert by filename
session
|> visit("/users")
|> click_link("Download avatar")
|> assert_download("avatar.jpg")
# Assert with custom function
session
|> visit("/users")
|> click_link("Download avatar")
|> assert_download(fn file ->
assert file.mime_type == "image/jpeg"
assert file.content == File.read!("expected_file.jpg")
end)
```
### Download File Object Fields
- **mime_type** (string) - The MIME type string
- **name** (string) - The downloaded filename
- **content** (binary) - The file content as binary
```
--------------------------------
### Cross-page Interaction (Static to LiveView and Back)
Source: https://github.com/germsvel/phoenix_test/blob/main/_autodocs/examples.md
Tests navigation between a static page and a LiveView page, including interaction within the LiveView and returning to the static page. Asserts content on both pages.
```elixir
test "from static page to liveview and back" do
conn
|> visit("/") # Static page
|> click_link("Live Chat")
|> assert_path("/live/chat") # LiveView page
|> fill_in("Message", with: "Hello!")
|> click_button("Send")
|> assert_has(".message", "Hello!")
|> click_link("Back Home")
|> assert_path("/") # Back to static
|> assert_has("h1", "Welcome")
end
```
--------------------------------
### Pipeable Session Operations
Source: https://github.com/germsvel/phoenix_test/blob/main/_autodocs/INDEX.md
Demonstrates chaining multiple session operations using pipes. This pattern enhances readability and maintainability for sequential actions.
```elixir
conn
|> visit("/page")
|> fill_in("Name", with: "Text")
|> click_button("Save")
|> assert_has(".success")
```
--------------------------------
### Assert Current Path with Options
Source: https://github.com/germsvel/phoenix_test/blob/main/_autodocs/protocol-driver.md
Asserts that the current path matches the provided path string, considering query parameters. Supports async timeouts for LiveView.
```elixir
def assert_path(session, path :: String.t(), opts :: Keyword.t()) :: session
```
--------------------------------
### Form Submission with Enter Key
Source: https://github.com/germsvel/phoenix_test/blob/main/_autodocs/examples.md
Demonstrates submitting a form by simulating the Enter key press instead of clicking a button.
```elixir
test "submit form with enter key" do
conn
|> visit("/search")
|> fill_in("Query", with: "Aragorn")
|> submit()
|> assert_path("/search")
|> assert_has("h2", "Search Results")
end
```
--------------------------------
### Build Live Child Session
Source: https://github.com/germsvel/phoenix_test/blob/main/_autodocs/session-structure.md
Creates a new session scoped to a child LiveView, identified by its selector. Useful for testing specific components rendered via `live_render/3`.
```elixir
def build_live_child(session :: PhoenixTest.Live.t(), selector :: String.t()) :: PhoenixTest.Live.t()
```
--------------------------------
### Form with Radio Buttons
Source: https://github.com/germsvel/phoenix_test/blob/main/_autodocs/examples.md
Demonstrates selecting a radio button option and filling in associated fields.
```elixir
test "select contact method" do
conn
|> visit("/contact-info")
|> choose("Email")
|> fill_in("Email Address", with: "user@example.com")
|> click_button("Save")
|> assert_has(".success", "Contact method updated")
end
```
--------------------------------
### Protocol Implementation for Static Handler
Source: https://github.com/germsvel/phoenix_test/blob/main/_autodocs/protocol-driver.md
Provides the specific implementation of the `PhoenixTest.Driver` protocol for the `PhoenixTest.Static` handler.
```elixir
defimpl PhoenixTest.Driver, for: PhoenixTest.Static do
def click_link(session, text) do
# Static-specific implementation
end
end
```
--------------------------------
### Upload File with Options or Selector
Source: https://github.com/germsvel/phoenix_test/blob/main/_autodocs/api-main-functions.md
Extends `upload/3` to include optional exact matching or the ability to specify the file input using a CSS selector. Use when the file input is not easily identifiable by its label.
```elixir
def upload(session, label :: String.t(), path :: String.t(), opts :: Keyword.t()) :: session
```
```elixir
def upload(session, input_selector :: String.t(), label :: String.t(), path :: String.t()) :: session
```
--------------------------------
### Form with File Upload
Source: https://github.com/germsvel/phoenix_test/blob/main/_autodocs/examples.md
Tests uploading a file through a form, specifying the input name and the file path.
```elixir
test "upload avatar" do
user = insert(:user)
conn
|> visit("/users/#{user.id}/edit")
|> upload("Avatar", "test/fixtures/avatar.jpg")
|> click_button("Save")
|> assert_has(".alert-success", "Profile updated")
end
```
--------------------------------
### Assert File Download Occurred
Source: https://github.com/germsvel/phoenix_test/blob/main/_autodocs/protocol-driver.md
Asserts that a file download occurred, verifying the filename. Primarily for static sessions; less common for LiveView.
```elixir
def assert_download(session, file_name :: String.t() | function()) :: session
```
--------------------------------
### Open Browser for Debugging
Source: https://github.com/germsvel/phoenix_test/blob/main/_autodocs/api-main-functions.md
Opens the default browser to display the current HTML of the session. Useful for debugging test failures.
```elixir
def open_browser(session) :: session
```
```elixir
session
|> visit("/")
|> fill_in("Name", with: "Aragorn")
|> open_browser()
|> submit()
```
--------------------------------
### choose/2
Source: https://github.com/germsvel/phoenix_test/blob/main/_autodocs/protocol-driver.md
Chooses a radio button identified by its label.
```APIDOC
## choose/2
### Description
Chooses a radio button by label.
### Method
(Implicitly invoked via Elixir function call)
### Parameters
#### Path Parameters
None
#### Query Parameters
None
#### Request Body
None
### Parameters
- **session**: The current session object.
- **label** (String.t()): The label of the radio button to choose.
### Response
- **session**: The updated session object.
```
--------------------------------
### open_browser/2
Source: https://github.com/germsvel/phoenix_test/blob/main/_autodocs/protocol-driver.md
Opens the browser with a custom function, allowing for more control over what is displayed.
```APIDOC
## open_browser/2
### Description
Opens the browser with a custom function.
### Signature
```elixir
def open_browser(session, open_fun :: function()) :: session
```
### Parameters
#### Path Parameters
- **session** (any) - The current session.
- **open_fun** (function()) - A function that returns the content to be displayed in the browser.
### Returns
- **session** (any) - The session.
```
--------------------------------
### LiveView Live Patch for URL Updates
Source: https://github.com/germsvel/phoenix_test/blob/main/_autodocs/examples.md
Shows how `live_patch` can update the URL with query parameters without a full page reload. Asserts the URL and content after triggering the patch.
```elixir
test "live patch updates URL without leaving page" do
conn
|> visit("/live/posts")
|> click_link("Show Filters")
|> assert_path("/live/posts", query_params: %{show_filters: "true"})
|> assert_has(".filters", text: "Advanced Filters")
end
```
--------------------------------
### Credo Configuration for NoOpenBrowser
Source: https://github.com/germsvel/phoenix_test/blob/main/_autodocs/advanced-features.md
Add this Credo rule to your `.credo.exs` file to prevent `open_browser/1` calls from appearing in production code.
```elixir
{
PhoenixTest.Credo.NoOpenBrowser,
[]
}
```
--------------------------------
### Unwrap for Static Page Operations
Source: https://github.com/germsvel/phoenix_test/blob/main/_autodocs/advanced-features.md
Use `unwrap/2` to perform custom static page testing operations. The function passed must return a `Plug.Conn.t()` struct, and redirects are handled automatically.
```elixir
session
|> unwrap(fn conn ->
conn
|> Phoenix.ConnTest.recycle()
|> post("/custom-endpoint", %{"data" => "value"})
end)
```
--------------------------------
### Navigation with Redirect
Source: https://github.com/germsvel/phoenix_test/blob/main/_autodocs/examples.md
Verifies that unauthorized access to a protected path redirects to the login page.
```elixir
test "unauthorized access redirects to login" do
conn
|> visit("/admin")
|> assert_path("/login")
|> assert_has("h1", "Login")
end
```
--------------------------------
### LiveView Search with phx-change
Source: https://github.com/germsvel/phoenix_test/blob/main/_autodocs/examples.md
Shows how LiveView's `phx-change` attribute can update results dynamically as the user types in a search input. Asserts the number of results after partial input.
```elixir
test "search updates as you type" do
conn
|> visit("/live/search")
|> fill_in("Query", with: "a")
|> assert_has(".results-count", "15") # Results update automatically
|> fill_in("Query", with: "ar")
|> assert_has(".results-count", "3")
end
```
--------------------------------
### PhoenixTest FileDownload Struct Definition
Source: https://github.com/germsvel/phoenix_test/blob/main/_autodocs/advanced-features.md
Defines the structure for representing a downloaded file, including its MIME type, name, and content.
```elixir
defstruct [
:mime_type, # The MIME type from Content-Type header
:name, # The filename from Content-Disposition header
:content # The file content as binary
]
```
--------------------------------
### Assert File Download by Filename
Source: https://github.com/germsvel/phoenix_test/blob/main/_autodocs/api-assertions.md
Verifies a file download by matching the expected filename. Requires the download to have a 'Content-Type: attachment; filename=...' header.
```elixir
session
|> visit("/users")
|> click_link("Download avatar")
|> assert_download("avatar.jpg")
```
--------------------------------
### assert_download/2
Source: https://github.com/germsvel/phoenix_test/blob/main/_autodocs/protocol-driver.md
Asserts that a file download occurred. For Static sessions, it checks the Content-Disposition header and verifies the filename. For LiveView, it's not typically used.
```APIDOC
## assert_download/2
### Description
Asserts that a file download occurred.
### Signature
```elixir
def assert_download(session, file_name :: String.t() | function()) :: session
```
### Parameters
#### Path Parameters
- **session** (any) - The current session.
- **file_name** (String.t() | function()) - The expected name of the downloaded file, or a function to determine it.
### Handling by Live
- Not typically used (LiveView rarely downloads directly)
### Handling by Static
- Checks Content-Disposition header
- Verifies filename matches
- Returns FileDownload struct for assertions
### Returns
- **session** (any) - The session.
```
--------------------------------
### PhoenixTest.Live Session Structure
Source: https://github.com/germsvel/phoenix_test/blob/main/_autodocs/session-structure.md
Defines the fields for a Live session, used for testing LiveView pages. It includes the LiveView test view, watcher, connection, form state, scope, current path, and operation tracking.
```elixir
defstruct [
:view,
:watcher,
:conn,
:active_form,
:within,
:current_path,
:current_operation
]
```
--------------------------------
### Check Checkbox with Selector and Options
Source: https://github.com/germsvel/phoenix_test/blob/main/_autodocs/api-main-functions.md
Use `check/4` to specify both a CSS selector for the checkbox and options like exact label matching.
```elixir
def check(session, checkbox_selector :: String.t(), label :: String.t(), opts :: Keyword.t()) :: session
```
```elixir
session |> check("#form-1 input", "Admin", exact: false)
```
--------------------------------
### link/1
Source: https://github.com/germsvel/phoenix_test/blob/main/_autodocs/html-query-utilities.md
Builds a locator for finding links by text. It accepts an options keyword list, where the 'text' option can be used to match the link's text.
```APIDOC
## link/1
### Description
Builds a locator for finding links by text.
### Method
`link(opts :: Keyword.t())`
### Parameters
#### Path Parameters
None
#### Query Parameters
None
#### Request Body
None
### Parameters
#### Options
- **text** (String.t()) - Optional - Link text to match
### Returns
`PhoenixTest.Locators.t()` — A locator
### Example
```elixir
locator = Locators.link(text: "Click Here")
Query.find_by_role!(html, locator)
```
```
--------------------------------
### Runtime Endpoint Configuration
Source: https://github.com/germsvel/phoenix_test/blob/main/_autodocs/overview.md
Configures the PhoenixTest endpoint at runtime using `Phoenix.ConnTest.build_conn/0` and `PhoenixTest.put_endpoint/2`.
```elixir
setup tags do
{:ok, conn: Phoenix.ConnTest.build_conn() |> PhoenixTest.put_endpoint(MyAppWeb.Endpoint)}
end
```
--------------------------------
### Upload File with Options
Source: https://github.com/germsvel/phoenix_test/blob/main/_autodocs/protocol-driver.md
Uploads a file to a file input field, with options for exact matching or a specific CSS selector. This allows for more precise targeting of file upload fields.
```elixir
def upload(session, label :: String.t(), path :: String.t(), opts :: Keyword.t()) :: session
```
```elixir
def upload(session, selector :: String.t(), label :: String.t(), path :: String.t()) :: session
```
--------------------------------
### Unwrap Native Structure for LiveViews and Static Pages
Source: https://github.com/germsvel/phoenix_test/blob/main/_autodocs/api-main-functions.md
Provides an escape hatch to access the underlying native data structure (LiveView's `view` or static page's `conn`). The function must return the result of a `render_*` action for LiveViews or a `conn` struct for static pages. Handles redirects.
```elixir
def unwrap(session, fun :: function()) :: session
```
```elixir
# In a LiveView
session
|> unwrap(fn view ->
view
|> element("#hook")
|> render_hook(:hook_event, %{name: "Legolas"})
end)
# In a static page
session
|> unwrap(fn conn ->
conn |> Phoenix.ConnTest.recycle()
end)
```
--------------------------------
### Open Browser for Debugging
Source: https://github.com/germsvel/phoenix_test/blob/main/_autodocs/advanced-features.md
Opens the default browser to display the current HTML state of the session. Useful for debugging test failures and visualizing form structures.
```elixir
session
|> visit("/form")
|> fill_in("Name", with: "Aragorn")
|> open_browser()
|> submit()
```
--------------------------------
### button/1
Source: https://github.com/germsvel/phoenix_test/blob/main/_autodocs/html-query-utilities.md
Builds a locator for finding buttons by text and other attributes. It accepts an options keyword list, where the 'text' option can be used to match the button's text.
```APIDOC
## button/1
### Description
Builds a locator for finding buttons by text and other attributes.
### Method
`button(opts :: Keyword.t())`
### Parameters
#### Path Parameters
None
#### Query Parameters
None
#### Request Body
None
### Parameters
#### Options
- **text** (String.t()) - Optional - Button text to match
### Returns
`PhoenixTest.Locators.t()` — A locator for use with query functions
### Example
```elixir
locator = Locators.button(text: "Delete")
Query.find_by_role!(html, locator)
```
```
--------------------------------
### assert_path/3
Source: https://github.com/germsvel/phoenix_test/blob/main/_autodocs/protocol-driver.md
Asserts that the current page path matches the specified path with options.
```APIDOC
## assert_path/3
### Description
Asserts that the current page path matches the specified path with options.
### Signature
```elixir
def assert_path(session, path :: String.t(), opts :: Keyword.t()) :: session
```
### Parameters
#### Path Parameters
- **session** (any) - The current session.
- **path** (String.t()) - The expected path.
- **opts** (Keyword.t()) - A keyword list of options to refine the assertion.
### Options
- `query_params`: Expected query parameters
- `timeout`: Async timeout (LiveView only)
### Returns
- **session** (any) - The session.
```
--------------------------------
### Unwrap Session for Advanced Operations
Source: https://github.com/germsvel/phoenix_test/blob/main/_autodocs/protocol-driver.md
Provides access to the underlying native structure for advanced operations. Use for LiveView or Static sessions.
```elixir
def unwrap(session, fun :: function()) :: session
```
--------------------------------
### Assert File Download in PhoenixTest
Source: https://github.com/germsvel/phoenix_test/blob/main/_autodocs/advanced-features.md
Use `assert_download/2` to verify that a file has been downloaded. It can take a filename or a function for custom assertions on the downloaded file's properties.
```elixir
session
|> visit("/users")
|> click_link("Download CSV")
|> assert_download("users.csv")
# With custom assertions
session
|> visit("/users")
|> click_link("Download JSON")
|> assert_download(fn file ->
assert file.mime_type == "application/json"
assert file.name == "users.json"
assert file.content |> Jason.decode!() |> is_map()
end)
```
--------------------------------
### PhoenixTest.Live Session Structure
Source: https://github.com/germsvel/phoenix_test/blob/main/_autodocs/types-and-structures.md
Defines the structure for a LiveView page session. Used in all LiveView page tests.
```elixir
defstruct [
:view, # Phoenix.LiveViewTest.View.t()
:watcher, # PID of LiveViewWatcher
:conn, # Plug.Conn.t()
:active_form, # PhoenixTest.ActiveForm.t()
:within, # atom() | String.t() - :none or selector
:current_path, # String.t()
:current_operation # PhoenixTest.Operation.t()
]
```
--------------------------------
### Fill Text Inputs and Textareas by Label
Source: https://github.com/germsvel/phoenix_test/blob/main/_autodocs/api-main-functions.md
Use `fill_in/3` to fill text inputs and textareas by their associated label text. It supports exact or partial label matching and triggers LiveView events if applicable.
```elixir
session
|> fill_in("Name", with: "Aragorn")
|> fill_in("Email", with: "aragorn@dunedain.com")
|> fill_in("Name", with: "Ara", exact: false) # Matches "Name *"
```
--------------------------------
### submit/1
Source: https://github.com/germsvel/phoenix_test/blob/main/_autodocs/api-main-functions.md
Submits a pre-filled form without requiring a button click, emulating pressing Enter. This is useful for triggering form submissions, including LiveView's `phx-submit` event.
```APIDOC
## submit/1
### Description
Submits a pre-filled form without clicking a button, emulating pressing Enter. For LiveView forms with `phx-submit`, triggers that event. Otherwise submits the form normally. Includes any hidden inputs and default data in the payload.
### Method
Not applicable (Elixir function)
### Endpoint
Not applicable (Elixir function)
### Parameters
#### Path Parameters
None
#### Query Parameters
None
#### Request Body
None
### Parameters
- **session** (session) - Required - Current test session
### Returns
- **session** (session) - Updated session after form submission
### Request Example
```elixir
session
|> fill_in("Name", with: "Aragorn")
|> choose("Email")
|> submit()
```
```
--------------------------------
### Choose Radio Button with Options or Selector
Source: https://github.com/germsvel/phoenix_test/blob/main/_autodocs/api-main-functions.md
Extends `choose/2` to allow for exact matching options or specifying a radio button via its CSS selector. Use when precise control over selection is needed.
```elixir
def choose(session, label :: String.t(), opts :: Keyword.t()) :: session
```
```elixir
def choose(session, radio_selector :: String.t(), label :: String.t()) :: session
```
```elixir
session |> choose("Email", exact: false)
```
```elixir
session |> choose("#fieldset-1 input", "Email")
```
--------------------------------
### unwrap/2
Source: https://github.com/germsvel/phoenix_test/blob/main/_autodocs/api-main-functions.md
Escape hatch to give access to the underlying "native" data structure (either the `view` from Phoenix.LiveViewTest for LiveViews, or the `conn` struct for static pages). The function must return the result of a `render_*` action for LiveViews or a `conn` struct for static pages.
```APIDOC
## unwrap/2
### Description
Escape hatch to give access to the underlying "native" data structure (either the `view` from Phoenix.LiveViewTest for LiveViews, or the `conn` struct for static pages). The function must return the result of a `render_*` action for LiveViews or a `conn` struct for static pages.
### Function Signature
def unwrap(session, fun :: function()) :: session
### Parameters
#### Path Parameters
- **session** (session) - Required - Current test session
- **fun** ((native -> native)) - Required - Function to execute with native struct
### Returns
- **session** (session) - Updated session after native action (handles redirects)
### Example
```elixir
# In a LiveView
session
|> unwrap(fn view ->
view
|> element("#hook")
|> render_hook(:hook_event, %{name: "Legolas"})
end)
# In a static page
session
|> unwrap(fn conn ->
conn |> Phoenix.ConnTest.recycle()
end)
```
```
--------------------------------
### Select Dropdown Options by Label
Source: https://github.com/germsvel/phoenix_test/blob/main/_autodocs/api-main-functions.md
Use `select/3` to choose an option from a select dropdown, targeting it by its label. Supports exact or partial matching for both label and option text.
```elixir
session
|> select("Race", option: "Human")
|> select("Race", option: "Human", exact: false)
|> select("Race", option: "Huma", exact_option: false)
```