Skip to content

Commit

Permalink
Add check and uncheck
Browse files Browse the repository at this point in the history
What changed?
============

We add `check` and `uncheck` functions to work with our new way of
interacting with forms.

Note that these rely on a form being present. They are not supposed to
be used outside of a form. We could make it so in the future, but for
now we keep them trying to replace the form, no trying to also handle
clicks (e.g. via `render_click` on `phx-click` presence).

Note on uncheck error message
----------------------------

It would be nice to add a better error when we're trying to find the
hidden input to "uncheck" but we can't. Right now it just fails with a
maybe surprising error if you don't know that checkboxes need hidden
inputs to "uncheck".

https://developer.mozilla.org/en-US/docs/Web/HTML/Element/Input/checkbox#value
  • Loading branch information
germsvel committed Mar 30, 2024
1 parent 5da74ec commit 58110b4
Show file tree
Hide file tree
Showing 8 changed files with 152 additions and 5 deletions.
6 changes: 6 additions & 0 deletions lib/phoenix_test.ex
Original file line number Diff line number Diff line change
Expand Up @@ -224,6 +224,12 @@ defmodule PhoenixTest do
@doc false
defdelegate select(session, option, attrs), to: Driver

@doc false
defdelegate check(session, label), to: Driver

@doc false
defdelegate uncheck(session, label), to: Driver

