germsvel / phoenix_test

PhoenixTest provides a unified way of writing feature tests -- regardless of whether you're testing LiveView pages or static (non-LiveView) pages.
https://hex.pm/packages/phoenix_test
MIT License
176 stars 22 forks source link

buttons with more than just a text node can't be clicked #23

Closed knewter closed 8 months ago

knewter commented 8 months ago
defmodule TinyposWeb.MerchantCanLoginTest do
  use TinyposWeb.FeatureCase, async: true

  test "merchant can login", %{conn: conn} do
    conn
    |> visit("/merchants/login")
    |> fill_form("#merchant", %{"merchant[phone]" => "5555551212"})
    |> click_button("Get started")
    |> assert_has(".user", "Aragorn") # This bit is fake but it fails on the prior line
  end
end

When I run the test, it fails but it throws an exception when trying to tell me that it failed:

  1) test merchant can login (TinyposWeb.MerchantCanLoginTest)
     test/tinypos_web/features/merchant_login_test.exs:4
     ** (FunctionClauseError) no function clause matching in anonymous fn/1 in PhoenixTest.Query.format_potential_matches/1

     The following arguments were given to anonymous fn/1 in PhoenixTest.Query.format_potential_matches/1:

         # 1
         {"button", [{"phx-click", "update_step"}, {"phx-value-step", "merchant_login_with_email"}, {"class", "transition-all ease-in-out inline-flex items-center justify-centerpy-2 px-3 text-xs font-semibold text-white"}], [{"span", [{"class", "material-icons-outlined"}], ["\n                    email\n                  "]}, {"span", [{"class", "ml-2"}], ["Email login"]}]}

     code: |> click_button("Get started")
     stacktrace:
       (phoenix_test 0.2.3) lib/phoenix_test/query.ex:155: anonymous fn/1 in PhoenixTest.Query.format_potential_matches/1
       (elixir 1.16.0) lib/enum.ex:1801: anonymous fn/2 in Enum.map_join/3
       (elixir 1.16.0) lib/enum.ex:4384: Enum.map_intersperse_list/3
       (elixir 1.16.0) lib/enum.ex:1801: Enum.map_join/3
       (phoenix_test 0.2.3) lib/phoenix_test/query.ex:106: PhoenixTest.Query.find_one_of!/2
       (phoenix_test 0.2.3) lib/phoenix_test/live.ex:59: PhoenixTest.Driver.PhoenixTest.Live.click_button/3
       test/tinypos_web/features/merchant_login_test.exs:8: (test)

This is because it's trying to print the error message, but format_potential_matches assumes the third element is a single-item list with just a text node in it matching the text provided.

  defp format_potential_matches(elements) do
    Enum.map_join(elements, "\n", fn
      {tag, _, [content]} -> "<#{tag}> tag with content #{inspect(content)}"
    end)
  end

Instead, it gets this:

  {"button",
   [
     {"type", "submit"},
     {"class",
      "transition-all ease-in-out inline-flex items-center justify-center rounded-full bg-blue-600 py-2 px-3 text-sm font-semibold text-white shadow-sm hover:bg-blue-700 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-blue-600"}
   ],
   [
     {"span", [{"class", "mr-2"}], ["Get Started"]},
     {"span", [{"class", "material-icons-outlined"}],
      ["\n        arrow_circle_right\n      "]}
   ]}

This may not be expected usage, but the failure note throwing an exception seemed reportable.

knewter commented 8 months ago

Patching format_potential_matches to just inspect the whole third element in the tuple rather than matching it as a single-item list led to this error result, which is at least understandable:

  1) test merchant can login (TinyposWeb.MerchantCanLoginTest)
     test/tinypos_web/features/merchant_login_test.exs:4
     ** (ArgumentError) Could not find an element with given selectors.

     I was looking for an element with one of these selectors:

     Selector "input[type=submit][value=Get started]"
     Selector "button" with content "Get started"

     I found some elements that match the selector but not the content:

     <button> tag with content [{"span", [{"class", "material-icons-outlined"}], ["\n                    email\n                  "]}, {"span", [{"class", "ml-2"}], ["Email login"]}]
     <button> tag with content [{"span", [{"class", "mr-2"}], ["Get Started"]}, {"span", [{"class", "material-icons-outlined"}], ["\n        arrow_circle_right\n      "]}]
knewter commented 8 months ago

closing, fixed here: https://github.com/germsvel/phoenix_test/commit/82e7415294271b6bbd8adbfc47da43bddc7527b7

germsvel commented 8 months ago

Thanks for all the investigation @knewter. Apologies for not having released that commit sooner. I was trying to get one more thing in before cutting another release.