Skip to content

Commit

Permalink
Raise when multiple links found Static pages
Browse files Browse the repository at this point in the history
What changed?
=============

We update our `Query.find/3` result to differentiate between finding one
or many elements.

Since we now do that, we can improve our assertions. But we also bring
the static and LiveView behavior up to par in a place where we had a
difference.

LiveView raises when we find multiple elements that have the same
selector and text. So, it requires users to find a unique element.

Our Static implementation would simply follow the first link (if many
were found) instead of raising. We now update the code to raise if we
find many -- matching the LiveView behavior.
  • Loading branch information
germsvel committed Feb 3, 2024
1 parent c995fc1 commit daa4dca
Show file tree
Hide file tree
Showing 4 changed files with 38 additions and 22 deletions.
7 changes: 7 additions & 0 deletions lib/phoenix_test/assertions.ex
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,13 @@ defmodule PhoenixTest.Assertions do
#{format_found_element(element)}
"""

{:found_many, elements} ->
raise """
Expected not to find an element.
But found #{Enum.count(elements)} elements with selector #{inspect(selector)} and text #{inspect(text)}:
"""
end
end

Expand Down
38 changes: 24 additions & 14 deletions lib/phoenix_test/query.ex
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,14 @@ defmodule PhoenixTest.Query do

{:found, element} ->
element

{:found_many, _elements} ->
msg =
"""
Found more than one element with selector #{inspect(selector)} and text #{inspect(text)}.
"""

raise ArgumentError, msg
end
end

Expand Down Expand Up @@ -81,21 +89,10 @@ defmodule PhoenixTest.Query do

{:found, found_element} ->
found_element
end
end

defp find_with_text(html, selector, text) do
elements_matched_selector =
html
|> Html.all(selector)

Enum.find(elements_matched_selector, :not_found, fn element ->
Html.text(element) =~ text
end)
|> then(fn
:not_found -> {:not_found, elements_matched_selector}
found -> {:found, found}
end)
{:found_many, [found_element | _]} ->
found_element
end
end

defp find_one_of(html, elements) do
Expand All @@ -110,9 +107,22 @@ defmodule PhoenixTest.Query do
|> Enum.find({:not_found, elements}, fn
{:not_found, _} -> false
{:found, _} -> true
{:found_many, _} -> true
end)
end

defp find_with_text(html, selector, text) do
elements_matched_selector = Html.all(html, selector)

elements_matched_selector
|> Enum.filter(fn element -> Html.text(element) =~ text end)
|> case do
[] -> {:not_found, elements_matched_selector}
[found] -> {:found, found}
[_ | _] = found_many -> {:found_many, found_many}
end
end

defp first(html, selector) do
html
|> Html.all(selector)
Expand Down
4 changes: 1 addition & 3 deletions test/phoenix_test/assertions_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -118,9 +118,7 @@ defmodule PhoenixTest.AssertionsTest do
msg = """
Expected not to find an element.
But found an element with selector ".multiple_links" and text "Multiple links":
<a> with content "Multiple links"
But found 2 elements with selector ".multiple_links" and text "Multiple links":
"""

assert_raise RuntimeError, msg, fn ->
Expand Down
11 changes: 6 additions & 5 deletions test/phoenix_test/static_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -37,11 +37,12 @@ defmodule PhoenixTest.StaticTest do
|> assert_has("h1", "Page 2")
end

test "follows first link when there are multiple links with same text", %{conn: conn} do
conn
|> visit("/page/index")
|> click_link("Multiple links")
|> assert_has("h1", "Page 3")
test "raises error when there are multiple links with same text", %{conn: conn} do
assert_raise ArgumentError, ~r/Found more than one element with selector/, fn ->
conn
|> visit("/page/index")
|> click_link("Multiple links")
end
end

test "handles navigation to a LiveView", %{conn: conn} do
Expand Down

0 comments on commit daa4dca

Please sign in to comment.