### 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) ```