### Install Playwright and Browsers (npm) Source: https://hexdocs.pm/phoenix_test_playwright/0.8.0/phoenix_test_playwright/PhoenixTest These npm commands are used to install Playwright as a development dependency and then install the necessary browser binaries for Playwright to use. This is a prerequisite for running Playwright tests. ```bash npm --prefix assets i -D playwright npm --prefix assets exec -- playwright install chromium --with-deps ``` -------------------------------- ### Playwright Test with Browser Session (PhoenixTest.Playwright.Case) Source: https://hexdocs.pm/phoenix_test_playwright/0.8.0/phoenix_test_playwright/PhoenixTest This example demonstrates using `PhoenixTest.Playwright.Case` to interact with a browser session. It highlights that `conn` in this context is a Playwright session, not a `Plug.Conn`, allowing for browser-specific actions like visiting a URL and evaluating JavaScript in the browser console. ```elixir defmodule MyTest do use PhoenixTest.Playwright.Case, async: true # `conn` isn't a `Plug.Conn` but a Playwright session. # We use the name `conn` anyway so you can easily switch `PhoenixTest` drivers. test "in browser", %{conn: conn} do conn |> visit(~p"/") |> unwrap(&Frame.evaluate(&1.frame_id, "console.log('Hey')")) end ``` -------------------------------- ### Run Feature Tests with PhoenixTestPlaywright Source: https://hexdocs.pm/phoenix_test_playwright/0.8.0/phoenix_test_playwright/PhoenixTest This example demonstrates how to define and run feature tests using PhoenixTest.Playwright.Case. It showcases asynchronous test execution, parameterization for different browsers, controlling browser visibility and speed, and basic interaction with a web page including navigation, form filling, and assertions. Dependencies include `PhoenixTest.Playwright.Case`. ```elixir defmodule Features.RegisterTest do use PhoenixTest.Playwright.Case, async: true, parameterize: [ %{browser: :chromium}, %{browser: :firefox} ], headless: false, slow_mo: :timer.seconds(1) @tag trace: :open test "register", %{conn: conn} do conn |> visit(~p"/") |> click_link("Register") |> fill_in("Email", with: "f@ftes.de") |> click_button("Create an account") |> assert_has(".text-rose-600", text: "required") |> screenshot("error.png", full_page: true) end end ``` -------------------------------- ### Override Playwright Test Options (headless, slow_mo) Source: https://hexdocs.pm/phoenix_test_playwright/0.8.0/phoenix_test_playwright/PhoenixTest This example shows how to override global Playwright configuration options directly within a test module. Here, `headless` is set to `false` to display the browser window, and `slow_mo` introduces a delay between interactions for debugging purposes. ```elixir defmodule DebuggingFeatureTest do use PhoenixTest.Playwright.Case, async: true, # Show browser and pause 1 second between every interaction headless: false, slow_mo: :timer.seconds(1) end ``` -------------------------------- ### Add PhoenixTestPlaywright Dependency (mix.exs) Source: https://hexdocs.pm/phoenix_test_playwright/0.8.0/phoenix_test_playwright/PhoenixTest This snippet shows how to add the `phoenix_test_playwright` dependency to your `mix.exs` file. It's configured to be used only during testing and doesn't require runtime functionality. ```elixir defmodule MyProject.Mixfile do use Mix def project do [ # ... other project configurations deps: deps() ] end def deps do [ {:phoenix_test_playwright, "~> 0.4", only: :test, runtime: false} # ... other dependencies ] end end ``` -------------------------------- ### Handle Browser Dialogs with PhoenixTest Source: https://hexdocs.pm/phoenix_test_playwright/0.8.0/phoenix_test_playwright/PhoenixTest This snippet shows how to handle browser dialogs (alert, confirm, prompt) using `with_dialog`. It takes a callback function that determines how to respond to each dialog. Tests using this function should include the `@tag accept_dialogs: false` to prevent default acceptance. ```elixir @tag accept_dialogs: false test "conditionally handle dialog", %{conn: conn} do conn |> visit("/") |> with_dialog( fn %{message: "Are you sure?"} -> :accept %{message: "Enter the magic number"} -> {:accept, "42"} %{message: "Self destruct?"} -> :dismiss end, fn conn -> conn |> click_button("Delete") |> assert_has(".flash", text: "Deleted") end ) end ``` -------------------------------- ### Configure PhoenixTest for Playwright (config/test.exs) Source: https://hexdocs.pm/phoenix_test_playwright/0.8.0/phoenix_test_playwright/PhoenixTest This configuration block in `config/test.exs` sets up the `phoenix_test` application, specifying the OTP app and providing Playwright-specific options. These options control browser behavior like the default browser, headless mode, JavaScript logging, screenshotting, tracing, and timeouts. ```elixir config :phoenix_test, otp_app: :your_app, playwright: [ browser: :chromium, headless: System.get_env("PW_HEADLESS", "true") in ~w(t true), js_logger: false, screenshot: System.get_env("PW_SCREENSHOT", "false") in ~w(t true), trace: System.get_env("PW_TRACE", "false") in ~w(t true), browser_launch_timeout: 10_000, ] ``` -------------------------------- ### Manually Capture Screenshots Source: https://hexdocs.pm/phoenix_test_playwright/0.8.0/phoenix_test_playwright/PhoenixTest This Elixir code demonstrates how to capture a screenshot of the entire page using the `screenshot/2` function. The screenshot is saved to a file named 'home.png'. ```elixir |> visit(~p"/") |> screenshot("home.png") # captures entire page by default, not just viewport ``` -------------------------------- ### Take Screenshots with PhoenixTest Source: https://hexdocs.pm/phoenix_test_playwright/0.8.0/phoenix_test_playwright/PhoenixTest This snippet demonstrates how to take screenshots using the `screenshot` function in PhoenixTest. It allows specifying the filename and path for the saved image. No specific dependencies are mentioned beyond the PhoenixTest library itself. ```elixir |> screenshot("my-screenshot.png") |> screenshot("my-test/my-screenshot.jpg") ``` -------------------------------- ### Wait for LiveView Connection Source: https://hexdocs.pm/phoenix_test_playwright/0.8.0/phoenix_test_playwright/PhoenixTest This Elixir code snippet shows how to ensure a LiveView connection is established before proceeding with further test actions. It uses `visit` to navigate to the page and `assert_has` to wait for the presence of an element indicating a connected LiveView (`body .phx-connected`). ```elixir |> visit(~p"/") |> assert_has("body .phx-connected") # now continue, playwright has waited for LiveView to connect ``` -------------------------------- ### Custom Playwright Feature: Assert File Download Source: https://hexdocs.pm/phoenix_test_playwright/0.8.0/phoenix_test_playwright/PhoenixTest This Elixir function asserts that a file download has occurred with a specific filename and content. It listens for the Playwright 'download' event, waits for the file to be written to disk, and then verifies its name and content. It uses a helper function `wait_for_file` to handle asynchronous file creation. ```elixir # In your test, first call `|> tap(&Connection.subscribe(&1.page_id))` def assert_download(conn, name, contains: content) do assert_receive({:playwright, %{method: :download} = download_msg}, 2000) path = Connection.initializer(download_msg.params.artifact.guid).absolute_path wait_for_file(path) assert download_msg.params.suggested_filename =~ name assert File.read!(path) =~ content conn end ``` -------------------------------- ### Using Ecto SQL Sandbox with Playwright Tests Source: https://hexdocs.pm/phoenix_test_playwright/0.8.0/phoenix_test_playwright/PhoenixTest This snippet shows how PhoenixTest.Playwright.Case automatically handles Ecto SQL Sandbox for concurrent browser tests. It ensures that each test runs in isolation by providing a user agent referencing your Ecto repositories, preventing data interference between tests. ```elixir defmodule MyTest do use PhoenixTest.Playwright.Case, async: true end ``` -------------------------------- ### Generic Playwright Assertion Helper Source: https://hexdocs.pm/phoenix_test_playwright/0.8.0/phoenix_test_playwright/PhoenixTest This is a generic helper function for Playwright assertions. It takes connection parameters and options, unwraps the Playwright frame, performs an expectation, and asserts the result. It supports negating the assertion using the `:is_not` option. ```elixir def assert_found(conn, params, opts \ []) do is_not = Keyword.get(opts, :is_not, false) params = Enum.into(params, %{is_not: is_not}) unwrap(conn, fn frame_id -> {:ok, found} = Frame.expect(frame_id, params) if is_not, do: refute(found), else: assert(found) end) end ``` -------------------------------- ### Verify Email HTML with Plug.Swoosh.MailboxPreview Source: https://hexdocs.pm/phoenix_test_playwright/0.8.0/phoenix_test_playwright/PhoenixTest This Elixir code demonstrates how to interact with and verify the content of emails sent via `Plug.Swoosh` within a Playwright test. It involves navigating to the mailbox preview, clicking on a specific email, and then interacting with elements within an iframe to confirm actions and assert expected flash messages. ```elixir |> visit(~p"/dev/mailbox") |> click_link("Confirmation instructions") |> within("iframe >> internal:control=enter-frame", fn conn -> conn |> click_link("Confirm account") |> click_button("Confirm my account") |> assert_has("#flash-info", text: "User confirmed") end) ``` -------------------------------- ### Simulate Typing with PhoenixTest Source: https://hexdocs.pm/phoenix_test_playwright/0.8.0/phoenix_test_playwright/PhoenixTest This function simulates user typing into a specified element. It supports an optional `:delay` option to control the time between key presses. The function takes a selector and the text to type as input. It's recommended to use `PhoenixTest.fill_in/4` in most cases. ```elixir @spec type(t(), selector(), String.t(), [{:delay, non_neg_integer()}]) :: t() |> type("#id", "some text") |> type(Selector.role("heading", "Untitled", exact: true), "New title") ``` -------------------------------- ### Add Session Cookie for Emulation - Elixir Source: https://hexdocs.pm/phoenix_test_playwright/0.8.0/phoenix_test_playwright/PhoenixTest Adds a Plug.Session cookie to the browser context, useful for emulating logged-in users. The cookie's :value must be a map, and session_options are identical to those used when writing plug Plug.Session. ```elixir add_session_cookie(conn, cookie, session_options) ``` -------------------------------- ### Helper Function to Wait for File Existence Source: https://hexdocs.pm/phoenix_test_playwright/0.8.0/phoenix_test_playwright/PhoenixTest This recursive Elixir function waits for a file to exist at the given path. It checks for the file's existence periodically with a specified `wait_for_ms` interval, up to a maximum `remaining_ms`. If the file does not exist within the time limit, it raises a 'flunk' error. ```elixir defp wait_for_file(path, remaining_ms \ 2000, wait_for_ms \ 100) defp wait_for_file(path, remaining_ms, _) when remaining_ms <= 0, do: flunk("File #{path} does not exist") defp wait_for_file(path, remaining_ms, wait_for_ms) do if File.exists?(path) do :ok else Process.sleep(wait_for_ms) wait_for_file(path, remaining_ms - wait_for_ms, wait_for_ms) end end ``` -------------------------------- ### Handle Browser Dialogs - Elixir Source: https://hexdocs.pm/phoenix_test_playwright/0.8.0/phoenix_test_playwright/PhoenixTest Manages browser dialogs (alert, confirm, prompt) by executing a callback function while the dialog is active. This is useful for automating interactions with these native browser prompts. ```elixir with_dialog(session, callback, fun) ``` -------------------------------- ### Handle Test Failures in CI (Timeout) Source: https://hexdocs.pm/phoenix_test_playwright/0.8.0/phoenix_test_playwright/PhoenixTest This section provides strategies for addressing test timeouts in CI environments. It suggests limiting test concurrency, increasing the Playwright timeout configuration, and utilizing more powerful CI runners. ```bash # Limit concurrency for GitHub CI shared runners mix test --max-cases 1 ``` ```elixir # Increase timeout configuration config :phoenix_test, playwright: [timeout: :timer.seconds(4)] ``` -------------------------------- ### Simulate Key Presses in Browser - Elixir Source: https://hexdocs.pm/phoenix_test_playwright/0.8.0/phoenix_test_playwright/PhoenixTest Focuses an element and simulates pressing keyboard keys. Supports special keys, modifiers, and combinations. Use type/4 for simple text input without special keys. ```elixir press(conn, selector, key, opts \\ []) ## Options * `:delay` (`non_neg_integer/0`) - Time to wait between keydown and keyup in milliseconds. The default value is `0`. ## Examples ```elixir |> press("#id", "Control+Shift+T") |> press(Selector.button("Submit", exact: true), "Enter") ``` ``` -------------------------------- ### Take Page Screenshot - Elixir Source: https://hexdocs.pm/phoenix_test_playwright/0.8.0/phoenix_test_playwright/PhoenixTest Captures a screenshot of the current page and saves it to a specified file path. The file type is determined by the extension, and saving location is configured via :screenshot_dir in PhoenixTest.Playwright.Config. ```elixir screenshot(conn, file_path, opts \\ []) ``` -------------------------------- ### Simulate User Typing - Elixir Source: https://hexdocs.pm/phoenix_test_playwright/0.8.0/phoenix_test_playwright/PhoenixTest Focuses on a specified element and simulates user typing. This function is intended for basic text input without the need to press special keys. ```elixir type(conn, selector, text, opts \\ []) ``` -------------------------------- ### Manually Record and Open Playwright Trace Source: https://hexdocs.pm/phoenix_test_playwright/0.8.0/phoenix_test_playwright/PhoenixTest This Elixir test snippet uses the `@tag trace: :open` attribute to automatically record a Playwright trace during test execution and open it in the Playwright trace viewer upon completion. This is useful for interactive debugging. ```elixir @tag trace: :open test "record a trace and open it automatically in the viewer" do # test body here end ``` -------------------------------- ### Custom Playwright Feature: Accessibility Audit Source: https://hexdocs.pm/phoenix_test_playwright/0.8.0/phoenix_test_playwright/PhoenixTest This Elixir function performs an accessibility audit on the current frame using axe-core. It evaluates the accessibility rules, processes the results, and asserts that no violations were found. This requires the 'A11yAudit' library. ```elixir defp assert_a11y(conn) do Frame.evaluate(conn.frame_id, A11yAudit.JS.axe_core()) results = conn.frame_id |> Frame.evaluate("axe.run()") |> A11yAudit.Results.from_json() A11yAudit.Assertions.assert_no_violations(results) conn end ``` -------------------------------- ### Helper Function to Interact Within an Iframe Source: https://hexdocs.pm/phoenix_test_playwright/0.8.0/phoenix_test_playwright/PhoenixTest This Elixir function provides a convenient way to execute operations within an iframe. It takes an optional iframe selector (defaulting to 'iframe') and a function to execute. It uses `within` to enter the frame context before executing the provided function. ```elixir defp within_iframe(selector \ "iframe", fun) when is_function(fun, 1) do within("#{selector} >> internal:control=enter-frame", fun) end ``` -------------------------------- ### Unwrap Playwright IDs with PhoenixTest Source: https://hexdocs.pm/phoenix_test_playwright/0.8.0/phoenix_test_playwright/PhoenixTest The `unwrap` function allows invoking a provided function with Playwright IDs (context, page, frame). This is useful for interacting directly with Playwright's underlying objects for advanced operations. The function takes a Playwright session and a callback function. ```elixir @spec unwrap(t(), (%{context_id: any(), page_id: any(), frame_id: any()} -> any())) :: t() |> unwrap(&Frame.evaluate(&1.frame_id, "console.log('Hey')")) ``` -------------------------------- ### Assert LiveComponent Connection with Playwright Source: https://hexdocs.pm/phoenix_test_playwright/0.8.0/phoenix_test_playwright/PhoenixTest This snippet demonstrates how to assert that a LiveComponent has connected using Playwright. It checks for the presence of a 'data-connected' attribute on a specific element. This is useful for ensuring dynamic content loaded by LiveComponents is available before proceeding with further interactions. ```elixir
``` |> visit(~p"/") |> assert_has("#my-component[data-connected]") # now continue, playwright has waited for LiveComponent to connect ``` ``` -------------------------------- ### Set Base URL for Playwright Tests (test/test_helpers.exs) Source: https://hexdocs.pm/phoenix_test_playwright/0.8.0/phoenix_test_playwright/PhoenixTest This configuration in `test/test_helpers.exs` sets the base URL for Playwright tests by retrieving it from the application environment. This is crucial for Playwright to know where to direct browser actions. ```elixir Application.put_env(:phoenix_test, :base_url, YourAppWeb.Endpoint.url()) ``` -------------------------------- ### Automatically Capture Traces for Failed Tests in CI Source: https://hexdocs.pm/phoenix_test_playwright/0.8.0/phoenix_test_playwright/PhoenixTest This configuration in `config/test.exs` enables Playwright tracing based on the `PW_TRACE` environment variable. The accompanying GitHub Actions workflow snippet (`.github/workflows/elixir.yml`) shows how to conditionally run tests with tracing enabled only when a previous test run fails, aiding in CI debugging. ```elixir # config/test.exs config :phoenix_test, playwright: [trace: System.get_env("PW_TRACE", "false") in ~w(t true)] ``` ```yaml # .github/workflows/elixir.yml run: "mix test || if [[ $? = 2 ]]; then PW_TRACE=true mix test --failed; else false; fi" ``` -------------------------------- ### Automatically Capture Screenshots for Failed Tests in CI Source: https://hexdocs.pm/phoenix_test_playwright/0.8.0/phoenix_test_playwright/PhoenixTest This configuration in `config/test.exs` enables Playwright screenshotting based on the `PW_SCREENSHOT` environment variable. The GitHub Actions workflow snippet (`.github/workflows/elixir.yml`) shows how to conditionally run tests with screenshotting enabled only for failed tests in CI, useful for diagnosing test failures. ```elixir # config/test.exs config :phoenix_test, playwright: [screenshot: System.get_env("PW_SCREENSHOT", "false") in ~w(t true)] ``` ```yaml # .github/workflows/elixir.yml run: "mix test || if [[ $? = 2 ]]; then PW_SCREENSHOT=true mix test --failed; else false; fi" ``` -------------------------------- ### Click Element in Browser - Elixir Source: https://hexdocs.pm/phoenix_test_playwright/0.8.0/phoenix_test_playwright/PhoenixTest Clicks an element that is not a link or button. For links or buttons, use click_link/4 and click_button/4 respectively. Supports exact text matching via an :exact option. ```elixir click(conn, selector, text, opts \\ []) ## Options * `:exact` (`boolean/0`) - Exact or substring text match. The default value is `false`. ## Examples ```elixir |> click(Selector.menuitem("Edit", exact: true)) |> click("summary", "(expand)", exact: false) ``` ``` -------------------------------- ### Generic Selector Type Definition - Elixir Source: https://hexdocs.pm/phoenix_test_playwright/0.8.0/phoenix_test_playwright/PhoenixTest Defines a generic selector type that can accept either a Playwright selector or a CSS selector. This provides flexibility in how elements are targeted within tests. ```elixir @type selector() :: playwright_selector() | css_selector() ``` -------------------------------- ### Add Cookies to Browser Context - Elixir Source: https://hexdocs.pm/phoenix_test_playwright/0.8.0/phoenix_test_playwright/PhoenixTest Adds cookies to the browser context using Plug.Conn.put_resp_cookie/3. This function is not suitable for signed Plug.Session cookies. Refer to PhoenixTest.Playwright.CookieArgs for cookie types. ```elixir add_cookies(conn, cookies) ``` -------------------------------- ### Custom Playwright Feature: Assert Checkbox or Radio Button is Chosen Source: https://hexdocs.pm/phoenix_test_playwright/0.8.0/phoenix_test_playwright/PhoenixTest This Elixir function asserts that a checkbox or radio button associated with a given label is checked. It utilizes Playwright selectors to find the input element by its label and verifies that it has the 'checked' attribute. ```elixir def assert_is_chosen(conn, label, opts \ []) do opts = Keyword.validate!(opts, exact: true) assert_found(conn, selector: Selector.label(label, opts), expression: "to.have.attribute", expressionArg: "checked" ) end ``` -------------------------------- ### Custom Playwright Feature: Styled Radio Button Selection Source: https://hexdocs.pm/phoenix_test_playwright/0.8.0/phoenix_test_playwright/PhoenixTest This Elixir function provides a custom way to select a styled radio button that uses a hidden input. It finds the radio button by its label text and clicks it, abstracting the underlying DOM interaction. ```elixir def choose_styled_radio_with_hidden_input_button(session, label, opts \ []) do opts = Keyword.validate!(opts, exact: true) click(Selector.text(label, opts)) end ``` -------------------------------- ### Custom Playwright Feature: Refute Input Element is Editable Source: https://hexdocs.pm/phoenix_test_playwright/0.8.0/phoenix_test_playwright/PhoenixTest This Elixir function asserts that an input element, identified by its label, is NOT editable. It uses Playwright selectors and Negation to verify that the input does not have the 'editable' state. ```elixir def refute_is_editable(conn, label, opts \ []) do opts = Keyword.validate!(opts, exact: true) assert_found( conn, [ selector: Selector.label(label, opts), expression: "to.be.editable" ], is_not: true ) end ``` -------------------------------- ### Custom Playwright Feature: Assert Input Element is Editable Source: https://hexdocs.pm/phoenix_test_playwright/0.8.0/phoenix_test_playwright/PhoenixTest This Elixir function asserts that an input element, identified by its label, is editable. It uses Playwright selectors to target the input and checks if it has the 'editable' state. ```elixir def assert_is_editable(conn, label, opts \ []) do opts = Keyword.validate!(opts, exact: true) assert_found(conn, selector: Selector.label(label, opts), expression: "to.be.editable" ) end ``` -------------------------------- ### Playwright Selector Type Definition - Elixir Source: https://hexdocs.pm/phoenix_test_playwright/0.8.0/phoenix_test_playwright/PhoenixTest Defines the type for Playwright-specific selectors. This type allows for the use of Playwright's own selector engine, offering more advanced selection capabilities. ```elixir @type playwright_selector() :: String.t() ``` -------------------------------- ### CSS Selector Type Definition - Elixir Source: https://hexdocs.pm/phoenix_test_playwright/0.8.0/phoenix_test_playwright/PhoenixTest Defines the type for CSS selectors used within the Playwright context. This type alias ensures type safety when specifying element selectors. ```elixir @type css_selector() :: String.t() ``` -------------------------------- ### Custom Playwright Feature: Assert Selected Option in Select Element Source: https://hexdocs.pm/phoenix_test_playwright/0.8.0/phoenix_test_playwright/PhoenixTest This Elixir function asserts that a specific option within a select element is selected. It uses Playwright selectors to target the option by its label and verifies that it has the 'selected' attribute. ```elixir def assert_has_selected(conn, label, value, opts \ []) do opts = Keyword.validate!(opts, exact: true) assert_found(conn, selector: label |> Selector.label(opts) |> Selector.concat("option[selected]"), expression: "to.have.text", expectedText: [%{string: value}] ) end ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.