@doc """
Fills form data, validating that input fields are present.
Expand Down
2 changes: 2 additions & 0 deletions lib/phoenix_test/driver.ex
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ defprotocol PhoenixTest.Driver do
def click_button(session, selector, text)
def fill_in(session, label, attrs)
def select(session, option, attrs)
def check(session, label)
def uncheck(session, label)
def fill_form(session, selector, form_data)
def submit_form(session, selector, form_data)
def open_browser(session)
Expand Down
50 changes: 47 additions & 3 deletions lib/phoenix_test/live.ex
Original file line number Diff line number Diff line change
Expand Up @@ -102,11 +102,12 @@ defimpl PhoenixTest.Driver, for: PhoenixTest.Live do

field = Query.find_by_label!(html, label)
field_id = Html.attribute(field, "id")
name = Html.attribute(field, "name")

form = Query.find_ancestor!(html, "form", "##{field_id}")
id = Html.attribute(form, "id")

new_form_data = Utils.name_to_map(Html.attribute(field, "name"), value)
new_form_data = Utils.name_to_map(name, value)

active_form = add_to_active_form_data(session, new_form_data)

Expand All @@ -123,11 +124,54 @@ defimpl PhoenixTest.Driver, for: PhoenixTest.Live do

form = Query.find_ancestor!(html, "form", "##{field_id}")
id = Html.attribute(form, "id")
name = Html.attribute(field, "name")

option = Query.find!(Html.raw(field), "option", option)
value = Html.attribute(option, "value")
option_value = Html.attribute(option, "value")

new_form_data = Utils.name_to_map(Html.attribute(field, "name"), value)
new_form_data = Utils.name_to_map(name, option_value)

active_form = add_to_active_form_data(session, new_form_data)

session
|> PhoenixTest.Live.put_private(:active_form, active_form)
|> fill_form("form##{id}", active_form.form_data)
end

def check(session, label) do
html = render_html(session)

field = Query.find_by_label!(html, label)
field_id = Html.attribute(field, "id")
name = Html.attribute(field, "name")
value = Html.attribute(field, "value")

form = Query.find_ancestor!(html, "form", "##{field_id}")
id = Html.attribute(form, "id")

new_form_data = Utils.name_to_map(name, value)

active_form = add_to_active_form_data(session, new_form_data)

session
|> PhoenixTest.Live.put_private(:active_form, active_form)
|> fill_form("form##{id}", active_form.form_data)
end

def uncheck(session, label) do
html = render_html(session)

field = Query.find_by_label!(html, label)
field_id = Html.attribute(field, "id")
name = Html.attribute(field, "name")

hidden_input = Query.find!(html, "input[type='hidden'][name=#{name}]")
value = Html.attribute(hidden_input, "value")

form = Query.find_ancestor!(html, "form", "##{field_id}")
id = Html.attribute(form, "id")

new_form_data = Utils.name_to_map(name, value)

active_form = add_to_active_form_data(session, new_form_data)

Expand Down
42 changes: 42 additions & 0 deletions lib/phoenix_test/static.ex
Original file line number Diff line number Diff line change
Expand Up @@ -146,6 +146,26 @@ defimpl PhoenixTest.Driver, for: PhoenixTest.Static do
|> fill_form("form##{id}", active_form.form_data)
end

def check(session, label) do
html = render_html(session)

field = Query.find_by_label!(html, label)
field_id = Html.attribute(field, "id")
name = Html.attribute(field, "name")
value = Html.attribute(field, "value") || "on"

form = Query.find_ancestor!(html, "form", "##{field_id}")
id = Html.attribute(form, "id")

new_form_data = Utils.name_to_map(name, value)

active_form = add_to_active_form_data(session, new_form_data)

session
|> PhoenixTest.Static.put_private(:active_form, active_form)
|> fill_form("form##{id}", active_form.form_data)
end

defp add_to_active_form_data(session, new_form_data) do
session
|> PhoenixTest.Static.get_private(:active_form, %{form_data: %{}})
Expand All @@ -154,6 +174,28 @@ defimpl PhoenixTest.Driver, for: PhoenixTest.Static do
end)
end

def uncheck(session, label) do
html = render_html(session)

field = Query.find_by_label!(html, label)
field_id = Html.attribute(field, "id")
name = Html.attribute(field, "name")

hidden_input = Query.find!(html, "input[type='hidden'][name=#{name}]")
value = Html.attribute(hidden_input, "value")

form = Query.find_ancestor!(html, "form", "##{field_id}")
id = Html.attribute(form, "id")

new_form_data = Utils.name_to_map(name, value)

active_form = add_to_active_form_data(session, new_form_data)

session
|> PhoenixTest.Static.put_private(:active_form, active_form)
|> fill_form("form##{id}", active_form.form_data)
end

def fill_form(session, selector, form_data) do
form_element =
session
Expand Down
20 changes: 20 additions & 0 deletions test/phoenix_test/live_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -225,6 +225,26 @@ defmodule PhoenixTest.LiveTest do
end
end

describe "check/3" do
test "checks a checkbox", %{conn: conn} do
conn
|> visit("/live/index")
|> check("Admin")
|> click_button("Save")
|> assert_has("#form-data", text: "admin: on")
end
end

describe "uncheck/3" do
test "sends the default value (in hidden input)", %{conn: conn} do
conn
|> visit("/live/index")
|> uncheck("Admin")
|> click_button("Save")
|> assert_has("#form-data", text: "admin: off")
end
end

describe "fill_form/3" do
test "does not trigger phx-change event if one isn't present", %{conn: conn} do
session = conn |> visit("/live/index")
Expand Down
28 changes: 28 additions & 0 deletions test/phoenix_test/static_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -277,6 +277,34 @@ defmodule PhoenixTest.StaticTest do
end
end

describe "check/3" do
test "checks a checkbox", %{conn: conn} do
conn
|> visit("/page/index")
|> check("Admin (boolean)")
|> click_button("Save")
|> assert_has("#form-data", text: "admin_boolean: true")
end

test "sets checkbox value as 'on' by default", %{conn: conn} do
conn
|> visit("/page/index")
|> check("Admin")
|> click_button("Save")
|> assert_has("#form-data", text: "admin: on")
end
end

describe "uncheck/3" do
test "sends the default value (in hidden input)", %{conn: conn} do
conn
|> visit("/page/index")
|> uncheck("Admin")
|> click_button("Save")
|> assert_has("#form-data", text: "admin: off")
end
end

describe "fill_form/3" do
test "raises an error when form cannot be found with given selector", %{conn: conn} do
assert_raise ArgumentError, ~r/Could not find element with selector/, fn ->
Expand Down
3 changes: 2 additions & 1 deletion test/support/index_live.ex
Original file line number Diff line number Diff line change
Expand Up @@ -61,8 +61,9 @@ defmodule PhoenixTest.IndexLive do
<label for="first_name">First Name</label>
<input id="first_name" name="first_name" />
<input type="hidden" name="admin" value="off" />
<label for="admin">Admin</label>
<input type="checkbox" name="admin" value="on" />
<input id="admin" type="checkbox" name="admin" value="on" />
<label for="race">Race</label>
<select id="race" name="race">
Expand Down
6 changes: 5 additions & 1 deletion test/support/page_view.ex
Original file line number Diff line number Diff line change
Expand Up @@ -114,8 +114,12 @@ defmodule PhoenixTest.PageView do
<label for="name">First Name</label>
<input type="text" id="name" name="name" />
<input type="hidden" name="admin" value="off" />
<label for="admin">Admin</label>
<input type="checkbox" name="admin" />
<input id="admin" type="checkbox" name="admin" />
<label for="admin_boolean">Admin (boolean)</label>
<input id="admin_boolean" type="checkbox" name="admin_boolean" value="true" />
<label for="race">Race</label>
<select id="race" name="race">
Expand Down

0 comments on commit 58110b4

Please sign in to comment.