From 2b617c125b4f8f9903881d657d2490b5adca0bb5 Mon Sep 17 00:00:00 2001 From: Fredrik Teschke Date: Sun, 6 Oct 2024 11:20:23 +0200 Subject: [PATCH] Add playwright driver --- .gitignore | 2 + lib/phoenix_test.ex | 6 + lib/phoenix_test/assertions.ex | 2 +- lib/phoenix_test/phoenix_test_case.ex | 66 +++++++ lib/phoenix_test/playwright.ex | 246 +++++++++++++++++++++++++ lib/phoenix_test/playwright_locator.ex | 31 ++++ mix.exs | 6 +- mix.lock | 4 + priv/static/assets/app.css | 0 priv/static/favicon.ico | 0 test/phoenix_test/assertions_test.exs | 91 ++++++--- test/phoenix_test/live_test.exs | 218 +++++++++++++--------- test/phoenix_test/playwright_test.exs | 15 ++ test/phoenix_test/static_test.exs | 165 +++++++++-------- test/support/index_live.ex | 4 +- test/support/page_view.ex | 8 +- test/support/test_helpers.ex | 13 ++ test/test_helper.exs | 2 + 18 files changed, 680 insertions(+), 199 deletions(-) create mode 100644 lib/phoenix_test/phoenix_test_case.ex create mode 100644 lib/phoenix_test/playwright.ex create mode 100644 lib/phoenix_test/playwright_locator.ex create mode 100644 priv/static/assets/app.css create mode 100644 priv/static/favicon.ico create mode 100644 test/phoenix_test/playwright_test.exs diff --git a/.gitignore b/.gitignore index 6bdf718f..def55516 100644 --- a/.gitignore +++ b/.gitignore @@ -27,3 +27,5 @@ phoenix_test-*.tar # Ignore assets that are produced by build tools. /priv/static/assets/ + +.envrc diff --git a/lib/phoenix_test.ex b/lib/phoenix_test.ex index afcf2bfb..85a85cd2 100644 --- a/lib/phoenix_test.ex +++ b/lib/phoenix_test.ex @@ -213,6 +213,12 @@ defmodule PhoenixTest do LiveView or a static view. You don't need to worry about which type of page you're visiting. """ + if Code.ensure_loaded?(Playwright.Page) do + def visit(%Playwright.Page{} = page, path) do + PhoenixTest.Playwright.build(page, path) + end + end + def visit(conn, path) do case get(conn, path) do %{assigns: %{live_module: _}} = conn -> diff --git a/lib/phoenix_test/assertions.ex b/lib/phoenix_test/assertions.ex index 60b6b104..72313cb8 100644 --- a/lib/phoenix_test/assertions.ex +++ b/lib/phoenix_test/assertions.ex @@ -285,7 +285,7 @@ defmodule PhoenixTest.Assertions do |> append_found(found) end - defp assert_not_found_error_msg(selector, opts, other_matches \\ []) do + def assert_not_found_error_msg(selector, opts, other_matches \\ []) do count = Keyword.get(opts, :count, :any) position = Keyword.get(opts, :at, :any) text = Keyword.get(opts, :text, :no_text) diff --git a/lib/phoenix_test/phoenix_test_case.ex b/lib/phoenix_test/phoenix_test_case.ex new file mode 100644 index 00000000..3a1380c0 --- /dev/null +++ b/lib/phoenix_test/phoenix_test_case.ex @@ -0,0 +1,66 @@ +defmodule PhoenixTest.Case do + @moduledoc false + + defmacro __using__(options \\ []) do + quote do + import PhoenixTest + + setup_all do + [conn: Phoenix.ConnTest.build_conn()] + end + + if Code.ensure_loaded?(Playwright.Page) and unquote(options[:playwright]) do + setup_all(context) do + opts = Map.new(unquote(options)) + PhoenixTest.Case.setup_all_playwright(opts) + end + + setup(context) do + PhoenixTest.Case.setup_playwright(context) + end + end + end + end + + if Code.ensure_loaded?(Playwright.Page) do + def setup_all_playwright(options) do + client = options.playwright + launch_options = Map.merge(Playwright.SDK.Config.launch_options(), options) + runner_options = Map.merge(Playwright.SDK.Config.playwright_test(), options) + Application.put_env(:playwright, LaunchOptions, launch_options) + {:ok, _} = Application.ensure_all_started(:playwright) + browser = setup_browser(client, runner_options, launch_options) + + [browser: browser] + end + + def setup_playwright(%{playwright: _} = context) do + page = Playwright.Browser.new_page(context.browser) + ExUnit.Callbacks.on_exit(fn -> Playwright.Page.close(page) end) + + [conn: page] + end + + def setup_playwright(_context) do + [conn: Phoenix.ConnTest.build_conn()] + end + + defp setup_browser(true = _client, runner_options, launch_options) do + setup_browser(:chromium, runner_options, launch_options) + end + + defp setup_browser(client, runner_options, launch_options) do + case runner_options.transport do + :driver -> + {_pid, browser} = Playwright.BrowserType.launch(client, launch_options) + ExUnit.Callbacks.on_exit(fn -> Playwright.Browser.close(browser) end) + browser + + :websocket -> + options = Playwright.SDK.Config.connect_options() + {_pid, browser} = Playwright.BrowserType.connect(options.ws_endpoint) + browser + end + end + end +end diff --git a/lib/phoenix_test/playwright.ex b/lib/phoenix_test/playwright.ex new file mode 100644 index 00000000..794b6166 --- /dev/null +++ b/lib/phoenix_test/playwright.ex @@ -0,0 +1,246 @@ +if Code.ensure_loaded?(Playwright.Page) do + defmodule PhoenixTest.Playwright do + @moduledoc false + + alias ExUnit.AssertionError + alias PhoenixTest.Assertions + alias PhoenixTest.OpenBrowser + alias PhoenixTest.Playwright.Locator, as: L + alias Playwright.Locator + alias Playwright.Page + alias Playwright.SDK.Channel + + defstruct [:page, within: :none] + + @endpoint Application.compile_env(:phoenix_test, :endpoint) + @default_timeout :timer.seconds(1) + + def build(page, path) do + base_url = Application.fetch_env!(:phoenix_test, :base_url) + Page.goto(page, base_url <> path) + %__MODULE__{page: page} + end + + def assert_has(session, selector, opts \\ []) do + unless found?(session, selector, opts) do + raise(AssertionError, Assertions.assert_not_found_error_msg(selector, opts, [])) + end + + session + end + + def refute_has(session, selector, opts \\ []) do + if found?(session, selector, opts, is_not: true) do + raise(AssertionError, Assertions.refute_found_error_msg(selector, opts, [])) + end + + session + end + + defp found?(session, selector, opts, query_attrs \\ []) do + # TODO + if opts[:count], do: raise("count not implemented") + + locator = + session + |> maybe_within() + |> L.concat(L.css(selector)) + |> L.concat(L.text(opts[:text], opts)) + |> L.concat(L.at(opts[:at])) + + query = + Enum.into(query_attrs, %{ + expression: "to.be.visible", + is_not: false, + selector: locator.selector, + timeout: timeout(opts) + }) + + Channel.post(session.page.session, {:guid, locator.frame.guid}, :expect, query) + end + + def render_page_title(session) do + Page.title(session.page) + end + + def render_html(session) do + session + |> maybe_within() + |> Locator.inner_html() + end + + def click_link(session, selector, text) do + session + |> maybe_within() + |> L.concat(L.css(selector)) + |> L.concat(L.text(text, exact: false)) + |> Locator.click(%{timeout: timeout()}) + |> handle_result(selector) + + session + end + + def click_button(session, selector, text) do + session + |> maybe_within() + |> L.concat(L.css(selector)) + |> L.concat(L.text(text, exact: false)) + |> Locator.click(%{timeout: timeout()}) + |> handle_result(selector) + + session + end + + def within(session, selector, fun) do + session + |> Map.put(:within, selector) + |> fun.() + |> Map.put(:within, :none) + end + + def fill_in(session, input_selector, label, opts) do + {value, opts} = Keyword.pop!(opts, :with) + fun = &Locator.fill(&1, to_string(value), &2) + input(session, input_selector, label, opts, fun) + end + + def select(session, input_selector, option, opts) do + {label, opts} = Keyword.pop!(opts, :from) + fun = &Locator.select_option(&1, %{label: option}, &2) + input(session, input_selector, label, opts, fun) + end + + def check(session, input_selector, label, opts) do + fun = &Locator.check/2 + input(session, input_selector, label, opts, fun) + end + + def uncheck(session, input_selector, label, opts) do + fun = &Locator.uncheck/2 + input(session, input_selector, label, opts, fun) + end + + def choose(session, input_selector, label, opts) do + fun = &Locator.check/2 + input(session, input_selector, label, opts, fun) + end + + def upload(session, input_selector, label, paths, opts) do + fun = &Locator.set_input_files(&1, List.wrap(paths), &2) + input(session, input_selector, label, opts, fun) + end + + defp input(session, input_selector, label, opts, fun) do + session + |> maybe_within() + |> L.concat(L.css(input_selector)) + |> L.and(L.label(label, opts)) + |> fun.(%{timeout: timeout(opts)}) + |> handle_result(input_selector, label) + + session + end + + defp maybe_within(session) do + case session.within do + :none -> Locator.new(session.page, "*") + selector -> Page.locator(session.page, "css=#{selector}") + end + end + + defp handle_result(result, selector, label \\ nil) do + case result do + list when is_list(list) -> + {:ok, list} + + :ok -> + result + + {:ok, _} -> + result + + {:error, %{type: "Error", message: "Error: strict mode violation" <> _}} -> + raise(ArgumentError, "Found more than one element with selector #{inspect(selector)}") + + {:error, %{type: "TimeoutError"}} -> + msg = + case label do + nil -> "Could not find element with selector #{inspect(selector)}." + _ -> "Could not find element with label #{inspect(label)}." + end + + raise(ArgumentError, msg) + + {:error, %{type: "Error", message: "Clicking the checkbox did not change its state"}} -> + :ok + end + end + + def submit(session) do + Page.Keyboard.down(session.page, "Enter") + session + end + + def open_browser(session, open_fun \\ &OpenBrowser.open_with_system_cmd/1) do + html = + session.page + |> Page.content() + |> Floki.parse_document!() + |> Floki.traverse_and_update(&OpenBrowser.prefix_static_paths(&1, @endpoint)) + |> Floki.raw_html() + + path = Path.join([System.tmp_dir!(), "phx-test#{System.unique_integer([:monotonic])}.html"]) + File.write!(path, html) + open_fun.(path) + + session + end + + def unwrap(session, fun) do + fun.(session.page) + session + end + + def current_path(session) do + url = Page.url(session.page) + uri = URI.parse(url) + [uri.path, uri.query] |> Enum.reject(&is_nil/1) |> Enum.join("?") + end + + defp timeout(opts \\ []) do + default = Application.get_env(:phoenix_test, :timeout, @default_timeout) + Keyword.get(opts, :timeout, default) + end + end + + defimpl PhoenixTest.Driver, for: PhoenixTest.Playwright do + alias PhoenixTest.Assertions + alias PhoenixTest.Playwright + + defdelegate render_page_title(session), to: Playwright + defdelegate render_html(session), to: Playwright + defdelegate click_link(session, selector, text), to: Playwright + defdelegate click_button(session, selector, text), to: Playwright + defdelegate within(session, selector, fun), to: Playwright + defdelegate fill_in(session, input_selector, label, opts), to: Playwright + defdelegate select(session, input_selector, option, opts), to: Playwright + defdelegate check(session, input_selector, label, opts), to: Playwright + defdelegate uncheck(session, input_selector, label, opts), to: Playwright + defdelegate choose(session, input_selector, label, opts), to: Playwright + defdelegate upload(session, input_selector, label, path, opts), to: Playwright + defdelegate submit(session), to: Playwright + defdelegate open_browser(session), to: Playwright + defdelegate open_browser(session, open_fun), to: Playwright + defdelegate unwrap(session, fun), to: Playwright + defdelegate current_path(session), to: Playwright + + defdelegate assert_has(session, selector), to: Playwright + defdelegate assert_has(session, selector, opts), to: Playwright + defdelegate refute_has(session, selector), to: Playwright + defdelegate refute_has(session, selector, opts), to: Playwright + defdelegate assert_path(session, path), to: Assertions + defdelegate assert_path(session, path, opts), to: Assertions + defdelegate refute_path(session, path), to: Assertions + defdelegate refute_path(session, path, opts), to: Assertions + end +end diff --git a/lib/phoenix_test/playwright_locator.ex b/lib/phoenix_test/playwright_locator.ex new file mode 100644 index 00000000..87487415 --- /dev/null +++ b/lib/phoenix_test/playwright_locator.ex @@ -0,0 +1,31 @@ +defmodule PhoenixTest.Playwright.Locator do + @moduledoc false + + def concat(locator, :none), do: locator + def concat(locator, string), do: Playwright.Locator.locator(locator, string) + + def unquote(:and)(locator, :none), do: locator + + def unquote(:and)(locator, string) do + and_string = "internal:and=#{Jason.encode!(string)}" + Playwright.Locator.locator(locator, and_string) + end + + def text(nil, _opts), do: :none + def text(text, opts), do: "internal:text=\"#{text}\"#{exact_suffix(opts)}" + + def label(nil, _opts), do: :none + def label(label, opts), do: "internal:label=\"#{label}\"#{exact_suffix(opts)}" + + def at(nil), do: :none + def at(at), do: "nth=#{at + 1}" + + def css(nil), do: :none + def css([]), do: :none + def css(selector) when is_binary(selector), do: css([selector]) + def css(selectors) when is_list(selectors), do: "css=#{Enum.join(selectors, ",")}" + + defp exact_suffix(opts) when is_list(opts), do: opts |> Keyword.get(:exact, false) |> exact_suffix() + defp exact_suffix(true), do: "s" + defp exact_suffix(false), do: "i" +end diff --git a/mix.exs b/mix.exs index af2aad37..5525d766 100644 --- a/mix.exs +++ b/mix.exs @@ -41,7 +41,7 @@ defmodule PhoenixTest.MixProject do # Run "mix help deps" to learn about dependencies. defp deps do [ - {:esbuild, "~> 0.8", only: :test, runtime: false}, + {:esbuild, "~> 0.8", runtime: false}, {:ex_doc, "~> 0.31", only: :dev, runtime: false}, {:floki, ">= 0.30.0"}, {:jason, "~> 1.4"}, @@ -51,7 +51,9 @@ defmodule PhoenixTest.MixProject do {:phoenix, "~> 1.7.10"}, {:phoenix_live_view, "~> 0.20.1"}, {:plug_cowboy, "~> 2.7", only: :test, runtime: false}, - {:styler, "~> 0.11", only: [:dev, :test], runtime: false} + {:styler, "~> 0.11", only: [:dev, :test], runtime: false}, + {:cowlib, "~> 2.13.0", override: true}, + {:playwright, github: "ftes/playwright-elixir", ref: "phoenix-test", optional: true} ] end diff --git a/mix.lock b/mix.lock index 0685833d..5a5431c1 100644 --- a/mix.lock +++ b/mix.lock @@ -7,6 +7,7 @@ "esbuild": {:hex, :esbuild, "0.8.1", "0cbf919f0eccb136d2eeef0df49c4acf55336de864e63594adcea3814f3edf41", [:mix], [{:castore, ">= 0.0.0", [hex: :castore, repo: "hexpm", optional: false]}, {:jason, "~> 1.4", [hex: :jason, repo: "hexpm", optional: false]}], "hexpm", "25fc876a67c13cb0a776e7b5d7974851556baeda2085296c14ab48555ea7560f"}, "ex_doc": {:hex, :ex_doc, "0.32.1", "21e40f939515373bcdc9cffe65f3b3543f05015ac6c3d01d991874129d173420", [:mix], [{:earmark_parser, "~> 1.4.39", [hex: :earmark_parser, repo: "hexpm", optional: false]}, {:makeup_c, ">= 0.1.1", [hex: :makeup_c, repo: "hexpm", optional: true]}, {:makeup_elixir, "~> 0.14", [hex: :makeup_elixir, repo: "hexpm", optional: false]}, {:makeup_erlang, "~> 0.1", [hex: :makeup_erlang, repo: "hexpm", optional: false]}], "hexpm", "5142c9db521f106d61ff33250f779807ed2a88620e472ac95dc7d59c380113da"}, "floki": {:hex, :floki, "0.35.2", "87f8c75ed8654b9635b311774308b2760b47e9a579dabf2e4d5f1e1d42c39e0b", [:mix], [], "hexpm", "6b05289a8e9eac475f644f09c2e4ba7e19201fd002b89c28c1293e7bd16773d9"}, + "gun": {:hex, :gun, "1.3.3", "cf8b51beb36c22b9c8df1921e3f2bc4d2b1f68b49ad4fbc64e91875aa14e16b4", [:rebar3], [{:cowlib, "~> 2.7.0", [hex: :cowlib, repo: "hexpm", optional: false]}], "hexpm", "3106ce167f9c9723f849e4fb54ea4a4d814e3996ae243a1c828b256e749041e0"}, "jason": {:hex, :jason, "1.4.1", "af1504e35f629ddcdd6addb3513c3853991f694921b1b9368b0bd32beb9f1b63", [:mix], [{:decimal, "~> 1.0 or ~> 2.0", [hex: :decimal, repo: "hexpm", optional: true]}], "hexpm", "fbb01ecdfd565b56261302f7e1fcc27c4fb8f32d56eab74db621fc154604a7a1"}, "makeup": {:hex, :makeup, "1.1.1", "fa0bc768698053b2b3869fa8a62616501ff9d11a562f3ce39580d60860c3a55e", [:mix], [{:nimble_parsec, "~> 1.2.2 or ~> 1.3", [hex: :nimble_parsec, repo: "hexpm", optional: false]}], "hexpm", "5dc62fbdd0de44de194898b6710692490be74baa02d9d108bc29f007783b0b48"}, "makeup_diff": {:hex, :makeup_diff, "0.1.0", "5be352b6aa6f07fa6a236e3efd7ba689a03f28fb5d35b7a0fa0a1e4a64f6d8bb", [:mix], [{:makeup, "~> 1.0", [hex: :makeup, repo: "hexpm", optional: false]}], "hexpm", "186bad5bb433a8afeb16b01423950e440072284a4103034ca899180343b9b4ac"}, @@ -21,12 +22,15 @@ "phoenix_live_view": {:hex, :phoenix_live_view, "0.20.3", "8b6406bc0a451f295407d7acff7f234a6314be5bbe0b3f90ed82b07f50049878", [:mix], [{:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}, {:phoenix, "~> 1.6.15 or ~> 1.7.0", [hex: :phoenix, repo: "hexpm", optional: false]}, {:phoenix_html, "~> 3.3 or ~> 4.0", [hex: :phoenix_html, repo: "hexpm", optional: false]}, {:phoenix_template, "~> 1.0", [hex: :phoenix_template, repo: "hexpm", optional: false]}, {:phoenix_view, "~> 2.0", [hex: :phoenix_view, repo: "hexpm", optional: true]}, {:plug, "~> 1.15", [hex: :plug, repo: "hexpm", optional: false]}, {:telemetry, "~> 0.4.2 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "a8e4385e05618b424779f894ed2df97d3c7518b7285fcd11979077ae6226466b"}, "phoenix_pubsub": {:hex, :phoenix_pubsub, "2.1.3", "3168d78ba41835aecad272d5e8cd51aa87a7ac9eb836eabc42f6e57538e3731d", [:mix], [], "hexpm", "bba06bc1dcfd8cb086759f0edc94a8ba2bc8896d5331a1e2c2902bf8e36ee502"}, "phoenix_template": {:hex, :phoenix_template, "1.0.4", "e2092c132f3b5e5b2d49c96695342eb36d0ed514c5b252a77048d5969330d639", [:mix], [{:phoenix_html, "~> 2.14.2 or ~> 3.0 or ~> 4.0", [hex: :phoenix_html, repo: "hexpm", optional: true]}], "hexpm", "2c0c81f0e5c6753faf5cca2f229c9709919aba34fab866d3bc05060c9c444206"}, + "playwright": {:git, "https://github.com/ftes/playwright-elixir.git", "93b728034dce4e3c70f81b970d4f77f8813e5fce", [ref: "phoenix-test"]}, "plug": {:hex, :plug, "1.15.2", "94cf1fa375526f30ff8770837cb804798e0045fd97185f0bb9e5fcd858c792a3", [:mix], [{:mime, "~> 1.0 or ~> 2.0", [hex: :mime, repo: "hexpm", optional: false]}, {:plug_crypto, "~> 1.1.1 or ~> 1.2 or ~> 2.0", [hex: :plug_crypto, repo: "hexpm", optional: false]}, {:telemetry, "~> 0.4.3 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "02731fa0c2dcb03d8d21a1d941bdbbe99c2946c0db098eee31008e04c6283615"}, "plug_cowboy": {:hex, :plug_cowboy, "2.7.1", "87677ffe3b765bc96a89be7960f81703223fe2e21efa42c125fcd0127dd9d6b2", [:mix], [{:cowboy, "~> 2.7", [hex: :cowboy, repo: "hexpm", optional: false]}, {:cowboy_telemetry, "~> 0.3", [hex: :cowboy_telemetry, repo: "hexpm", optional: false]}, {:plug, "~> 1.14", [hex: :plug, repo: "hexpm", optional: false]}], "hexpm", "02dbd5f9ab571b864ae39418db7811618506256f6d13b4a45037e5fe78dc5de3"}, "plug_crypto": {:hex, :plug_crypto, "2.0.0", "77515cc10af06645abbfb5e6ad7a3e9714f805ae118fa1a70205f80d2d70fe73", [:mix], [], "hexpm", "53695bae57cc4e54566d993eb01074e4d894b65a3766f1c43e2c61a1b0f45ea9"}, "ranch": {:hex, :ranch, "1.8.0", "8c7a100a139fd57f17327b6413e4167ac559fbc04ca7448e9be9057311597a1d", [:make, :rebar3], [], "hexpm", "49fbcfd3682fab1f5d109351b61257676da1a2fdbe295904176d5e521a2ddfe5"}, + "recase": {:hex, :recase, "0.8.1", "ab98cd35857a86fa5ca99036f575241d71d77d9c2ab0c39aacf1c9b61f6f7d1d", [:mix], [], "hexpm", "9fd8d63e7e43bd9ea385b12364e305778b2bbd92537e95c4b2e26fc507d5e4c2"}, "styler": {:hex, :styler, "0.11.9", "2595393b94e660cd6e8b582876337cc50ff047d184ccbed42fdad2bfd5d78af5", [:mix], [], "hexpm", "8b7806ba1fdc94d0a75127c56875f91db89b75117fcc67572661010c13e1f259"}, "telemetry": {:hex, :telemetry, "1.2.1", "68fdfe8d8f05a8428483a97d7aab2f268aaff24b49e0f599faa091f1d4e7f61c", [:rebar3], [], "hexpm", "dad9ce9d8effc621708f99eac538ef1cbe05d6a874dd741de2e689c47feafed5"}, + "uuid": {:hex, :uuid, "1.1.8", "e22fc04499de0de3ed1116b770c7737779f226ceefa0badb3592e64d5cfb4eb9", [:mix], [], "hexpm", "c790593b4c3b601f5dc2378baae7efaf5b3d73c4c6456ba85759905be792f2ac"}, "websock": {:hex, :websock, "0.5.3", "2f69a6ebe810328555b6fe5c831a851f485e303a7c8ce6c5f675abeb20ebdadc", [:mix], [], "hexpm", "6105453d7fac22c712ad66fab1d45abdf049868f253cf719b625151460b8b453"}, "websock_adapter": {:hex, :websock_adapter, "0.5.5", "9dfeee8269b27e958a65b3e235b7e447769f66b5b5925385f5a569269164a210", [:mix], [{:bandit, ">= 0.6.0", [hex: :bandit, repo: "hexpm", optional: true]}, {:plug, "~> 1.14", [hex: :plug, repo: "hexpm", optional: false]}, {:plug_cowboy, "~> 2.6", [hex: :plug_cowboy, repo: "hexpm", optional: true]}, {:websock, "~> 0.5", [hex: :websock, repo: "hexpm", optional: false]}], "hexpm", "4b977ba4a01918acbf77045ff88de7f6972c2a009213c515a445c48f224ffce9"}, } diff --git a/priv/static/assets/app.css b/priv/static/assets/app.css new file mode 100644 index 00000000..e69de29b diff --git a/priv/static/favicon.ico b/priv/static/favicon.ico new file mode 100644 index 00000000..e69de29b diff --git a/test/phoenix_test/assertions_test.exs b/test/phoenix_test/assertions_test.exs index c11d8025..cce59646 100644 --- a/test/phoenix_test/assertions_test.exs +++ b/test/phoenix_test/assertions_test.exs @@ -1,5 +1,6 @@ defmodule PhoenixTest.AssertionsTest do use ExUnit.Case, async: true + use PhoenixTest.Case, playwright: :chromium import PhoenixTest import PhoenixTest.Locators @@ -8,17 +9,14 @@ defmodule PhoenixTest.AssertionsTest do alias ExUnit.AssertionError alias PhoenixTest.Live - setup 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 + test_also_with_playwright "succeeds if single element is found with CSS selector", %{conn: conn} do conn |> visit("/page/index") |> assert_has("[data-role='title']") end + # TODO Playwright: Fix error message test "raises an error if the element cannot be found at all", %{conn: conn} do conn = visit(conn, "/page/index") @@ -29,24 +27,27 @@ defmodule PhoenixTest.AssertionsTest do end end + # TODO Playwright: Fix special page title assertion test "succeeds if element searched is title (Static)", %{conn: conn} do conn |> visit("/page/index") |> assert_has("title") end + # TODO Playwright: Fix special page title assertion test "succeeds if element searched is title (Live)", %{conn: conn} do conn |> visit("/live/index") |> assert_has("title") end - test "succeeds if more than one element matches selector", %{conn: conn} do + test_also_with_playwright "succeeds if more than one element matches selector", %{conn: conn} do conn |> visit("/page/index") |> assert_has("li") end + # TODO Playwright: Compile PhoenixTest locators test "takes in input helper in assertion", %{conn: conn} do conn |> visit("/page/index") @@ -55,7 +56,7 @@ defmodule PhoenixTest.AssertionsTest do end describe "assert_has/3" do - test "succeeds if single element is found with CSS selector and text (Static)", %{conn: conn} do + test_also_with_playwright "succeeds if single element is found with CSS selector and text (Static)", %{conn: conn} do conn |> visit("/page/index") |> assert_has("h1", text: "Main page") @@ -64,7 +65,7 @@ defmodule PhoenixTest.AssertionsTest do |> assert_has("[data-role='title']", text: "Main page") end - test "succeeds if single element is found with CSS selector and text (Live)", %{conn: conn} do + test_also_with_playwright "succeeds if single element is found with CSS selector and text (Live)", %{conn: conn} do conn |> visit("/live/index") |> assert_has("h1", text: "LiveView main page") @@ -73,7 +74,7 @@ defmodule PhoenixTest.AssertionsTest do |> assert_has("[data-role='title']", text: "LiveView main page") end - test "succeeds if more than one element matches selector but text narrows it down", %{ + test_also_with_playwright "succeeds if more than one element matches selector but text narrows it down", %{ conn: conn } do conn @@ -81,24 +82,25 @@ defmodule PhoenixTest.AssertionsTest do |> assert_has("li", text: "Aragorn") end - test "succeeds if more than one element matches selector and text", %{conn: conn} do + test_also_with_playwright "succeeds if more than one element matches selector and text", %{conn: conn} do conn |> visit("/page/index") |> assert_has(".multiple_links", text: "Multiple links") end - test "succeeds if text difference is only a matter of truncation", %{conn: conn} do + test_also_with_playwright "succeeds if text difference is only a matter of truncation", %{conn: conn} do conn |> visit("/page/index") |> assert_has(".has_extra_space", text: "Has extra space") end - test "succeeds when a non-200 status code is returned", %{conn: conn} do + test_also_with_playwright "succeeds when a non-200 status code is returned", %{conn: conn} do conn |> visit("/page/unauthorized") |> assert_has("h1", text: "Unauthorized") end + # TODO Playwright: Fix error message test "raises an error if the element cannot be found at all", %{conn: conn} do conn = visit(conn, "/page/index") @@ -109,6 +111,7 @@ defmodule PhoenixTest.AssertionsTest do end end + # TODO Playwright: Fix error message test "raises error if element cannot be found but selector matches other elements", %{ conn: conn } do @@ -130,24 +133,28 @@ defmodule PhoenixTest.AssertionsTest do end end + # TODO Playwright: Fix special page title assertion test "can be used to assert on page title (Static)", %{conn: conn} do conn |> visit("/page/index") |> assert_has("title", text: "PhoenixTest is the best!") end + # TODO Playwright: Fix special page title assertion test "can be used to assert on page title (Live)", %{conn: conn} do conn |> visit("/live/index") |> assert_has("title", text: "PhoenixTest is the best!") end + # TODO Playwright: Fix special page title assertion test "can assert title's exactness", %{conn: conn} do conn |> visit("/live/index") |> assert_has("title", text: "PhoenixTest is the best!", exact: true) end + # TODO Playwright: Fix error message test "raises if title does not match expected value (Static)", %{conn: conn} do msg = ignore_whitespace(""" @@ -161,6 +168,7 @@ defmodule PhoenixTest.AssertionsTest do end end + # TODO Playwright: Fix error message test "raises if title does not match expected value (Live)", %{conn: conn} do msg = ignore_whitespace(""" @@ -174,6 +182,7 @@ defmodule PhoenixTest.AssertionsTest do end end + # TODO Playwright: Fix error message test "raises if title is contained but is not exactly the same as expected (with exact=true)", %{conn: conn} do msg = @@ -188,6 +197,7 @@ defmodule PhoenixTest.AssertionsTest do end end + # TODO Playwright: Fix error message test "raises error if element cannot be found and selector matches a nested structure", %{ conn: conn } do @@ -217,6 +227,7 @@ defmodule PhoenixTest.AssertionsTest do end end + # TODO Playwright: Support count test "accepts a `count` option", %{conn: conn} do conn |> visit("/page/index") @@ -226,6 +237,7 @@ defmodule PhoenixTest.AssertionsTest do |> assert_has("h1", text: "Main page", count: 1) end + # TODO Playwright: Fix error message test "raises an error if count is more than expected count", %{conn: conn} do session = visit(conn, "/page/index") @@ -241,6 +253,7 @@ defmodule PhoenixTest.AssertionsTest do end end + # TODO Playwright: Fix error message test "raises an error if count is less than expected count", %{conn: conn} do session = visit(conn, "/page/index") @@ -256,13 +269,14 @@ defmodule PhoenixTest.AssertionsTest do end end - test "accepts an `exact` option to match text exactly", %{conn: conn} do + test_also_with_playwright "accepts an `exact` option to match text exactly", %{conn: conn} do conn |> visit("/page/index") |> assert_has("h1", text: "Main", exact: false) |> assert_has("h1", text: "Main page", exact: true) end + # TODO Playwright: Fix error message test "raises if `exact` text doesn't match", %{conn: conn} do msg = ignore_whitespace(""" @@ -282,12 +296,14 @@ defmodule PhoenixTest.AssertionsTest do end end + # TODO Fix: Evaluate both at and text options (there is only one Legolas text) test "accepts an `at` option to assert on a specific element", %{conn: conn} do conn |> visit("/page/index") |> assert_has("#multiple-items li", at: 2, text: "Legolas") end + # TODO Playwright: Fix error message test "raises if it cannot find element at `at` position", %{conn: conn} do msg = ignore_whitespace(""" @@ -303,27 +319,28 @@ defmodule PhoenixTest.AssertionsTest do end describe "refute_has/2" do - test "succeeds if no element is found with CSS selector (Static)", %{conn: conn} do + test_also_with_playwright "succeeds if no element is found with CSS selector (Static)", %{conn: conn} do conn |> visit("/page/index") |> refute_has("#some-invalid-id") |> refute_has("[data-role='invalid-role']") end - test "succeeds if no element is found with CSS selector (Live)", %{conn: conn} do + test_also_with_playwright "succeeds if no element is found with CSS selector (Live)", %{conn: conn} do conn |> visit("/live/index") |> refute_has("#some-invalid-id") |> refute_has("[data-role='invalid-role']") end - test "can refute presence of title (Static)", %{conn: conn} do + test_also_with_playwright "can refute presence of title (Static)", %{conn: conn} do conn |> visit("/page/index_no_layout") |> refute_has("title") |> refute_has("#something-else-to-test-pipe") end + # TODO Playwright: Support 'count' test "accepts a `count` option", %{conn: conn} do conn |> visit("/page/index") @@ -333,6 +350,7 @@ defmodule PhoenixTest.AssertionsTest do |> refute_has(".multiple_links", text: "Multiple links", count: 1) end + # TODO Playwright: Fix error message test "raises if element is found", %{conn: conn} do msg = ignore_whitespace(""" @@ -352,6 +370,7 @@ defmodule PhoenixTest.AssertionsTest do end end + # TODO Playwright: Fix error message test "raises if title is found", %{conn: conn} do msg = ignore_whitespace(""" @@ -365,6 +384,7 @@ defmodule PhoenixTest.AssertionsTest do end end + # TODO Playwright: Fix error message test "raises an error if multiple elements are found", %{conn: conn} do conn = visit(conn, "/page/index") @@ -380,6 +400,7 @@ defmodule PhoenixTest.AssertionsTest do end end + # TODO Playwright: Fix error message test "raises if there is one element and count is 1", %{conn: conn} do conn = visit(conn, "/page/index") @@ -393,6 +414,7 @@ defmodule PhoenixTest.AssertionsTest do end end + # TODO Playwright: Fix error message test "raises if there are the same number of elements as refuted", %{conn: conn} do conn = visit(conn, "/page/index") @@ -410,26 +432,27 @@ defmodule PhoenixTest.AssertionsTest do end describe "refute_has/3" do - test "can be used to refute on page title (Static)", %{conn: conn} do + test_also_with_playwright "can be used to refute on page title (Static)", %{conn: conn} do conn |> visit("/page/index") |> refute_has("title", text: "Not the title") |> refute_has("title", text: "Not this title either") end - test "can be used to refute on page title (Live)", %{conn: conn} do + test_also_with_playwright "can be used to refute on page title (Live)", %{conn: conn} do conn |> visit("/live/index") |> refute_has("title", text: "Not the title") |> refute_has("title", text: "Not this title either") end - test "can be used to refute page title's exactness", %{conn: conn} do + test_also_with_playwright "can be used to refute page title's exactness", %{conn: conn} do conn |> visit("/live/index") |> refute_has("title", text: "PhoenixTest is the", exact: true) end + # TODO Playwright: Fix error message test "raises if title matches value (Static)", %{conn: conn} do msg = ignore_whitespace(""" @@ -443,6 +466,7 @@ defmodule PhoenixTest.AssertionsTest do end end + # TODO Playwright: Fix error message test "raises if title matches value (Live)", %{conn: conn} do msg = ignore_whitespace(""" @@ -456,7 +480,7 @@ defmodule PhoenixTest.AssertionsTest do end end - test "succeeds if no element is found with CSS selector and text (Static)", %{conn: conn} do + test_also_with_playwright "succeeds if no element is found with CSS selector and text (Static)", %{conn: conn} do conn |> visit("/page/index") |> refute_has("h1", text: "Not main page") @@ -465,7 +489,7 @@ defmodule PhoenixTest.AssertionsTest do |> refute_has("#title", text: "Not main page") end - test "succeeds if no element is found with CSS selector and text (Live)", %{conn: conn} do + test_also_with_playwright "succeeds if no element is found with CSS selector and text (Live)", %{conn: conn} do conn |> visit("/live/index") |> refute_has("h1", text: "Not main page") @@ -474,6 +498,7 @@ defmodule PhoenixTest.AssertionsTest do |> refute_has("#title", text: "Not main page") end + # TODO Playwright: Fix error message test "raises an error if one element is found", %{conn: conn} do conn = visit(conn, "/page/index") @@ -493,6 +518,7 @@ defmodule PhoenixTest.AssertionsTest do end end + # TODO Playwright: Fix error message test "raises an error if multiple elements are found", %{conn: conn} do conn = visit(conn, "/page/index") @@ -516,12 +542,13 @@ defmodule PhoenixTest.AssertionsTest do end end - test "accepts an `exact` option to match text exactly", %{conn: conn} do + test_also_with_playwright "accepts an `exact` option to match text exactly", %{conn: conn} do conn |> visit("/page/index") |> refute_has("h1", text: "Main", exact: true) end + # TODO Playwright: Fix error message test "raises if `exact` text makes refutation false", %{conn: conn} do msg = ignore_whitespace(""" @@ -541,18 +568,19 @@ defmodule PhoenixTest.AssertionsTest do end end - test "accepts an `at` option (without text) to refute on a specific element", %{conn: conn} do + test_also_with_playwright "accepts an `at` option (without text) to refute on a specific element", %{conn: conn} do conn |> visit("/page/index") |> refute_has("#single-list-item li", at: 2) end - test "accepts an `at` option with text to refute on a specific element", %{conn: conn} do + test_also_with_playwright "accepts an `at` option with text to refute on a specific element", %{conn: conn} do conn |> visit("/page/index") |> refute_has("#multiple-items li", at: 2, text: "Aragorn") end + # TODO Playwright: Fix error message test "raises if it finds element at `at` position", %{conn: conn} do msg = ignore_whitespace(""" @@ -574,24 +602,25 @@ defmodule PhoenixTest.AssertionsTest do end describe "assert_path" do - test "asserts the session's current path" do + test_also_with_playwright "asserts the session's current path" do session = %Live{current_path: "/page/index"} assert_path(session, "/page/index") end - test "asserts query params are the same" do + test_also_with_playwright "asserts query params are the same" do session = %Live{current_path: "/page/index?hello=world"} assert_path(session, "/page/index", query_params: %{"hello" => "world"}) end - test "order of query params does not matter" do + test_also_with_playwright "order of query params does not matter" do session = %Live{current_path: "/page/index?hello=world&foo=bar"} assert_path(session, "/page/index", query_params: %{"foo" => "bar", "hello" => "world"}) end + # TODO Playwright: Fix error message test "raises helpful error if path doesn't match" do msg = ignore_whitespace(""" @@ -605,6 +634,7 @@ defmodule PhoenixTest.AssertionsTest do end end + # TODO Playwright: Fix error message test "raises helpful error if path doesn't have query params" do msg = ignore_whitespace(""" @@ -618,6 +648,7 @@ defmodule PhoenixTest.AssertionsTest do end end + # TODO Playwright: Fix error message test "raises helpful error if query params don't match" do msg = ignore_whitespace(""" @@ -633,18 +664,19 @@ defmodule PhoenixTest.AssertionsTest do end describe "refute_path" do - test "refute the given path is the current path" do + test_also_with_playwright "refute the given path is the current path" do session = %Live{current_path: "/page/index"} refute_path(session, "/page/page_2") end - test "refutes query params are the same" do + test_also_with_playwright "refutes query params are the same" do session = %Live{current_path: "/page/index?hello=world"} refute_path(session, "/page/index", query_params: %{"hello" => "not-world"}) end + # TODO Playwright: Fix error message test "raises helpful error if path matches" do msg = ignore_whitespace(""" @@ -658,6 +690,7 @@ defmodule PhoenixTest.AssertionsTest do end end + # TODO Playwright: Fix error message test "raises helpful error if query params MATCH" do msg = ignore_whitespace(""" diff --git a/test/phoenix_test/live_test.exs b/test/phoenix_test/live_test.exs index 206d90f6..dd8a5e8e 100644 --- a/test/phoenix_test/live_test.exs +++ b/test/phoenix_test/live_test.exs @@ -1,17 +1,15 @@ defmodule PhoenixTest.LiveTest do use ExUnit.Case, async: true + use PhoenixTest.Case, playwright: :chromium import PhoenixTest import PhoenixTest.Locators + import PhoenixTest.TestHelpers alias PhoenixTest.Driver - setup do - %{conn: Phoenix.ConnTest.build_conn()} - end - describe "render_page_title/1" do - test "renders the page title", %{conn: conn} do + test_also_with_playwright "renders the page title", %{conn: conn} do title = conn |> visit("/live/index") @@ -20,6 +18,7 @@ defmodule PhoenixTest.LiveTest do assert title == "PhoenixTest is the best!" end + # TODO Playwright: Fix by converting to assert_has(title) to include await test "renders updated page title", %{conn: conn} do title = conn @@ -30,6 +29,7 @@ defmodule PhoenixTest.LiveTest do assert title == "Title changed!" end + # TODO Playwright: fix test "returns nil if page title isn't found", %{conn: conn} do title = conn @@ -41,19 +41,19 @@ defmodule PhoenixTest.LiveTest do end describe "visit/2" do - test "navigates to given LiveView page", %{conn: conn} do + test_also_with_playwright "navigates to given LiveView page", %{conn: conn} do conn |> visit("/live/index") |> assert_has("h1", text: "LiveView main page") end - test "follows redirects", %{conn: conn} do + test_also_with_playwright "follows redirects", %{conn: conn} do conn |> visit("/live/redirect_on_mount/redirect") |> assert_has("h1", text: "LiveView main page") end - test "follows push redirects (push navigate)", %{conn: conn} do + test_also_with_playwright "follows push redirects (push navigate)", %{conn: conn} do conn |> visit("/live/redirect_on_mount/push_navigate") |> assert_has("h1", text: "LiveView main page") @@ -69,6 +69,7 @@ defmodule PhoenixTest.LiveTest do end) end + # TODO Playwright: Fix error message test "raises error if route doesn't exist", %{conn: conn} do assert_raise ArgumentError, ~r/404/, fn -> visit(conn, "/live/non_route") @@ -77,35 +78,35 @@ defmodule PhoenixTest.LiveTest do end describe "click_link/2" do - test "follows 'navigate' links", %{conn: conn} do + test_also_with_playwright "follows 'navigate' links", %{conn: conn} do conn |> visit("/live/index") |> click_link("Navigate link") |> assert_has("h1", text: "LiveView page 2") end - test "follows navigation that subsequently redirect", %{conn: conn} do + test_also_with_playwright "follows navigation that subsequently redirect", %{conn: conn} do conn |> visit("/live/index") |> click_link("Navigate (and redirect back) link") |> assert_has("h1", text: "LiveView main page") end - test "accepts click_link with selector", %{conn: conn} do + test_also_with_playwright "accepts click_link with selector", %{conn: conn} do conn |> visit("/live/index") |> click_link("a", "Navigate link") |> assert_has("h1", text: "LiveView page 2") end - test "handles patches to current view", %{conn: conn} do + test_also_with_playwright "handles patches to current view", %{conn: conn} do conn |> visit("/live/index") |> click_link("Patch link") |> assert_has("h2", text: "LiveView main page details") end - test "handles navigation to a non-liveview", %{conn: conn} do + test_also_with_playwright "handles navigation to a non-liveview", %{conn: conn} do conn |> visit("/live/index") |> click_link("Navigate to non-liveview") @@ -123,6 +124,7 @@ defmodule PhoenixTest.LiveTest do end) end + # TODO Playwright: Fix error message test "raises error when there are multiple links with same text", %{conn: conn} do assert_raise ArgumentError, ~r/2 of them matched the text filter/, fn -> conn @@ -131,6 +133,7 @@ defmodule PhoenixTest.LiveTest do end end + # TODO Playwright: Fix error message test "raises an error when link element can't be found with given text", %{conn: conn} do assert_raise ArgumentError, ~r/elements but none matched the text filter "No link"/, fn -> conn @@ -139,6 +142,7 @@ defmodule PhoenixTest.LiveTest do end end + # TODO Playwright: Fix error message test "raises an error when there are no links on the page", %{conn: conn} do assert_raise ArgumentError, ~r/selector "a" did not return any element/, fn -> conn @@ -149,6 +153,7 @@ defmodule PhoenixTest.LiveTest do end describe "click_button/2" do + # TODO Playwright: Fix assert on nested text test "handles a `phx-click` button", %{conn: conn} do conn |> visit("/live/index") @@ -176,7 +181,7 @@ defmodule PhoenixTest.LiveTest do refute PhoenixTest.ActiveForm.active?(session.active_form) end - test "includes name and value if specified", %{conn: conn} do + test_also_with_playwright "includes name and value if specified", %{conn: conn} do conn |> visit("/live/index") |> fill_in("User Name", with: "Aragorn") @@ -184,7 +189,7 @@ defmodule PhoenixTest.LiveTest do |> assert_has("#form-data", text: "user:no-phx-change-form-button: save") end - test "includes default data if form is untouched", %{conn: conn} do + test_also_with_playwright "includes default data if form is untouched", %{conn: conn} do conn |> visit("/live/index") |> click_button("Save Full Form") @@ -196,15 +201,19 @@ defmodule PhoenixTest.LiveTest do |> refute_has("#form-data", text: "disabled_textarea:") end - test "can click button that does not submit form after filling form", %{conn: conn} do + test_also_with_playwright "can click button that does not submit form after filling form", %{conn: conn} do conn |> visit("/live/index") - |> fill_in("Email", with: "some@example.com") + |> within("#email-form", fn session -> + fill_in(session, "Email", with: "some@example.com") + end) |> click_button("Save Nested Form") |> refute_has("#form-data", text: "email: some@example.com") end - test "submits owner form if button isn't nested inside form (including button data)", %{conn: conn} do + test_also_with_playwright "submits owner form if button isn't nested inside form (including button data)", %{ + conn: conn + } do conn |> visit("/live/index") |> within("#owner-form", fn session -> @@ -215,7 +224,7 @@ defmodule PhoenixTest.LiveTest do |> assert_has("#form-data", text: "form-button: save-owner-form") end - test "follows form's redirect to live page", %{conn: conn} do + test_also_with_playwright "follows form's redirect to live page", %{conn: conn} do conn |> visit("/live/index") |> within("#redirect-form", &fill_in(&1, "Name", with: "Aragorn")) @@ -223,7 +232,7 @@ defmodule PhoenixTest.LiveTest do |> assert_has("h1", text: "LiveView page 2") end - test "follows form's redirect to static page", %{conn: conn} do + test_also_with_playwright "follows form's redirect to static page", %{conn: conn} do conn |> visit("/live/index") |> within("#redirect-form-to-static", &fill_in(&1, "Name", with: "Aragorn")) @@ -231,7 +240,7 @@ defmodule PhoenixTest.LiveTest do |> assert_has("h1", text: "Main page") end - test "submits regular (non phx-submit) form", %{conn: conn} do + test_also_with_playwright "submits regular (non phx-submit) form", %{conn: conn} do conn |> visit("/live/index") |> within("#non-liveview-form", &fill_in(&1, "Name", with: "Aragorn")) @@ -239,6 +248,7 @@ defmodule PhoenixTest.LiveTest do |> assert_has("#form-data", text: "name: Aragorn") end + # TODO Playwright: Fix error message test "raises an error if form doesn't have a `phx-submit` or `action`", %{conn: conn} do msg = ~r/to have a `phx-submit` or `action` defined/ @@ -250,6 +260,7 @@ defmodule PhoenixTest.LiveTest do end end + # TODO Playwright: Fix error message test "raises an error when there are no buttons on page", %{conn: conn} do assert_raise ArgumentError, ~r/Could not find an element/, fn -> conn @@ -258,6 +269,7 @@ defmodule PhoenixTest.LiveTest do end end + # TODO Playwright: Fix error message test "raises an error if button is not part of form and has no phx-submit", %{conn: conn} do msg = ~r/to have a valid `phx-click` attribute or belong to a `form` element/ @@ -268,6 +280,7 @@ defmodule PhoenixTest.LiveTest do end end + # TODO Playwright: Fix error message test "raises an error if active form but can't find button", %{conn: conn} do msg = ~r/Could not find an element/ @@ -284,7 +297,7 @@ defmodule PhoenixTest.LiveTest do end describe "within/3" do - test "scopes assertions within selector", %{conn: conn} do + test_also_with_playwright "scopes assertions within selector", %{conn: conn} do conn |> visit("/live/index") |> assert_has("button", text: "Reset") @@ -293,6 +306,7 @@ defmodule PhoenixTest.LiveTest do end) end + # TODO Playwright: Fix assert with locator test "scopes further form actions within a selector", %{conn: conn} do conn |> visit("/live/index") @@ -302,6 +316,7 @@ defmodule PhoenixTest.LiveTest do |> assert_has(input(label: "Email", value: "someone@example.com")) end + # TODO Playwright: Fix error message test "raises when data is not in scoped HTML", %{conn: conn} do assert_raise ArgumentError, ~r/Could not find element with label "User Name"/, fn -> conn @@ -314,14 +329,17 @@ defmodule PhoenixTest.LiveTest do end describe "fill_in/4" do + # TODO Fix IndexLive: phx-update=ignore test "fills in a single text field based on the label", %{conn: conn} do conn |> visit("/live/index") - |> fill_in("Email", with: "someone@example.com") + |> within("#email-form", fn session -> + fill_in(session, "Email", with: "someone@example.com") + end) |> assert_has(input(label: "Email", value: "someone@example.com")) end - test "can fill input with `nil` to override existing value", %{conn: conn} do + test_also_with_playwright "can fill input with `nil` to override existing value", %{conn: conn} do conn |> visit("/live/index") |> within("#pre-rendered-data-form", fn session -> @@ -330,7 +348,7 @@ defmodule PhoenixTest.LiveTest do |> assert_has("#form-data", text: "input's value is empty") end - test "can fill-in textareas", %{conn: conn} do + test_also_with_playwright "can fill-in textareas", %{conn: conn} do conn |> visit("/live/index") |> fill_in("Notes", with: "Dunedain. Heir to the throne. King of Arnor and Gondor") @@ -340,7 +358,7 @@ defmodule PhoenixTest.LiveTest do ) end - test "can fill-in complex form fields", %{conn: conn} do + test_also_with_playwright "can fill-in complex form fields", %{conn: conn} do conn |> visit("/live/index") |> fill_in("First Name", with: "Aragorn") @@ -352,7 +370,7 @@ defmodule PhoenixTest.LiveTest do ) end - test "can fill in numbers", %{conn: conn} do + test_also_with_playwright "can fill in numbers", %{conn: conn} do conn |> visit("/live/index") |> fill_in("Level (number)", with: 10) @@ -360,7 +378,7 @@ defmodule PhoenixTest.LiveTest do |> assert_has("#form-data", text: "level: 10") end - test "works in 'nested' forms", %{conn: conn} do + test_also_with_playwright "works in 'nested' forms", %{conn: conn} do conn |> visit("/live/index") |> fill_in("User Name", with: "Aragorn") @@ -370,24 +388,28 @@ defmodule PhoenixTest.LiveTest do |> assert_has("#form-data", text: "user:role: El Jefe") end - test "can be used to submit form", %{conn: conn} do + test_also_with_playwright "can be used to submit form", %{conn: conn} do conn |> visit("/live/index") - |> fill_in("Email", with: "someone@example.com") + |> within("#email-form", fn session -> + fill_in(session, "Email", with: "someone@example.com") + end) |> click_button("Save Email") |> assert_has("#form-data", text: "email: someone@example.com") end - test "can be combined with other forms' fill_ins (without pollution)", %{conn: conn} do + test_also_with_playwright "can be combined with other forms' fill_ins (without pollution)", %{conn: conn} do conn |> visit("/live/index") - |> fill_in("Email", with: "frodo@example.com") + |> within("#email-form", fn session -> + fill_in(session, "Email", with: "frodo@example.com") + end) |> fill_in("Comments", with: "Hobbit") |> assert_has("#form-data", text: "comments: Hobbit") |> refute_has("#form-data", text: "email: frodo@example.com") end - test "can target a label with exact: false", %{conn: conn} do + test_also_with_playwright "can target a label with exact: false", %{conn: conn} do conn |> visit("/live/index") |> within("#complex-labels", fn session -> @@ -396,7 +418,7 @@ defmodule PhoenixTest.LiveTest do |> assert_has("#form-data", text: "name: Frodo") end - test "can target input with selector if multiple labels have same text", %{conn: conn} do + test_also_with_playwright "can target input with selector if multiple labels have same text", %{conn: conn} do conn |> visit("/live/index") |> within("#same-labels", fn session -> @@ -405,6 +427,7 @@ defmodule PhoenixTest.LiveTest do |> assert_has("#form-data", text: "book-characters: Frodo") end + # TODO Playwright: Fix error message test "raises an error when element can't be found with label", %{conn: conn} do msg = ~r/Could not find element with label "Non-existent Email Label"./ @@ -415,6 +438,7 @@ defmodule PhoenixTest.LiveTest do end end + # TODO Playwright: Fix error message test "raises an error when label is found but no corresponding input is found", %{conn: conn} do msg = ~r/Found label but can't find labeled element whose `id` matches/ @@ -427,21 +451,21 @@ defmodule PhoenixTest.LiveTest do end describe "select/3" do - test "selects given option for a label", %{conn: conn} do + test_also_with_playwright "selects given option for a label", %{conn: conn} do conn |> visit("/live/index") |> select("Elf", from: "Race") |> assert_has("#full-form option[value='elf']") end - test "allows selecting option if a similar option exists", %{conn: conn} do + test_also_with_playwright "allows selecting option if a similar option exists", %{conn: conn} do conn |> visit("/live/index") |> select("Orc", from: "Race") |> assert_has("#full-form option[value='orc']") end - test "works in 'nested' forms", %{conn: conn} do + test_also_with_playwright "works in 'nested' forms", %{conn: conn} do conn |> visit("/live/index") |> select("False", from: "User Admin") @@ -449,7 +473,7 @@ defmodule PhoenixTest.LiveTest do |> assert_has("#form-data", text: "user:admin: false") end - test "can be used to submit form", %{conn: conn} do + test_also_with_playwright "can be used to submit form", %{conn: conn} do conn |> visit("/live/index") |> select("Elf", from: "Race") @@ -457,6 +481,7 @@ defmodule PhoenixTest.LiveTest do |> assert_has("#form-data", text: "race: elf") end + # TODO Playwright: Support select multiple test "works for multiple select", %{conn: conn} do conn |> visit("/live/index") @@ -466,15 +491,17 @@ defmodule PhoenixTest.LiveTest do |> assert_has("#form-data", text: "[elf, dwarf]") end + # TODO Fix IndexLive: phx-update=ignore test "works with phx-click outside of forms", %{conn: conn} do conn |> visit("/live/index") |> within("#not-a-form", fn session -> - select(session, "Dog", from: "Choose a pet:") + select(session, "Cat", from: "Choose a pet:") end) - |> assert_has("#form-data", text: "selected: [dog]") + |> assert_has("#form-data", text: "selected: [cat]") end + # TODO Playwright: Fix selecting multiple test "works with phx-click and multi-select", %{conn: conn} do conn |> visit("/live/index") @@ -484,26 +511,27 @@ defmodule PhoenixTest.LiveTest do |> assert_has("#form-data", text: "selected: [dog, cat]") end - test "can target a label with exact: false", %{conn: conn} do + test_also_with_playwright "can target a label with exact: false", %{conn: conn} do conn |> visit("/live/index") |> within("#complex-labels", fn session -> - select(session, "Dog", from: "Choose a pet:", exact: false) + select(session, "Cat", from: "Choose a pet:", exact: false) end) - |> assert_has("#form-data", text: "pet: dog") + |> assert_has("#form-data", text: "pet: cat") end + # TODO Playwright: Support exact_option test "can target an option's text with exact_option: false", %{conn: conn} do conn |> visit("/live/index") |> within("#full-form", fn session -> - select(session, "Hum", from: "Race", exact_option: false) + select(session, "Dwa", from: "Race", exact_option: false) end) |> submit() - |> assert_has("#form-data", text: "race: human") + |> assert_has("#form-data", text: "race: dwarf") end - test "can target option with selector if multiple labels have same text", %{conn: conn} do + test_also_with_playwright "can target option with selector if multiple labels have same text", %{conn: conn} do conn |> visit("/live/index") |> within("#same-labels", fn session -> @@ -512,6 +540,7 @@ defmodule PhoenixTest.LiveTest do |> assert_has("#form-data", text: "favorite-character: Frodo") end + # TODO Playwright: Fix error message test "raises an error if select option is neither in a form nor has a phx-click", %{conn: conn} do session = visit(conn, "/live/index") @@ -522,7 +551,7 @@ defmodule PhoenixTest.LiveTest do end describe "check/3" do - test "checks a checkbox", %{conn: conn} do + test_also_with_playwright "checks a checkbox", %{conn: conn} do conn |> visit("/live/index") |> check("Admin") @@ -530,7 +559,7 @@ defmodule PhoenixTest.LiveTest do |> assert_has("#form-data", text: "admin: on") end - test "can check an unchecked checkbox", %{conn: conn} do + test_also_with_playwright "can check an unchecked checkbox", %{conn: conn} do conn |> visit("/live/index") |> uncheck("Admin") @@ -539,7 +568,7 @@ defmodule PhoenixTest.LiveTest do |> assert_has("#form-data", text: "admin: on") end - test "handle checkbox name with '?'", %{conn: conn} do + test_also_with_playwright "handle checkbox name with '?'", %{conn: conn} do conn |> visit("/live/index") |> check("Subscribe") @@ -547,7 +576,7 @@ defmodule PhoenixTest.LiveTest do |> assert_has("#form-data", text: "subscribe?: on") end - test "works in 'nested' forms", %{conn: conn} do + test_also_with_playwright "works in 'nested' forms", %{conn: conn} do conn |> visit("/live/index") |> check("Payer") @@ -555,7 +584,7 @@ defmodule PhoenixTest.LiveTest do |> assert_has("#form-data", text: "user:payer: on") end - test "works with phx-click outside a form", %{conn: conn} do + test_also_with_playwright "works with phx-click outside a form", %{conn: conn} do conn |> visit("/live/index") |> within("#not-a-form", fn session -> @@ -564,7 +593,7 @@ defmodule PhoenixTest.LiveTest do |> assert_has("#form-data", text: "value: second-breakfast") end - test "can target a label with exact: false", %{conn: conn} do + test_also_with_playwright "can target a label with exact: false", %{conn: conn} do conn |> visit("/live/index") |> within("#complex-labels", fn session -> @@ -573,7 +602,7 @@ defmodule PhoenixTest.LiveTest do |> assert_has("#form-data", text: "human: yes") end - test "can specify input selector when multiple checkboxes have same label", %{conn: conn} do + test_also_with_playwright "can specify input selector when multiple checkboxes have same label", %{conn: conn} do conn |> visit("/live/index") |> within("#same-labels", fn session -> @@ -582,6 +611,7 @@ defmodule PhoenixTest.LiveTest do |> assert_has("#form-data", text: "like-elixir: yes") end + # TODO Playwright: Fix error message test "raises error if checkbox doesn't have phx-click or belong to form", %{conn: conn} do session = visit(conn, "/live/index") @@ -592,7 +622,7 @@ defmodule PhoenixTest.LiveTest do end describe "uncheck/3" do - test "sends the default value (in hidden input)", %{conn: conn} do + test_also_with_playwright "sends the default value (in hidden input)", %{conn: conn} do conn |> visit("/live/index") |> uncheck("Admin") @@ -600,7 +630,7 @@ defmodule PhoenixTest.LiveTest do |> assert_has("#form-data", text: "admin: off") end - test "can uncheck a previous check/2 in the test", %{conn: conn} do + test_also_with_playwright "can uncheck a previous check/2 in the test", %{conn: conn} do conn |> visit("/live/index") |> check("Admin") @@ -609,7 +639,7 @@ defmodule PhoenixTest.LiveTest do |> assert_has("#form-data", text: "admin: off") end - test "works in 'nested' forms", %{conn: conn} do + test_also_with_playwright "works in 'nested' forms", %{conn: conn} do conn |> visit("/live/index") |> check("Payer") @@ -618,6 +648,7 @@ defmodule PhoenixTest.LiveTest do |> assert_has("#form-data", text: "user:payer: off") end + # TODO Fix IndexLive (phx-update="ignore") test "works with phx-click outside a form", %{conn: conn} do conn |> visit("/live/index") @@ -629,6 +660,7 @@ defmodule PhoenixTest.LiveTest do |> refute_has("#form-data", text: "value: second-breakfast") end + # TODO Fix IndexLive (phx-update="ignore") test "can target a label with exact: false", %{conn: conn} do conn |> visit("/live/index") @@ -640,6 +672,7 @@ defmodule PhoenixTest.LiveTest do |> assert_has("#form-data", text: "human: no") end + # TODO Fix IndexLive (phx-update="ignore") test "can specify input selector when multiple checkboxes have same label", %{conn: conn} do conn |> visit("/live/index") @@ -652,6 +685,7 @@ defmodule PhoenixTest.LiveTest do |> assert_has("#form-data", text: "like-elixir: no") end + # TODO Playwright: Fix error message test "raises error if checkbox doesn't have phx-click or belong to form", %{conn: conn} do session = visit(conn, "/live/index") @@ -662,7 +696,7 @@ defmodule PhoenixTest.LiveTest do end describe "choose/3" do - test "chooses an option in radio button", %{conn: conn} do + test_also_with_playwright "chooses an option in radio button", %{conn: conn} do conn |> visit("/live/index") |> choose("Email Choice") @@ -670,13 +704,14 @@ defmodule PhoenixTest.LiveTest do |> assert_has("#form-data", text: "contact: email") end - test "uses the default 'checked' if present", %{conn: conn} do + test_also_with_playwright "uses the default 'checked' if present", %{conn: conn} do conn |> visit("/live/index") |> click_button("Save Full Form") |> assert_has("#form-data", text: "contact: mail") end + # TODO Fix IndexLive: phx-update=ignore test "works with a phx-click outside of a form", %{conn: conn} do conn |> visit("/live/index") @@ -686,7 +721,7 @@ defmodule PhoenixTest.LiveTest do |> assert_has("#form-data", text: "value: huey") end - test "can target a label with exact: false", %{conn: conn} do + test_also_with_playwright "can target a label with exact: false", %{conn: conn} do conn |> visit("/live/index") |> within("#complex-labels", fn session -> @@ -695,7 +730,9 @@ defmodule PhoenixTest.LiveTest do |> assert_has("#form-data", text: "book-or-movie: book") end - test "can specify input selector when multiple options have same label in same form", %{conn: conn} do + test_also_with_playwright "can specify input selector when multiple options have same label in same form", %{ + conn: conn + } do conn |> visit("/live/index") |> within("#same-labels", fn session -> @@ -704,6 +741,7 @@ defmodule PhoenixTest.LiveTest do |> assert_has("#form-data", text: "elixir-yes: yes") end + # TODO Playwright: Fix error message test "raises an error if radio is neither in a form nor has a phx-click", %{conn: conn} do session = visit(conn, "/live/index") @@ -713,6 +751,7 @@ defmodule PhoenixTest.LiveTest do end end + # TODO Fix IndexLive: add phx-change to all forms and only consume uploaded entries on submit describe "upload/4" do test "uploads an image", %{conn: conn} do conn @@ -747,7 +786,8 @@ defmodule PhoenixTest.LiveTest do |> assert_has("#form-data", text: "main_avatar: elixir.jpg") end - test "upload (without other form actions) does not work with submit (matches browser behavior)", %{conn: conn} do + test "upload (without other form actions) does not work with submit (matches browser behavior)", + %{conn: conn} do session = conn |> visit("/live/index") @@ -762,7 +802,7 @@ defmodule PhoenixTest.LiveTest do end describe "filling out full form with field functions" do - test "populates all fields", %{conn: conn} do + test_also_with_playwright "populates all fields", %{conn: conn} do conn |> visit("/live/index") |> fill_in("First Name", with: "Legolas") @@ -780,7 +820,7 @@ defmodule PhoenixTest.LiveTest do |> assert_has("#form-data", text: "notes: Woodland Elf") end - test "populates all fields in nested forms", %{conn: conn} do + test_also_with_playwright "populates all fields in nested forms", %{conn: conn} do conn |> visit("/live/index") |> fill_in("User Name", with: "Legolas") @@ -792,15 +832,17 @@ defmodule PhoenixTest.LiveTest do end describe "submit/1" do - test "submits a pre-filled form via phx-submit", %{conn: conn} do + test_also_with_playwright "submits a pre-filled form via phx-submit", %{conn: conn} do conn |> visit("/live/index") - |> fill_in("Email", with: "some@example.com") + |> within("#email-form", fn session -> + fill_in(session, "Email", with: "some@example.com") + end) |> submit() |> assert_has("#form-data", text: "email: some@example.com") end - test "includes pre-rendered data", %{conn: conn} do + test_also_with_playwright "includes pre-rendered data", %{conn: conn} do conn |> visit("/live/index") |> fill_in("First Name", with: "Aragorn") @@ -810,7 +852,7 @@ defmodule PhoenixTest.LiveTest do |> assert_has("#form-data", text: "contact: mail") end - test "includes the first button's name and value if present", %{conn: conn} do + test_also_with_playwright "includes the first button's name and value if present", %{conn: conn} do conn |> visit("/live/index") |> fill_in("First Name", with: "Aragorn") @@ -818,7 +860,7 @@ defmodule PhoenixTest.LiveTest do |> assert_has("#form-data", text: "full_form_button: save") end - test "can submit form without button", %{conn: conn} do + test_also_with_playwright "can submit form without button", %{conn: conn} do conn |> visit("/live/index") |> fill_in("Country of Origin", with: "Arnor") @@ -826,7 +868,7 @@ defmodule PhoenixTest.LiveTest do |> assert_has("#form-data", text: "country: Arnor") end - test "follows form's redirect to live page", %{conn: conn} do + test_also_with_playwright "follows form's redirect to live page", %{conn: conn} do conn |> visit("/live/index") |> within("#redirect-form", fn session -> @@ -837,7 +879,7 @@ defmodule PhoenixTest.LiveTest do |> assert_has("h1", text: "LiveView page 2") end - test "follows form's redirect to static page", %{conn: conn} do + test_also_with_playwright "follows form's redirect to static page", %{conn: conn} do conn |> visit("/live/index") |> within("#redirect-form-to-static", fn session -> @@ -863,7 +905,7 @@ defmodule PhoenixTest.LiveTest do end) end - test "submits regular (non phx-submit) form", %{conn: conn} do + test_also_with_playwright "submits regular (non phx-submit) form", %{conn: conn} do conn |> visit("/live/index") |> within("#non-liveview-form", fn session -> @@ -875,6 +917,7 @@ defmodule PhoenixTest.LiveTest do |> assert_has("#form-data", text: "button: save") end + # TODO Playwright: Fix error message test "raises an error if there's no active form", %{conn: conn} do message = ~r/There's no active form. Fill in a form with `fill_in`, `select`, etc./ @@ -885,6 +928,7 @@ defmodule PhoenixTest.LiveTest do end end + # TODO Playwright: Fix error message test "raises an error if form doesn't have a `phx-submit` or `action`", %{conn: conn} do msg = ~r/to have a `phx-submit` or `action` defined/ @@ -942,19 +986,19 @@ defmodule PhoenixTest.LiveTest do end describe "current_path" do - test "it is set on visit", %{conn: conn} do + test_also_with_playwright "it is set on visit", %{conn: conn} do session = visit(conn, "/live/index") assert PhoenixTest.Driver.current_path(session) == "/live/index" end - test "it is set on visit with query string", %{conn: conn} do + test_also_with_playwright "it is set on visit with query string", %{conn: conn} do session = visit(conn, "/live/index?foo=bar") assert PhoenixTest.Driver.current_path(session) == "/live/index?foo=bar" end - test "it is updated on href navigation", %{conn: conn} do + test_also_with_playwright "it is updated on href navigation", %{conn: conn} do session = conn |> visit("/live/index") @@ -963,6 +1007,7 @@ defmodule PhoenixTest.LiveTest do assert PhoenixTest.Driver.current_path(session) == "/page/index?details=true&foo=bar" end + # TODO Playwright: Fix (await?) test "it is updated on live navigation", %{conn: conn} do session = conn @@ -972,7 +1017,7 @@ defmodule PhoenixTest.LiveTest do assert PhoenixTest.Driver.current_path(session) == "/live/page_2?details=true&foo=bar" end - test "it is updated on live patching", %{conn: conn} do + test_also_with_playwright "it is updated on live patching", %{conn: conn} do session = conn |> visit("/live/index") @@ -981,6 +1026,7 @@ defmodule PhoenixTest.LiveTest do assert PhoenixTest.Driver.current_path(session) == "/live/index?details=true&foo=bar" end + # TODO Playwright: Fix (await?) test "it is updated on push navigation", %{conn: conn} do session = conn @@ -990,7 +1036,7 @@ defmodule PhoenixTest.LiveTest do assert PhoenixTest.Driver.current_path(session) == "/live/page_2?foo=bar" end - test "it is updated on push patch", %{conn: conn} do + test_also_with_playwright "it is updated on push patch", %{conn: conn} do session = conn |> visit("/live/index") @@ -1001,21 +1047,27 @@ defmodule PhoenixTest.LiveTest do end describe "shared form helpers behavior" do - test "triggers phx-change validations", %{conn: conn} do + test_also_with_playwright "triggers phx-change validations", %{conn: conn} do conn |> visit("/live/index") - |> fill_in("Email", with: nil) + |> within("#email-form", fn session -> + session + |> fill_in("Email", with: "email") + |> fill_in("Email", with: nil) + end) |> assert_has("#form-errors", text: "Errors present") end - test "sends _target with phx-change events", %{conn: conn} do + test_also_with_playwright "sends _target with phx-change events", %{conn: conn} do conn |> visit("/live/index") - |> fill_in("Email", with: "frodo@example.com") + |> within("#email-form", fn session -> + fill_in(session, "Email", with: "frodo@example.com") + end) |> assert_has("#form-data", text: "_target: [email]") end - test "does not trigger phx-change event if one isn't present", %{conn: conn} do + test_also_with_playwright "does not trigger phx-change event if one isn't present", %{conn: conn} do session = visit(conn, "/live/index") starting_html = Driver.render_html(session) @@ -1028,14 +1080,14 @@ defmodule PhoenixTest.LiveTest do assert starting_html == ending_html end - test "follows redirects on phx-change", %{conn: conn} do + test_also_with_playwright "follows redirects on phx-change", %{conn: conn} do conn |> visit("/live/index") |> fill_in("Email with redirect", with: "someone@example.com") |> assert_has("h1", text: "LiveView page 2") end - test "preserves correct order of active form vs form data", %{conn: conn} do + test_also_with_playwright "preserves correct order of active form vs form data", %{conn: conn} do conn |> visit("/live/index") |> within("#changes-hidden-input-form", fn session -> diff --git a/test/phoenix_test/playwright_test.exs b/test/phoenix_test/playwright_test.exs new file mode 100644 index 00000000..1057f0de --- /dev/null +++ b/test/phoenix_test/playwright_test.exs @@ -0,0 +1,15 @@ +defmodule PhoenixTest.PlaywrightTest do + use ExUnit.Case, async: true + use PlaywrightTest.Case + + describe "render_page_title/1" do + test "renders the page title", %{page: page} do + title = + page + |> PhoenixTest.visit("/page/index") + |> PhoenixTest.Driver.render_page_title() + + assert title == "PhoenixTest is the best!" + end + end +end diff --git a/test/phoenix_test/static_test.exs b/test/phoenix_test/static_test.exs index ffde7598..6c635608 100644 --- a/test/phoenix_test/static_test.exs +++ b/test/phoenix_test/static_test.exs @@ -1,15 +1,12 @@ defmodule PhoenixTest.StaticTest do use ExUnit.Case, async: true + use PhoenixTest.Case, playwright: :chromium import PhoenixTest import PhoenixTest.TestHelpers - setup do - %{conn: Phoenix.ConnTest.build_conn()} - end - describe "render_page_title/1" do - test "renders the page title", %{conn: conn} do + test_also_with_playwright "renders the page title", %{conn: conn} do title = conn |> visit("/page/index") @@ -18,6 +15,7 @@ defmodule PhoenixTest.StaticTest do assert title == "PhoenixTest is the best!" end + # TODO Playwright "" vs nil test "renders nil if there's no page title", %{conn: conn} do title = conn @@ -29,13 +27,13 @@ defmodule PhoenixTest.StaticTest do end describe "visit/2" do - test "navigates to given static page", %{conn: conn} do + test_also_with_playwright "navigates to given static page", %{conn: conn} do conn |> visit("/page/index") |> assert_has("h1", text: "Main page") end - test "follows redirects", %{conn: conn} do + test_also_with_playwright "follows redirects", %{conn: conn} do conn |> visit("/page/redirect_to_static") |> assert_has("h1", text: "Main page") @@ -59,21 +57,21 @@ defmodule PhoenixTest.StaticTest do end describe "click_link/2" do - test "follows link's path", %{conn: conn} do + test_also_with_playwright "follows link's path", %{conn: conn} do conn |> visit("/page/index") |> click_link("Page 2") |> assert_has("h1", text: "Page 2") end - test "follows link that subsequently redirects", %{conn: conn} do + test_also_with_playwright "follows link that subsequently redirects", %{conn: conn} do conn |> visit("/page/index") |> click_link("Navigate away and redirect back") |> assert_has("h1", text: "Main page") end - test "accepts selector for link", %{conn: conn} do + test_also_with_playwright "accepts selector for link", %{conn: conn} do conn |> visit("/page/index") |> click_link("a", "Page 2") @@ -91,17 +89,17 @@ defmodule PhoenixTest.StaticTest do end) end - test "handles navigation to a LiveView", %{conn: conn} do + test_also_with_playwright "handles navigation to a LiveView", %{conn: conn} do conn |> visit("/page/index") |> click_link("To LiveView!") |> assert_has("h1", text: "LiveView main page") end - test "handles form submission via `data-method` & `data-to` attributes", %{conn: conn} do + test_also_with_playwright "handles form submission via `data-method` & `data-to` attributes", %{conn: conn} do conn |> visit("/page/index") - |> click_link("Data-method Delete") + |> click_link("Data_method Delete") |> assert_has("h1", text: "Record deleted") end @@ -135,7 +133,7 @@ defmodule PhoenixTest.StaticTest do end end - test "raises error when there are multiple links with same text", %{conn: conn} do + test_also_with_playwright "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") @@ -143,7 +141,7 @@ defmodule PhoenixTest.StaticTest do end end - test "raises an error when link element can't be found with given text", %{conn: conn} do + test_also_with_playwright "raises an error when link element can't be found with given text", %{conn: conn} do assert_raise ArgumentError, ~r/Could not find element with selector/, fn -> conn |> visit("/page/index") @@ -151,7 +149,7 @@ defmodule PhoenixTest.StaticTest do end end - test "raises an error when there are no links on the page", %{conn: conn} do + test_also_with_playwright "raises an error when there are no links on the page", %{conn: conn} do assert_raise ArgumentError, ~r/Could not find element with selector/, fn -> conn |> visit("/page/page_2") @@ -161,35 +159,35 @@ defmodule PhoenixTest.StaticTest do end describe "click_button/2" do - test "handles a button that defaults to GET", %{conn: conn} do + test_also_with_playwright "handles a button that defaults to GET", %{conn: conn} do conn |> visit("/page/index") |> click_button("Get record") |> assert_has("h1", text: "Record received") end - test "accepts selector for button", %{conn: conn} do + test_also_with_playwright "accepts selector for button", %{conn: conn} do conn |> visit("/page/index") |> click_button("button", "Get record") |> assert_has("h1", text: "Record received") end - test "handles a button clicks when button PUTs data (hidden input)", %{conn: conn} do + test_also_with_playwright "handles a button clicks when button PUTs data (hidden input)", %{conn: conn} do conn |> visit("/page/index") |> click_button("Mark as active") |> assert_has("h1", text: "Record updated") end - test "handles a button clicks when button DELETEs data (hidden input)", %{conn: conn} do + test_also_with_playwright "handles a button clicks when button DELETEs data (hidden input)", %{conn: conn} do conn |> visit("/page/index") |> click_button("Delete record") |> assert_has("h1", text: "Record deleted") end - test "can submit forms with input type submit", %{conn: conn} do + test_also_with_playwright "can submit forms with input type submit", %{conn: conn} do conn |> visit("/page/index") |> fill_in("Email", with: "sample@example.com") @@ -197,7 +195,7 @@ defmodule PhoenixTest.StaticTest do |> assert_has("#form-data", text: "email: sample@example.com") end - test "can handle clicking button that does not submit form after filling a form", %{conn: conn} do + test_also_with_playwright "can handle clicking button that does not submit form after filling a form", %{conn: conn} do conn |> visit("/page/index") |> fill_in("Email", with: "some@example.com") @@ -205,7 +203,7 @@ defmodule PhoenixTest.StaticTest do |> refute_has("#form-data", text: "email: some@example.com") end - test "submits owner form if button isn't nested inside form", %{conn: conn} do + test_also_with_playwright "submits owner form if button isn't nested inside form", %{conn: conn} do conn |> visit("/page/index") |> within("#owner-form", fn session -> @@ -215,17 +213,17 @@ defmodule PhoenixTest.StaticTest do |> assert_has("#form-data", text: "name: Aragorn") end - test "can handle redirects to a LiveView", %{conn: conn} do + test_also_with_playwright "can handle redirects to a LiveView", %{conn: conn} do conn |> visit("/page/index") |> click_button("Post and Redirect") |> assert_has("h1", text: "LiveView main page") end - test "handles form submission via `data-method` & `data-to` attributes", %{conn: conn} do + test_also_with_playwright "handles form submission via `data-method` & `data-to` attributes", %{conn: conn} do conn |> visit("/page/index") - |> click_button("Data-method Delete") + |> click_button("Data_method Delete") |> assert_has("h1", text: "Record deleted") end @@ -249,7 +247,7 @@ defmodule PhoenixTest.StaticTest do refute PhoenixTest.ActiveForm.active?(session.active_form) end - test "includes name and value if specified", %{conn: conn} do + test_also_with_playwright "includes name and value if specified", %{conn: conn} do conn |> visit("/page/index") |> fill_in("User Name", with: "Aragorn") @@ -257,7 +255,7 @@ defmodule PhoenixTest.StaticTest do |> assert_has("#form-data", text: "user:save-button: nested-form-save") end - test "can handle clicking button that does not submit form after fill_in", %{conn: conn} do + test_also_with_playwright "can handle clicking button that does not submit form after fill_in", %{conn: conn} do conn |> visit("/page/index") |> fill_in("Email", with: "some@example.com") @@ -265,7 +263,7 @@ defmodule PhoenixTest.StaticTest do |> refute_has("#form-data", text: "email: some@example.com") end - test "includes default data if form is untouched", %{conn: conn} do + test_also_with_playwright "includes default data if form is untouched", %{conn: conn} do conn |> visit("/page/index") |> click_button("Save Full Form") @@ -287,7 +285,7 @@ defmodule PhoenixTest.StaticTest do end end - test "raises an error when there are no buttons on page", %{conn: conn} do + test_also_with_playwright "raises an error when there are no buttons on page", %{conn: conn} do msg = ~r/Could not find an element with given selectors/ assert_raise ArgumentError, msg, fn -> @@ -297,7 +295,7 @@ defmodule PhoenixTest.StaticTest do end end - test "raises an error if can't find button", %{conn: conn} do + test_also_with_playwright "raises an error if can't find button", %{conn: conn} do msg = ~r/Could not find an element with given selectors/ assert_raise ArgumentError, msg, fn -> @@ -320,6 +318,7 @@ defmodule PhoenixTest.StaticTest do end describe "within/3" do + # TODO Playwright: Fix refute_has test "scopes assertions within selector", %{conn: conn} do conn |> visit("/page/index") @@ -329,7 +328,7 @@ defmodule PhoenixTest.StaticTest do end) end - test "scopes further form actions within a selector", %{conn: conn} do + test_also_with_playwright "scopes further form actions within a selector", %{conn: conn} do conn |> visit("/page/index") |> within("#email-form", fn session -> @@ -340,7 +339,7 @@ defmodule PhoenixTest.StaticTest do |> assert_has("#form-data", text: "email: someone@example.com") end - test "raises when data is not in scoped HTML", %{conn: conn} do + test_also_with_playwright "raises when data is not in scoped HTML", %{conn: conn} do assert_raise ArgumentError, ~r/Could not find element with label "User Name"/, fn -> conn |> visit("/page/index") @@ -352,7 +351,7 @@ defmodule PhoenixTest.StaticTest do end describe "fill_in/4" do - test "fills in a single text field based on the label", %{conn: conn} do + test_also_with_playwright "fills in a single text field based on the label", %{conn: conn} do conn |> visit("/page/index") |> fill_in("Email", with: "someone@example.com") @@ -360,7 +359,7 @@ defmodule PhoenixTest.StaticTest do |> assert_has("#form-data", text: "email: someone@example.com") end - test "can fill input with `nil` to override existing value", %{conn: conn} do + test_also_with_playwright "can fill input with `nil` to override existing value", %{conn: conn} do conn |> visit("/page/index") |> fill_in("Pre Rendered Input", with: nil) @@ -368,7 +367,7 @@ defmodule PhoenixTest.StaticTest do |> assert_has("#form-data", text: "input's value is empty") end - test "can fill-in complex form fields", %{conn: conn} do + test_also_with_playwright "can fill-in complex form fields", %{conn: conn} do conn |> visit("/page/index") |> fill_in("First Name", with: "Aragorn") @@ -380,7 +379,7 @@ defmodule PhoenixTest.StaticTest do ) end - test "can fill in numbers", %{conn: conn} do + test_also_with_playwright "can fill in numbers", %{conn: conn} do conn |> visit("/page/index") |> fill_in("Level (number)", with: 10) @@ -388,7 +387,7 @@ defmodule PhoenixTest.StaticTest do |> assert_has("#form-data", text: "level: 10") end - test "works in 'nested' forms", %{conn: conn} do + test_also_with_playwright "works in 'nested' forms", %{conn: conn} do conn |> visit("/page/index") |> fill_in("User Name", with: "Aragorn") @@ -399,7 +398,7 @@ defmodule PhoenixTest.StaticTest do |> assert_has("#form-data", text: "user:role: El Jefe") end - test "can be combined with other forms' fill_ins (without pollution)", %{conn: conn} do + test_also_with_playwright "can be combined with other forms' fill_ins (without pollution)", %{conn: conn} do conn |> visit("/page/index") |> fill_in("First Name", with: "Aragorn") @@ -409,7 +408,7 @@ defmodule PhoenixTest.StaticTest do |> assert_has("#form-data", text: "user:name: Legolas") end - test "can target a label with exact: false", %{conn: conn} do + test_also_with_playwright "can target a label with exact: false", %{conn: conn} do conn |> visit("/page/index") |> within("#complex-labels", fn session -> @@ -419,7 +418,7 @@ defmodule PhoenixTest.StaticTest do |> assert_has("#form-data", text: "name: Frodo") end - test "can target input with selector if multiple labels have same text", %{conn: conn} do + test_also_with_playwright "can target input with selector if multiple labels have same text", %{conn: conn} do conn |> visit("/page/index") |> within("#same-labels", fn session -> @@ -429,7 +428,7 @@ defmodule PhoenixTest.StaticTest do |> assert_has("#form-data", text: "book-characters: Frodo") end - test "raises an error when element can't be found with label", %{conn: conn} do + test_also_with_playwright "raises an error when element can't be found with label", %{conn: conn} do msg = ~r/Could not find element with label "Non-existent Email Label"./ assert_raise ArgumentError, msg, fn -> @@ -439,6 +438,7 @@ defmodule PhoenixTest.StaticTest do end end + # TODO Playwright: Fix error message test "raises an error when label is found but no corresponding input is found", %{conn: conn} do msg = ~r/Found label but can't find labeled element whose `id` matches/ @@ -451,7 +451,7 @@ defmodule PhoenixTest.StaticTest do end describe "select/3" do - test "selects given option for a label", %{conn: conn} do + test_also_with_playwright "selects given option for a label", %{conn: conn} do conn |> visit("/page/index") |> select("Elf", from: "Race") @@ -459,21 +459,21 @@ defmodule PhoenixTest.StaticTest do |> assert_has("#form-data", text: "race: elf") end - test "picks first by default", %{conn: conn} do + test_also_with_playwright "picks first by default", %{conn: conn} do conn |> visit("/page/index") |> click_button("Save Full Form") |> assert_has("#form-data", text: "race: human") end - test "allows selecting option if a similar option exists", %{conn: conn} do + test_also_with_playwright "allows selecting option if a similar option exists", %{conn: conn} do conn |> visit("/page/index") |> select("Orc", from: "Race") |> assert_has("#full-form option[value='orc']") end - test "works in 'nested' forms", %{conn: conn} do + test_also_with_playwright "works in 'nested' forms", %{conn: conn} do conn |> visit("/page/index") |> select("False", from: "User Admin") @@ -481,6 +481,7 @@ defmodule PhoenixTest.StaticTest do |> assert_has("#form-data", text: "user:admin: false") end + # TODO Playwright: Support selecting multiple test "handles multi select", %{conn: conn} do conn |> visit("/page/index") @@ -489,13 +490,14 @@ defmodule PhoenixTest.StaticTest do |> assert_has("#form-data", text: "race_2: [elf,dwarf]") end - test "contains no data for empty multi select", %{conn: conn} do + test_also_with_playwright "contains no data for empty multi select", %{conn: conn} do conn |> visit("/page/index") |> click_button("Save Full Form") |> refute_has("#form-data", text: "race_2") end + # TODO Playwright: Support submit() when select is focused test "can target a label with exact: false", %{conn: conn} do conn |> visit("/page/index") @@ -506,6 +508,7 @@ defmodule PhoenixTest.StaticTest do |> assert_has("#form-data", text: "pet: dog") end + # TODO Playwright: Use strict=false test "can target an option's text with exact_option: false", %{conn: conn} do conn |> visit("/page/index") @@ -516,6 +519,7 @@ defmodule PhoenixTest.StaticTest do |> assert_has("#form-data", text: "race: human") end + # TODO Playwright: Support submit() when select is focused test "can target option with selector if multiple labels have same text", %{conn: conn} do conn |> visit("/page/index") @@ -528,7 +532,7 @@ defmodule PhoenixTest.StaticTest do end describe "check/3" do - test "checks a checkbox", %{conn: conn} do + test_also_with_playwright "checks a checkbox", %{conn: conn} do conn |> visit("/page/index") |> check("Admin (boolean)") @@ -536,7 +540,7 @@ defmodule PhoenixTest.StaticTest do |> assert_has("#form-data", text: "admin_boolean: true") end - test "sets checkbox value as 'on' by default", %{conn: conn} do + test_also_with_playwright "sets checkbox value as 'on' by default", %{conn: conn} do conn |> visit("/page/index") |> check("Admin") @@ -544,7 +548,7 @@ defmodule PhoenixTest.StaticTest do |> assert_has("#form-data", text: "admin: on") end - test "can check an unchecked checkbox", %{conn: conn} do + test_also_with_playwright "can check an unchecked checkbox", %{conn: conn} do conn |> visit("/page/index") |> uncheck("Admin") @@ -553,7 +557,7 @@ defmodule PhoenixTest.StaticTest do |> assert_has("#form-data", text: "admin: on") end - test "handle checkbox name with '?'", %{conn: conn} do + test_also_with_playwright "handle checkbox name with '?'", %{conn: conn} do conn |> visit("/page/index") |> check("Subscribe") @@ -561,7 +565,7 @@ defmodule PhoenixTest.StaticTest do |> assert_has("#form-data", text: "subscribe?: on") end - test "can target a label with exact: false", %{conn: conn} do + test_also_with_playwright "can target a label with exact: false", %{conn: conn} do conn |> visit("/page/index") |> within("#complex-labels", fn session -> @@ -571,7 +575,7 @@ defmodule PhoenixTest.StaticTest do |> assert_has("#form-data", text: "human: yes") end - test "can specify input selector when multiple checkboxes have same label", %{conn: conn} do + test_also_with_playwright "can specify input selector when multiple checkboxes have same label", %{conn: conn} do conn |> visit("/page/index") |> within("#same-labels", fn session -> @@ -583,7 +587,7 @@ defmodule PhoenixTest.StaticTest do end describe "uncheck/3" do - test "sends the default value (in hidden input)", %{conn: conn} do + test_also_with_playwright "sends the default value (in hidden input)", %{conn: conn} do conn |> visit("/page/index") |> uncheck("Admin") @@ -591,7 +595,7 @@ defmodule PhoenixTest.StaticTest do |> assert_has("#form-data", text: "admin: off") end - test "can uncheck a previous check/2 in the test", %{conn: conn} do + test_also_with_playwright "can uncheck a previous check/2 in the test", %{conn: conn} do conn |> visit("/page/index") |> check("Admin") @@ -600,7 +604,7 @@ defmodule PhoenixTest.StaticTest do |> assert_has("#form-data", text: "admin: off") end - test "can target a label with exact: false", %{conn: conn} do + test_also_with_playwright "can target a label with exact: false", %{conn: conn} do conn |> visit("/page/index") |> within("#complex-labels", fn session -> @@ -612,7 +616,7 @@ defmodule PhoenixTest.StaticTest do |> assert_has("#form-data", text: "human: no") end - test "can specify input selector when multiple checkboxes have same label", %{conn: conn} do + test_also_with_playwright "can specify input selector when multiple checkboxes have same label", %{conn: conn} do conn |> visit("/page/index") |> within("#same-labels", fn session -> @@ -627,7 +631,7 @@ defmodule PhoenixTest.StaticTest do end describe "choose/3" do - test "chooses an option in radio button", %{conn: conn} do + test_also_with_playwright "chooses an option in radio button", %{conn: conn} do conn |> visit("/page/index") |> choose("Email Choice") @@ -635,14 +639,14 @@ defmodule PhoenixTest.StaticTest do |> assert_has("#form-data", text: "contact: email") end - test "uses the default 'checked' if present", %{conn: conn} do + test_also_with_playwright "uses the default 'checked' if present", %{conn: conn} do conn |> visit("/page/index") |> click_button("Save Full Form") |> assert_has("#form-data", text: "contact: mail") end - test "can target a label with exact: false", %{conn: conn} do + test_also_with_playwright "can target a label with exact: false", %{conn: conn} do conn |> visit("/page/index") |> within("#complex-labels", fn session -> @@ -652,7 +656,9 @@ defmodule PhoenixTest.StaticTest do |> assert_has("#form-data", text: "book-or-movie: book") end - test "can specify input selector when multiple options have same label in same form", %{conn: conn} do + test_also_with_playwright "can specify input selector when multiple options have same label in same form", %{ + conn: conn + } do conn |> visit("/page/index") |> within("#same-labels", fn session -> @@ -665,7 +671,7 @@ defmodule PhoenixTest.StaticTest do end describe "upload/4" do - test "uploads image", %{conn: conn} do + test_also_with_playwright "uploads image", %{conn: conn} do conn |> visit("/page/index") |> within("#file-upload-form", fn session -> @@ -676,6 +682,7 @@ defmodule PhoenixTest.StaticTest do |> assert_has("#form-data", text: "avatar: elixir.jpg") end + # TODO Playwright: Support multiple subsequent upload calls for same field test "uploads image list", %{conn: conn} do conn |> visit("/page/index") @@ -686,7 +693,7 @@ defmodule PhoenixTest.StaticTest do |> assert_has("#form-data", text: "avatars:[]: phoenix.jpg") end - test "uploads an image in nested forms", %{conn: conn} do + test_also_with_playwright "uploads an image in nested forms", %{conn: conn} do conn |> visit("/page/index") |> upload("Nested Avatar", "test/files/elixir.jpg") @@ -694,7 +701,7 @@ defmodule PhoenixTest.StaticTest do |> assert_has("#form-data", text: "user:avatar: elixir.jpg") end - test "can target a label with exact: false", %{conn: conn} do + test_also_with_playwright "can target a label with exact: false", %{conn: conn} do conn |> visit("/page/index") |> within("#complex-labels", fn session -> @@ -705,6 +712,7 @@ defmodule PhoenixTest.StaticTest do |> assert_has("#form-data", text: "avatar: elixir.jpg") end + # TODO Playwright: fix test "can specify input selector when multiple inputs have same label", %{conn: conn} do conn |> visit("/page/index") @@ -717,7 +725,7 @@ defmodule PhoenixTest.StaticTest do end describe "filling out full form with field functions" do - test "populates all fields", %{conn: conn} do + test_also_with_playwright "populates all fields", %{conn: conn} do conn |> visit("/page/index") |> fill_in("First Name", with: "Legolas") @@ -735,7 +743,7 @@ defmodule PhoenixTest.StaticTest do |> assert_has("#form-data", text: "notes: Woodland Elf") end - test "populates all fields in nested forms", %{conn: conn} do + test_also_with_playwright "populates all fields in nested forms", %{conn: conn} do conn |> visit("/page/index") |> fill_in("User Name", with: "Legolas") @@ -747,7 +755,7 @@ defmodule PhoenixTest.StaticTest do end describe "submit/1" do - test "submits form even if no submit is present (acts as )", %{conn: conn} do + test_also_with_playwright "submits form even if no submit is present (acts as )", %{conn: conn} do conn |> visit("/page/index") |> within("#no-submit-button-form", fn session -> @@ -758,8 +766,8 @@ defmodule PhoenixTest.StaticTest do |> assert_has("#form-data", text: "name: Aragorn") end - test "includes pre-rendered data (input value, selected option, checked checkbox, checked radio button)", - %{conn: conn} do + test_also_with_playwright "includes pre-rendered data (input value, selected option, checked checkbox, checked radio button)", + %{conn: conn} do conn |> visit("/page/index") |> fill_in("First Name", with: "Aragorn") @@ -768,7 +776,7 @@ defmodule PhoenixTest.StaticTest do |> assert_has("#form-data", text: "race: human") end - test "includes the first button's name and value if present", %{conn: conn} do + test_also_with_playwright "includes the first button's name and value if present", %{conn: conn} do conn |> visit("/page/index") |> fill_in("First Name", with: "Aragorn") @@ -776,7 +784,7 @@ defmodule PhoenixTest.StaticTest do |> assert_has("#form-data", text: "full_form_button: save") end - test "can submit form without button", %{conn: conn} do + test_also_with_playwright "can submit form without button", %{conn: conn} do conn |> visit("/page/index") |> fill_in("Country of Origin", with: "Arnor") @@ -784,7 +792,7 @@ defmodule PhoenixTest.StaticTest do |> assert_has("#form-data", text: "country: Arnor") end - test "can handle redirects", %{conn: conn} do + test_also_with_playwright "can handle redirects", %{conn: conn} do conn |> visit("/page/index") |> within("#no-submit-button-and-redirect", fn session -> @@ -810,7 +818,7 @@ defmodule PhoenixTest.StaticTest do end) end - test "handles when form PUTs data through hidden input", %{conn: conn} do + test_also_with_playwright "handles when form PUTs data through hidden input", %{conn: conn} do conn |> visit("/page/index") |> within("#update-form", fn session -> @@ -821,7 +829,7 @@ defmodule PhoenixTest.StaticTest do |> assert_has("#form-data", text: "name: Aragorn") end - test "handles a button clicks when button DELETEs data (hidden input)", %{conn: conn} do + test_also_with_playwright "handles a button clicks when button DELETEs data (hidden input)", %{conn: conn} do conn |> visit("/page/index") |> click_button("Delete record") @@ -862,7 +870,7 @@ defmodule PhoenixTest.StaticTest do %{open_fun: open_fun} end - test "opens the browser ", %{conn: conn, open_fun: open_fun} do + test_also_with_playwright "opens the browser ", %{conn: conn, open_fun: open_fun} do conn |> visit("/page/index") |> open_browser(open_fun) @@ -897,18 +905,19 @@ defmodule PhoenixTest.StaticTest do end describe "current_path" do - test "it is set on visit", %{conn: conn} do + test_also_with_playwright "it is set on visit", %{conn: conn} do session = visit(conn, "/page/index") assert PhoenixTest.Driver.current_path(session) == "/page/index" end - test "it includes query string if available", %{conn: conn} do + test_also_with_playwright "it includes query string if available", %{conn: conn} do session = visit(conn, "/page/index?foo=bar") assert PhoenixTest.Driver.current_path(session) == "/page/index?foo=bar" end + # TODO Playwright: Fix (maybe not possible, because need to await navigation) test "it is updated on href navigation", %{conn: conn} do session = conn @@ -918,7 +927,7 @@ defmodule PhoenixTest.StaticTest do assert PhoenixTest.Driver.current_path(session) == "/page/page_2?foo=bar" end - test "it is updated on redirects", %{conn: conn} do + test_also_with_playwright "it is updated on redirects", %{conn: conn} do session = conn |> visit("/page/index") diff --git a/test/support/index_live.ex b/test/support/index_live.ex index a77218e1..c6bcbda0 100644 --- a/test/support/index_live.ex +++ b/test/support/index_live.ex @@ -334,12 +334,12 @@ defmodule PhoenixTest.IndexLive do Do you like Elixir? - + Do you like Erlang - +
diff --git a/test/support/page_view.ex b/test/support/page_view.ex index d02f084e..caf7d212 100644 --- a/test/support/page_view.ex +++ b/test/support/page_view.ex @@ -66,13 +66,13 @@ defmodule PhoenixTest.PageView do data-to="/page/delete_record" data-csrf="sometoken" > - Data-method Delete + Data_method Delete
@@ -348,12 +348,12 @@ defmodule PhoenixTest.PageView do Do you like Elixir? - + Do you like Erlang - +
diff --git a/test/support/test_helpers.ex b/test/support/test_helpers.ex index a5906dc7..bc1cf9ab 100644 --- a/test/support/test_helpers.ex +++ b/test/support/test_helpers.ex @@ -1,6 +1,8 @@ defmodule PhoenixTest.TestHelpers do @moduledoc false + require ExUnit.Case + @doc """ Converts a multi-line string into a whitespace-forgiving regex """ @@ -12,4 +14,15 @@ defmodule PhoenixTest.TestHelpers do |> Enum.map_join("\n", fn s -> "\\s*" <> s <> "\\s*" end) |> Regex.compile!([:dotall]) end + + defmacro test_also_with_playwright(message, var \\ quote(do: _), contents) do + quote location: :keep do + tags = Module.get_attribute(__MODULE__, :tag) + ExUnit.Case.test(unquote(message), unquote(var), unquote(contents)) + + for tag <- tags, do: @tag(tag) + @tag :playwright + ExUnit.Case.test(unquote(message) <> " (JS)", unquote(var), unquote(contents)) + end + end end diff --git a/test/test_helper.exs b/test/test_helper.exs index 3dd79ff0..5703ed83 100644 --- a/test/test_helper.exs +++ b/test/test_helper.exs @@ -2,3 +2,5 @@ ExUnit.start() {:ok, _} = Supervisor.start_link([{Phoenix.PubSub, name: PhoenixTest.PubSub}], strategy: :one_for_one) {:ok, _} = PhoenixTest.Endpoint.start_link() + +Application.put_env(:phoenix_test, :base_url, PhoenixTest.Endpoint.url())