From 3756a479c604841f4fe264aee27b31bcb97ca2e3 Mon Sep 17 00:00:00 2001 From: German Velasco Date: Sat, 9 Mar 2024 17:01:41 -0500 Subject: [PATCH] Add `PhoenixTest.assert_has/2` What changed? ============ We add an `assert_has/2` helper that does not require the user to pass text. Sometimes, we want to assert that an element is present on the page even if we don't pass the text. Recently, that was something we wanted to do in a project when we were trying to assert the value of an input. Since the `value` is passed as part of the CSS selector, we did not need the third argument. --- lib/phoenix_test.ex | 12 +++++++- lib/phoenix_test/assertions.ex | 44 +++++++++++++++++++++++++-- test/phoenix_test/assertions_test.exs | 30 ++++++++++++++++++ 3 files changed, 82 insertions(+), 4 deletions(-) diff --git a/lib/phoenix_test.ex b/lib/phoenix_test.ex index cbfe692..7f81b71 100644 --- a/lib/phoenix_test.ex +++ b/lib/phoenix_test.ex @@ -291,11 +291,21 @@ defmodule PhoenixTest do @doc false defdelegate open_browser(session, open_fun), to: Driver + @doc """ + Assert helper to ensure an element with given CSS selector is present. + + It'll raise an error if no elements are found, but it will _not_ raise if more + than one matching element is found. + + If you want to specify the conten of the element, use `assert_has/3`. + """ + defdelegate assert_has(session, selector), to: Assertions + @doc """ Assert helper to ensure an element with given CSS selector and `text` is present. - It'll raise an error if no elements are found, but it will not raise if more + It'll raise an error if no elements are found, but it will _not_ raise if more than one matching element is found. """ defdelegate assert_has(session, selector, text), to: Assertions diff --git a/lib/phoenix_test/assertions.ex b/lib/phoenix_test/assertions.ex index 520dc07..d558377 100644 --- a/lib/phoenix_test/assertions.ex +++ b/lib/phoenix_test/assertions.ex @@ -8,19 +8,55 @@ defmodule PhoenixTest.Assertions do alias PhoenixTest.Query @doc """ - Asserts that the rendered HTML content within the given session contains an element - matching the specified selector and text. + Asserts that the rendered HTML content within the given session contains an + element matching the specified selector and (optional) text. ## Parameters - `session`: The test session. - `selector`: The CSS selector to search for. - - `text`: The expected text content of the element. + - `text` (optional): The expected text content of the element. ## Raises Raises `AssertionError` if no element is found with the given selector and text. """ + def assert_has(session, "title") do + title = PhoenixTest.Driver.render_page_title(session) + + if is_nil(title) || title == "" do + raise AssertionError, + message: """ + Expected title to be present but could not find it. + """ + else + assert true + end + + session + end + + def assert_has(session, selector) do + session + |> PhoenixTest.Driver.render_html() + |> Query.find(selector) + |> case do + {:found, _found} -> + assert true + + {:found_many, _found} -> + assert true + + :not_found -> + raise AssertionError, + message: """ + Could not find any elements with selector #{inspect(selector)}. + """ + end + + session + end + def assert_has(session, "title", text) do title = PhoenixTest.Driver.render_page_title(session) @@ -32,6 +68,8 @@ defmodule PhoenixTest.Assertions do Expected title to be #{inspect(text)} but got #{inspect(title)} """ end + + session end def assert_has(session, selector, text) do diff --git a/test/phoenix_test/assertions_test.exs b/test/phoenix_test/assertions_test.exs index 6c3713b..d5c59cb 100644 --- a/test/phoenix_test/assertions_test.exs +++ b/test/phoenix_test/assertions_test.exs @@ -10,6 +10,36 @@ defmodule PhoenixTest.AssertionsTest do %{conn: Phoenix.ConnTest.build_conn()} end + describe "assert_has/2" do + test "succeeds if single element is found with CSS selector", %{conn: conn} do + conn + |> visit("/page/index") + |> assert_has("[data-role='title']") + end + + test "raises an error if the element cannot be found at all", %{conn: conn} do + conn = visit(conn, "/page/index") + + msg = ~r/Could not find any elements with selector "#nonexistent-id"/ + + assert_raise AssertionError, msg, fn -> + conn |> assert_has("#nonexistent-id") + end + end + + test "succeeds if element searched is title (Static)", %{conn: conn} do + conn + |> visit("/page/index") + |> assert_has("title") + end + + test "succeeds if element searched is title (Live)", %{conn: conn} do + conn + |> visit("/live/index") + |> assert_has("title") + end + end + describe "assert_has/3" do test "succeeds if single element is found with CSS selector and text (Static)", %{conn: conn} do conn