From 33d2db212fe9420494854ee9bd1006224b7e47b5 Mon Sep 17 00:00:00 2001 From: Buck Doyle Date: Fri, 16 Jan 2026 21:49:27 -0600 Subject: [PATCH 1/8] Fix more registrations tests in CI --- registrations/test/integration/admin_test.exs | 13 ++-- registrations/test/integration/home_test.exs | 12 ++- .../test/integration/messages_test.exs | 8 +- .../test/integration/questions_test.exs | 6 +- .../test/integration/registrations_test.exs | 76 ++++++++++++++----- registrations/test/integration/teams_test.exs | 5 +- registrations/test/support/pages/home.ex | 31 +++++--- registrations/test/support/pages/nav.ex | 37 ++++++++- 8 files changed, 135 insertions(+), 53 deletions(-) diff --git a/registrations/test/integration/admin_test.exs b/registrations/test/integration/admin_test.exs index 5dd1aec2..df97af38 100644 --- a/registrations/test/integration/admin_test.exs +++ b/registrations/test/integration/admin_test.exs @@ -92,7 +92,7 @@ defmodule Registrations.Integration.Admin do Users.build_team_from(session, a.id) - assert Nav.info_text(session) == "Team built successfully" + assert Nav.info_text(session, "Team built successfully") == "Team built successfully" assert Users.teamed(session, a.id) assert Users.teamed(session, b.id) @@ -136,7 +136,8 @@ defmodule Registrations.Integration.Admin do Nav.users_link().click(session) Users.build_team_from(session, a.id) - assert Nav.error_text(session) == "Team built with placeholders!" + assert Nav.error_text(session, "Team built with placeholders!") == + "Team built with placeholders!" Nav.teams_link().click(session) @@ -193,13 +194,13 @@ defmodule Registrations.Integration.Admin do refute page_source(session) =~ "francine.pascal@example.com" visit(session, "/messages") - assert Nav.error_text(session) == "Who are you?" + assert Nav.error_text(session, "Who are you?") == "Who are you?" visit(session, "/teams") - assert Nav.error_text(session) == "Who are you?" + assert Nav.error_text(session, "Who are you?") == "Who are you?" visit(session, "/settings") - assert Nav.error_text(session) == "Who are you?" + assert Nav.error_text(session, "Who are you?") == "Who are you?" end end @@ -245,7 +246,7 @@ defmodule Registrations.Integration.UnmnemonicDevices.Admin do insert(:user, email: "francine.pascal@example.com") visit(session, "/settings") - assert Nav.error_text(session) == "Who are you?" + assert Nav.error_text(session, "Who are you?") == "Who are you?" end test "admin can view team JSON that includes voicepasses", %{session: session} do diff --git a/registrations/test/integration/home_test.exs b/registrations/test/integration/home_test.exs index 7597feaf..649db5aa 100644 --- a/registrations/test/integration/home_test.exs +++ b/registrations/test/integration/home_test.exs @@ -191,7 +191,8 @@ defmodule Registrations.Waydowntown.Integration.Home do Home.fill_waitlist_question(session, "When will the event take place?") Home.submit_waitlist(session) - assert Nav.info_text(session) == "we’ll let you know when registration opens" + assert Nav.info_text(session, "we’ll let you know when registration opens") == + "we’ll let you know when registration opens" wait_for_emails([sent_email]) assert sent_email.to == [{"", "mdrysdale@waydown.town"}] @@ -240,7 +241,8 @@ defmodule Registrations.Waydowntown.Integration.Home do Home.submit_waitlist(session) - assert Nav.info_text(session) == "was that an email address?" + assert Nav.info_text(session, "was that an email address?") == + "was that an email address?" assert wait_for_emails([]) == [] end @@ -268,7 +270,8 @@ defmodule Registrations.Waydowntown.Integration.Home do Home.fill_waitlist_question(session, "When will the event take place?") Home.submit_waitlist(session) - assert Nav.info_text(session) == "we’ll let you know when registration opens" + assert Nav.info_text(session, "we’ll let you know when registration opens") == + "we’ll let you know when registration opens" assert wait_for_emails([]) == [] end @@ -296,7 +299,8 @@ defmodule Registrations.Waydowntown.Integration.Home do Home.fill_waitlist_question(session, "When will this unwanted event take place?") Home.submit_waitlist(session) - assert Nav.info_text(session) == "we’ll let you know when registration opens" + assert Nav.info_text(session, "we’ll let you know when registration opens") == + "we’ll let you know when registration opens" assert wait_for_emails([]) == [] end diff --git a/registrations/test/integration/messages_test.exs b/registrations/test/integration/messages_test.exs index 703c85f7..1c6ad990 100644 --- a/registrations/test/integration/messages_test.exs +++ b/registrations/test/integration/messages_test.exs @@ -47,7 +47,7 @@ defmodule Registrations.Integration.Messages do Messages.send(session) - assert Nav.info_text(session) == "Message was sent" + assert Nav.info_text(session, "Message was sent") == "Message was sent" wait_for_emails([empty_email, _ignored1, email, _ignored2]) assert email.to == [{"", "user@example.com"}] @@ -96,7 +96,7 @@ defmodule Registrations.Integration.Messages do Messages.send_to_me(session) - assert Nav.info_text(session) == "Message was sent" + assert Nav.info_text(session, "Message was sent") == "Message was sent" wait_for_emails([email]) assert email.to == [{"", "admin@example.com"}] @@ -129,7 +129,7 @@ defmodule Registrations.Integration.Messages do Messages.send(session) - assert Nav.info_text(session) == "Message was sent" + assert Nav.info_text(session, "Message was sent") == "Message was sent" wait_for_emails([email]) assert email.from == {"Knut", "knut@example.com"} @@ -175,7 +175,7 @@ defmodule Registrations.Integration.Messages do Messages.send(session) - assert Nav.info_text(session) == "Message was sent" + assert Nav.info_text(session, "Message was sent") == "Message was sent" sent_emails = wait_for_emails([_email1, _email2, _email3, _email4]) diff --git a/registrations/test/integration/questions_test.exs b/registrations/test/integration/questions_test.exs index cc9b00e6..eb202328 100644 --- a/registrations/test/integration/questions_test.exs +++ b/registrations/test/integration/questions_test.exs @@ -21,7 +21,8 @@ defmodule Registrations.ClandestineRendezvous.Integration.Questions do Home.submit_question(session) - assert Nav.info_text(session) == "Your question has been submitted." + assert Nav.info_text(session, "Your question has been submitted.") == + "Your question has been submitted." wait_for_emails([sent_email]) assert sent_email.to == [{"", "b@events.chromatin.ca"}] @@ -58,7 +59,8 @@ defmodule Registrations.UnmnemonicDevices.Integration.Questions do Home.submit_question(session) - assert Nav.info_text(session) == "Your question has been submitted." + assert Nav.info_text(session, "Your question has been submitted.") == + "Your question has been submitted." wait_for_emails([sent_email]) assert sent_email.to == [{"", "knut@chromatin.ca"}] diff --git a/registrations/test/integration/registrations_test.exs b/registrations/test/integration/registrations_test.exs index b12f144c..69d0a067 100644 --- a/registrations/test/integration/registrations_test.exs +++ b/registrations/test/integration/registrations_test.exs @@ -19,7 +19,10 @@ defmodule Registrations.Integration.ClandestineRendezvous.Registrations do Register.submit(session) - assert Nav.error_text(session) == + assert Nav.error_text( + session, + "Oops, something went wrong! Please check the errors below:\nPassword can't be blank\nEmail can't be blank" + ) == "Oops, something went wrong! Please check the errors below:\nPassword can't be blank\nEmail can't be blank" assert Register.email_error(session) == "Email can't be blank" @@ -29,7 +32,10 @@ defmodule Registrations.Integration.ClandestineRendezvous.Registrations do Register.fill_email(session, "franklin.w.dixon@example.com") Register.submit(session) - assert Nav.error_text(session) == + assert Nav.error_text( + session, + "Oops, something went wrong! Please check the errors below:\nPassword can't be blank" + ) == "Oops, something went wrong! Please check the errors below:\nPassword can't be blank" Register.fill_email(session, "samuel.delaney@example.com") @@ -37,7 +43,7 @@ defmodule Registrations.Integration.ClandestineRendezvous.Registrations do Register.fill_password_confirmation(session, "nestofspiders") Register.submit(session) - assert Nav.info_text(session) == "Your account was created" + assert Nav.info_text(session, "Your account was created") == "Your account was created" wait_for_emails([admin_email, welcome_email]) @@ -67,20 +73,23 @@ defmodule Registrations.Integration.ClandestineRendezvous.Registrations do Login.fill_password(session, "Parable of the Talents") Login.submit(session) - assert Nav.error_text(session) == + assert Nav.error_text( + session, + "The provided login details did not work. Please verify your credentials, and try again." + ) == "The provided login details did not work. Please verify your credentials, and try again." Login.fill_password(session, "Xenogenesis") Login.submit(session) - assert Nav.info_text(session) == "Logged in" + assert Nav.info_text(session, "Logged in") == "Logged in" assert Nav.logout_link().text(session) == "Log out octavia.butler@example.com" assert Details.active?(session) Nav.logout_link().click(session) - assert Nav.info_text(session) == "Logged out" + assert Nav.info_text(session, "Logged out") == "Logged out" assert Nav.login_link().present?(session) assert Nav.register_link().present?(session) end @@ -99,7 +108,10 @@ defmodule Registrations.Integration.ClandestineRendezvous.Registrations do Account.fill_current_password(session, "Wrong") Account.submit(session) - assert Nav.error_text(session) == + assert Nav.error_text( + session, + "Oops, something went wrong! Please check the errors below:\nCurrent password is invalid" + ) == "Oops, something went wrong! Please check the errors below:\nCurrent password is invalid" Account.fill_current_password(session, "Xenogenesis") @@ -107,7 +119,10 @@ defmodule Registrations.Integration.ClandestineRendezvous.Registrations do Account.fill_new_password_confirmation(session, "vwxyz") Account.submit(session) - assert Nav.error_text(session) == + assert Nav.error_text( + session, + "Oops, something went wrong! Please check the errors below:\nPassword should be at least 8 character(s)\nPassword confirmation does not match confirmation" + ) == "Oops, something went wrong! Please check the errors below:\nPassword should be at least 8 character(s)\nPassword confirmation does not match confirmation" Account.fill_current_password(session, "Xenogenesis") @@ -115,7 +130,8 @@ defmodule Registrations.Integration.ClandestineRendezvous.Registrations do Account.fill_new_password_confirmation(session, "Lilith’s Brood") Account.submit(session) - assert Nav.info_text(session) == "Your account has been updated." + assert Nav.info_text(session, "Your account has been updated.") == + "Your account has been updated." Nav.logout_link().click(session) @@ -126,13 +142,16 @@ defmodule Registrations.Integration.ClandestineRendezvous.Registrations do Login.fill_password(session, "Xenogenesis") Login.submit(session) - assert Nav.error_text(session) == + assert Nav.error_text( + session, + "The provided login details did not work. Please verify your credentials, and try again." + ) == "The provided login details did not work. Please verify your credentials, and try again." Login.fill_password(session, "Lilith’s Brood") Login.submit(session) - assert Nav.info_text(session) == "Logged in" + assert Nav.info_text(session, "Logged in") == "Logged in" end test "forgot password", %{session: session} do @@ -148,7 +167,10 @@ defmodule Registrations.Integration.ClandestineRendezvous.Registrations do ForgotPassword.fill_email(session, "octavia.butler@example.com") ForgotPassword.submit(session) - assert Nav.info_text(session) == + assert Nav.info_text( + session, + "If an account for the provided email exists, an email with reset instructions will be sent to you. Please check your inbox." + ) == "If an account for the provided email exists, an email with reset instructions will be sent to you. Please check your inbox." wait_for_emails([forgot_password_email]) @@ -167,7 +189,8 @@ defmodule Registrations.Integration.ClandestineRendezvous.Registrations do assert String.starts_with?(reset_path, "/reset-password/") visit(session, "/reset-password/fake") - assert Nav.error_text(session) == "The reset token has expired." + assert Nav.error_text(session, "The reset token has expired.") == + "The reset token has expired." visit(session, reset_path) @@ -175,14 +198,18 @@ defmodule Registrations.Integration.ClandestineRendezvous.Registrations do Account.fill_new_password_confirmation(session, "awrongpassword") Account.submit(session) - assert Nav.error_text(session) == + assert Nav.error_text( + session, + "Oops, something went wrong! Please check the errors below:\nPassword confirmation does not match confirmation" + ) == "Oops, something went wrong! Please check the errors below:\nPassword confirmation does not match confirmation" Account.fill_new_password(session, "anewpassword") Account.fill_new_password_confirmation(session, "anewpassword") Account.submit(session) - assert Nav.info_text(session) == "The password has been updated." + assert Nav.info_text(session, "The password has been updated.") == + "The password has been updated." Login.fill_email(session, "Octavia.butler@example.com") Login.fill_password(session, "anewpassword") @@ -198,7 +225,8 @@ defmodule Registrations.Integration.ClandestineRendezvous.Registrations do Nav.logout_link().click(session) visit(session, reset_path) - assert Nav.error_text(session) == "The reset token has expired." + assert Nav.error_text(session, "The reset token has expired.") == + "The reset token has expired." end test "delete account", %{session: session} do @@ -210,7 +238,8 @@ defmodule Registrations.Integration.ClandestineRendezvous.Registrations do Nav.edit_details(session) Details.delete_account(session) - assert Nav.info_text(session) == "Your account has been deleted. Sorry to see you go!" + assert Nav.info_text(session, "Your account has been deleted. Sorry to see you go!") == + "Your account has been deleted. Sorry to see you go!" wait_for_emails([admin_email]) @@ -227,7 +256,8 @@ defmodule Registrations.Integration.ClandestineRendezvous.Registrations do Login.fill_password(session, "Xenogenesis") Login.submit(session) - assert Nav.info_text(session) == "Your account has been deleted. Sorry to see you go!" + assert Nav.info_text(session, "Your account has been deleted. Sorry to see you go!") == + "Your account has been deleted. Sorry to see you go!" end test "when registration is closed, a warning is displayed on the registration and details routes", @@ -242,13 +272,19 @@ defmodule Registrations.Integration.ClandestineRendezvous.Registrations do Nav.register_link().click(session) - assert Nav.error_text(session) == + assert Nav.error_text( + session, + "Registration is closed; however, you may continue and we will email you" + ) == "Registration is closed; however, you may continue and we will email you" insert(:octavia) Login.login_as_admin(session) - assert Nav.error_text(session) == + assert Nav.error_text( + session, + "You may change your details but it’s too late to guarantee the changes can be integrated" + ) == "You may change your details but it’s too late to guarantee the changes can be integrated" end end diff --git a/registrations/test/integration/teams_test.exs b/registrations/test/integration/teams_test.exs index 88b80bb2..ba1f90bb 100644 --- a/registrations/test/integration/teams_test.exs +++ b/registrations/test/integration/teams_test.exs @@ -65,7 +65,7 @@ defmodule Registrations.Integration.Teams do Details.submit(session) - assert Nav.info_text(session) == "Your details were saved" + assert Nav.info_text(session, "Your details were saved") == "Your details were saved" assert Details.accessibility_text(session) == "Some accessibility information" assert Details.comments().value(session) == "Some comments" @@ -229,7 +229,8 @@ defmodule Registrations.Integration.Teams do } do visit(session, "/details") - assert Nav.info_text(session) == "Please log in to edit your details" + assert Nav.info_text(session, "Please log in to edit your details") == + "Please log in to edit your details" Login.fill_email(session, "anemail") end diff --git a/registrations/test/support/pages/home.ex b/registrations/test/support/pages/home.ex index 061a5454..882a4d0e 100644 --- a/registrations/test/support/pages/home.ex +++ b/registrations/test/support/pages/home.ex @@ -43,21 +43,30 @@ defmodule Registrations.Pages.Home do Registrations.Pages.Home.Pi end - defmodule Pi do - @moduledoc false - alias Wallaby.Browser - alias Wallaby.Query + defmodule Pi do + @moduledoc false + alias Wallaby.Browser + alias Wallaby.Query + require WaitForIt - @selector "#pi" + @selector "#pi" - def present?(session) do - Browser.has?(session, Query.css(@selector)) - end + def present?(session) do + Browser.has?(session, Query.css(@selector)) + end - def click(session) do - Browser.click(session, Query.css(@selector)) + def click(session) do + WaitForIt.wait( + try do + Browser.click(session, Query.css(@selector)) + true + rescue + Wallaby.StaleReferenceError -> false + Wallaby.QueryError -> false + end + ) + end end - end def overlay do Registrations.Pages.Home.Overlay diff --git a/registrations/test/support/pages/nav.ex b/registrations/test/support/pages/nav.ex index 746acb5a..bc320c07 100644 --- a/registrations/test/support/pages/nav.ex +++ b/registrations/test/support/pages/nav.ex @@ -2,17 +2,18 @@ defmodule Registrations.Pages.Nav do @moduledoc false alias Wallaby.Browser alias Wallaby.Query + require WaitForIt def present?(session) do Browser.has?(session, Query.css(".row.nav")) end - def info_text(session) do - Browser.text(session, Query.css(".alert-info")) + def info_text(session, expected \\ nil) do + flash_text(session, ".alert-info", expected) end - def error_text(session) do - Browser.text(session, Query.css(".alert-danger")) + def error_text(session, expected \\ nil) do + flash_text(session, ".alert-danger", expected) end def register_link do @@ -136,4 +137,32 @@ defmodule Registrations.Pages.Nav do Browser.click(session, Query.css(@selector)) end end + + defp flash_text(session, selector, expected) when is_binary(expected) do + WaitForIt.wait(flash_text_matches?(session, selector, expected)) + expected + end + + defp flash_text(session, selector, nil) do + WaitForIt.wait(match?({:ok, _}, safe_text(session, selector))) + + {:ok, text} = safe_text(session, selector) + text + end + + defp flash_text_matches?(session, selector, expected) do + case safe_text(session, selector) do + {:ok, text} -> text == expected + :error -> false + end + end + + defp safe_text(session, selector) do + try do + {:ok, Browser.text(session, Query.css(selector))} + rescue + Wallaby.StaleReferenceError -> :error + Wallaby.QueryError -> :error + end + end end From 335a5742164b4ef6d20562db3710913a6fee526c Mon Sep 17 00:00:00 2001 From: Buck Doyle Date: Fri, 16 Jan 2026 22:35:11 -0600 Subject: [PATCH 2/8] Add more fixes --- registrations/test/integration/home_test.exs | 1 + registrations/test/integration/registrations_test.exs | 1 + registrations/test/support/pages/nav.ex | 7 +++++++ 3 files changed, 9 insertions(+) diff --git a/registrations/test/integration/home_test.exs b/registrations/test/integration/home_test.exs index 649db5aa..f78c032d 100644 --- a/registrations/test/integration/home_test.exs +++ b/registrations/test/integration/home_test.exs @@ -171,6 +171,7 @@ defmodule Registrations.Waydowntown.Integration.Home do Login.fill_email(session, "Octavia.butler@example.com") Login.fill_password(session, "Xenogenesis") Login.submit(session) + assert Nav.logout_link().text(session) == "Log out octavia.butler@example.com" visit(session, "/") refute(Home.placeholder_exists?(session)) diff --git a/registrations/test/integration/registrations_test.exs b/registrations/test/integration/registrations_test.exs index 69d0a067..398ae28b 100644 --- a/registrations/test/integration/registrations_test.exs +++ b/registrations/test/integration/registrations_test.exs @@ -134,6 +134,7 @@ defmodule Registrations.Integration.ClandestineRendezvous.Registrations do "Your account has been updated." Nav.logout_link().click(session) + assert Nav.info_text(session, "Logged out") == "Logged out" visit(session, "/") Nav.login_link().click(session) diff --git a/registrations/test/support/pages/nav.ex b/registrations/test/support/pages/nav.ex index bc320c07..d3fcb572 100644 --- a/registrations/test/support/pages/nav.ex +++ b/registrations/test/support/pages/nav.ex @@ -54,14 +54,17 @@ defmodule Registrations.Pages.Nav do @moduledoc false alias Wallaby.Browser alias Wallaby.Query + require WaitForIt @selector "a.logout" def text(session) do + WaitForIt.wait(Browser.has?(session, Query.css(@selector))) Browser.text(session, Query.css(@selector)) end def click(session) do + WaitForIt.wait(Browser.has?(session, Query.css(@selector))) Browser.click(session, Query.css(@selector)) end end @@ -70,10 +73,12 @@ defmodule Registrations.Pages.Nav do @moduledoc false alias Wallaby.Browser alias Wallaby.Query + require WaitForIt @selector "a.login" def click(session) do + WaitForIt.wait(Browser.has?(session, Query.css(@selector))) Browser.click(session, Query.css(@selector)) end @@ -86,10 +91,12 @@ defmodule Registrations.Pages.Nav do @moduledoc false alias Wallaby.Browser alias Wallaby.Query + require WaitForIt @selector "a.register" def click(session) do + WaitForIt.wait(Browser.has?(session, Query.css(@selector))) Browser.click(session, Query.css(@selector)) end From f2155148256e9bc8268fa33bf708461cff29e43e Mon Sep 17 00:00:00 2001 From: Buck Doyle Date: Sat, 17 Jan 2026 00:11:31 -0600 Subject: [PATCH 3/8] Add downcasing MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit I really dislike this… is there a better way --- registrations/test/integration/home_test.exs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/registrations/test/integration/home_test.exs b/registrations/test/integration/home_test.exs index f78c032d..5b2dcc13 100644 --- a/registrations/test/integration/home_test.exs +++ b/registrations/test/integration/home_test.exs @@ -171,7 +171,8 @@ defmodule Registrations.Waydowntown.Integration.Home do Login.fill_email(session, "Octavia.butler@example.com") Login.fill_password(session, "Xenogenesis") Login.submit(session) - assert Nav.logout_link().text(session) == "Log out octavia.butler@example.com" + assert String.downcase(Nav.logout_link().text(session)) == + "log out octavia.butler@example.com" visit(session, "/") refute(Home.placeholder_exists?(session)) From 3cb8ff7000f76ad4b6d3a0c1e4c49e70bd8c4646 Mon Sep 17 00:00:00 2001 From: Buck Doyle Date: Sat, 17 Jan 2026 11:17:53 -0600 Subject: [PATCH 4/8] Move assertions into page objects Still sceptical! --- registrations/test/integration/admin_test.exs | 13 +- registrations/test/integration/home_test.exs | 15 +-- .../test/integration/invitations_test.exs | 2 +- .../test/integration/messages_test.exs | 8 +- .../test/integration/questions_test.exs | 6 +- .../test/integration/registrations_test.exs | 126 ++++++++---------- registrations/test/integration/teams_test.exs | 5 +- registrations/test/support/pages/nav.ex | 39 +++++- 8 files changed, 113 insertions(+), 101 deletions(-) diff --git a/registrations/test/integration/admin_test.exs b/registrations/test/integration/admin_test.exs index df97af38..82491d0f 100644 --- a/registrations/test/integration/admin_test.exs +++ b/registrations/test/integration/admin_test.exs @@ -92,7 +92,7 @@ defmodule Registrations.Integration.Admin do Users.build_team_from(session, a.id) - assert Nav.info_text(session, "Team built successfully") == "Team built successfully" + Nav.assert_info_text(session, "Team built successfully") assert Users.teamed(session, a.id) assert Users.teamed(session, b.id) @@ -136,8 +136,7 @@ defmodule Registrations.Integration.Admin do Nav.users_link().click(session) Users.build_team_from(session, a.id) - assert Nav.error_text(session, "Team built with placeholders!") == - "Team built with placeholders!" + Nav.assert_error_text(session, "Team built with placeholders!") Nav.teams_link().click(session) @@ -194,13 +193,13 @@ defmodule Registrations.Integration.Admin do refute page_source(session) =~ "francine.pascal@example.com" visit(session, "/messages") - assert Nav.error_text(session, "Who are you?") == "Who are you?" + Nav.assert_error_text(session, "Who are you?") visit(session, "/teams") - assert Nav.error_text(session, "Who are you?") == "Who are you?" + Nav.assert_error_text(session, "Who are you?") visit(session, "/settings") - assert Nav.error_text(session, "Who are you?") == "Who are you?" + Nav.assert_error_text(session, "Who are you?") end end @@ -246,7 +245,7 @@ defmodule Registrations.Integration.UnmnemonicDevices.Admin do insert(:user, email: "francine.pascal@example.com") visit(session, "/settings") - assert Nav.error_text(session, "Who are you?") == "Who are you?" + Nav.assert_error_text(session, "Who are you?") end test "admin can view team JSON that includes voicepasses", %{session: session} do diff --git a/registrations/test/integration/home_test.exs b/registrations/test/integration/home_test.exs index 5b2dcc13..97c36c37 100644 --- a/registrations/test/integration/home_test.exs +++ b/registrations/test/integration/home_test.exs @@ -171,8 +171,7 @@ defmodule Registrations.Waydowntown.Integration.Home do Login.fill_email(session, "Octavia.butler@example.com") Login.fill_password(session, "Xenogenesis") Login.submit(session) - assert String.downcase(Nav.logout_link().text(session)) == - "log out octavia.butler@example.com" + Nav.assert_logged_in_as(session, "octavia.butler@example.com") visit(session, "/") refute(Home.placeholder_exists?(session)) @@ -193,8 +192,7 @@ defmodule Registrations.Waydowntown.Integration.Home do Home.fill_waitlist_question(session, "When will the event take place?") Home.submit_waitlist(session) - assert Nav.info_text(session, "we’ll let you know when registration opens") == - "we’ll let you know when registration opens" + Nav.assert_info_text(session, "we’ll let you know when registration opens") wait_for_emails([sent_email]) assert sent_email.to == [{"", "mdrysdale@waydown.town"}] @@ -243,8 +241,7 @@ defmodule Registrations.Waydowntown.Integration.Home do Home.submit_waitlist(session) - assert Nav.info_text(session, "was that an email address?") == - "was that an email address?" + Nav.assert_info_text(session, "was that an email address?") assert wait_for_emails([]) == [] end @@ -272,8 +269,7 @@ defmodule Registrations.Waydowntown.Integration.Home do Home.fill_waitlist_question(session, "When will the event take place?") Home.submit_waitlist(session) - assert Nav.info_text(session, "we’ll let you know when registration opens") == - "we’ll let you know when registration opens" + Nav.assert_info_text(session, "we’ll let you know when registration opens") assert wait_for_emails([]) == [] end @@ -301,8 +297,7 @@ defmodule Registrations.Waydowntown.Integration.Home do Home.fill_waitlist_question(session, "When will this unwanted event take place?") Home.submit_waitlist(session) - assert Nav.info_text(session, "we’ll let you know when registration opens") == - "we’ll let you know when registration opens" + Nav.assert_info_text(session, "we’ll let you know when registration opens") assert wait_for_emails([]) == [] end diff --git a/registrations/test/integration/invitations_test.exs b/registrations/test/integration/invitations_test.exs index c6b295fc..919551e2 100644 --- a/registrations/test/integration/invitations_test.exs +++ b/registrations/test/integration/invitations_test.exs @@ -55,6 +55,6 @@ defmodule Registrations.Integration.Invitations do Register.fill_password_confirmation(session, "simulteneity") Register.submit(session) - assert Nav.logout_link().text(session) == "Log out bedap@example.com" + Nav.assert_logged_in_as(session, "bedap@example.com") end end diff --git a/registrations/test/integration/messages_test.exs b/registrations/test/integration/messages_test.exs index 1c6ad990..af978d1c 100644 --- a/registrations/test/integration/messages_test.exs +++ b/registrations/test/integration/messages_test.exs @@ -47,7 +47,7 @@ defmodule Registrations.Integration.Messages do Messages.send(session) - assert Nav.info_text(session, "Message was sent") == "Message was sent" + Nav.assert_info_text(session, "Message was sent") wait_for_emails([empty_email, _ignored1, email, _ignored2]) assert email.to == [{"", "user@example.com"}] @@ -96,7 +96,7 @@ defmodule Registrations.Integration.Messages do Messages.send_to_me(session) - assert Nav.info_text(session, "Message was sent") == "Message was sent" + Nav.assert_info_text(session, "Message was sent") wait_for_emails([email]) assert email.to == [{"", "admin@example.com"}] @@ -129,7 +129,7 @@ defmodule Registrations.Integration.Messages do Messages.send(session) - assert Nav.info_text(session, "Message was sent") == "Message was sent" + Nav.assert_info_text(session, "Message was sent") wait_for_emails([email]) assert email.from == {"Knut", "knut@example.com"} @@ -175,7 +175,7 @@ defmodule Registrations.Integration.Messages do Messages.send(session) - assert Nav.info_text(session, "Message was sent") == "Message was sent" + Nav.assert_info_text(session, "Message was sent") sent_emails = wait_for_emails([_email1, _email2, _email3, _email4]) diff --git a/registrations/test/integration/questions_test.exs b/registrations/test/integration/questions_test.exs index eb202328..61f368ae 100644 --- a/registrations/test/integration/questions_test.exs +++ b/registrations/test/integration/questions_test.exs @@ -21,8 +21,7 @@ defmodule Registrations.ClandestineRendezvous.Integration.Questions do Home.submit_question(session) - assert Nav.info_text(session, "Your question has been submitted.") == - "Your question has been submitted." + Nav.assert_info_text(session, "Your question has been submitted.") wait_for_emails([sent_email]) assert sent_email.to == [{"", "b@events.chromatin.ca"}] @@ -59,8 +58,7 @@ defmodule Registrations.UnmnemonicDevices.Integration.Questions do Home.submit_question(session) - assert Nav.info_text(session, "Your question has been submitted.") == - "Your question has been submitted." + Nav.assert_info_text(session, "Your question has been submitted.") wait_for_emails([sent_email]) assert sent_email.to == [{"", "knut@chromatin.ca"}] diff --git a/registrations/test/integration/registrations_test.exs b/registrations/test/integration/registrations_test.exs index 398ae28b..03ac1df3 100644 --- a/registrations/test/integration/registrations_test.exs +++ b/registrations/test/integration/registrations_test.exs @@ -19,11 +19,10 @@ defmodule Registrations.Integration.ClandestineRendezvous.Registrations do Register.submit(session) - assert Nav.error_text( - session, - "Oops, something went wrong! Please check the errors below:\nPassword can't be blank\nEmail can't be blank" - ) == - "Oops, something went wrong! Please check the errors below:\nPassword can't be blank\nEmail can't be blank" + Nav.assert_error_text( + session, + "Oops, something went wrong! Please check the errors below:\nPassword can't be blank\nEmail can't be blank" + ) assert Register.email_error(session) == "Email can't be blank" # FIXME fix plural detection @@ -32,18 +31,17 @@ defmodule Registrations.Integration.ClandestineRendezvous.Registrations do Register.fill_email(session, "franklin.w.dixon@example.com") Register.submit(session) - assert Nav.error_text( - session, - "Oops, something went wrong! Please check the errors below:\nPassword can't be blank" - ) == - "Oops, something went wrong! Please check the errors below:\nPassword can't be blank" + Nav.assert_error_text( + session, + "Oops, something went wrong! Please check the errors below:\nPassword can't be blank" + ) Register.fill_email(session, "samuel.delaney@example.com") Register.fill_password(session, "nestofspiders") Register.fill_password_confirmation(session, "nestofspiders") Register.submit(session) - assert Nav.info_text(session, "Your account was created") == "Your account was created" + Nav.assert_info_text(session, "Your account was created") wait_for_emails([admin_email, welcome_email]) @@ -56,7 +54,7 @@ defmodule Registrations.Integration.ClandestineRendezvous.Registrations do assert String.contains?(welcome_email.text_body, "secret society") assert String.contains?(welcome_email.html_body, "secret society") - assert Nav.logout_link().text(session) == "Log out samuel.delaney@example.com" + Nav.assert_logged_in_as(session, "samuel.delaney@example.com") assert Details.active?(session) end @@ -73,23 +71,22 @@ defmodule Registrations.Integration.ClandestineRendezvous.Registrations do Login.fill_password(session, "Parable of the Talents") Login.submit(session) - assert Nav.error_text( - session, - "The provided login details did not work. Please verify your credentials, and try again." - ) == - "The provided login details did not work. Please verify your credentials, and try again." + Nav.assert_error_text( + session, + "The provided login details did not work. Please verify your credentials, and try again." + ) Login.fill_password(session, "Xenogenesis") Login.submit(session) - assert Nav.info_text(session, "Logged in") == "Logged in" - assert Nav.logout_link().text(session) == "Log out octavia.butler@example.com" + Nav.assert_info_text(session, "Logged in") + Nav.assert_logged_in_as(session, "octavia.butler@example.com") assert Details.active?(session) Nav.logout_link().click(session) - assert Nav.info_text(session, "Logged out") == "Logged out" + Nav.assert_info_text(session, "Logged out") assert Nav.login_link().present?(session) assert Nav.register_link().present?(session) end @@ -108,33 +105,30 @@ defmodule Registrations.Integration.ClandestineRendezvous.Registrations do Account.fill_current_password(session, "Wrong") Account.submit(session) - assert Nav.error_text( - session, - "Oops, something went wrong! Please check the errors below:\nCurrent password is invalid" - ) == - "Oops, something went wrong! Please check the errors below:\nCurrent password is invalid" + Nav.assert_error_text( + session, + "Oops, something went wrong! Please check the errors below:\nCurrent password is invalid" + ) Account.fill_current_password(session, "Xenogenesis") Account.fill_new_password(session, "abcde") Account.fill_new_password_confirmation(session, "vwxyz") Account.submit(session) - assert Nav.error_text( - session, - "Oops, something went wrong! Please check the errors below:\nPassword should be at least 8 character(s)\nPassword confirmation does not match confirmation" - ) == - "Oops, something went wrong! Please check the errors below:\nPassword should be at least 8 character(s)\nPassword confirmation does not match confirmation" + Nav.assert_error_text( + session, + "Oops, something went wrong! Please check the errors below:\nPassword should be at least 8 character(s)\nPassword confirmation does not match confirmation" + ) Account.fill_current_password(session, "Xenogenesis") Account.fill_new_password(session, "Lilith’s Brood") Account.fill_new_password_confirmation(session, "Lilith’s Brood") Account.submit(session) - assert Nav.info_text(session, "Your account has been updated.") == - "Your account has been updated." + Nav.assert_info_text(session, "Your account has been updated.") Nav.logout_link().click(session) - assert Nav.info_text(session, "Logged out") == "Logged out" + Nav.assert_info_text(session, "Logged out") visit(session, "/") Nav.login_link().click(session) @@ -143,16 +137,15 @@ defmodule Registrations.Integration.ClandestineRendezvous.Registrations do Login.fill_password(session, "Xenogenesis") Login.submit(session) - assert Nav.error_text( - session, - "The provided login details did not work. Please verify your credentials, and try again." - ) == - "The provided login details did not work. Please verify your credentials, and try again." + Nav.assert_error_text( + session, + "The provided login details did not work. Please verify your credentials, and try again." + ) Login.fill_password(session, "Lilith’s Brood") Login.submit(session) - assert Nav.info_text(session, "Logged in") == "Logged in" + Nav.assert_info_text(session, "Logged in") end test "forgot password", %{session: session} do @@ -168,11 +161,10 @@ defmodule Registrations.Integration.ClandestineRendezvous.Registrations do ForgotPassword.fill_email(session, "octavia.butler@example.com") ForgotPassword.submit(session) - assert Nav.info_text( - session, - "If an account for the provided email exists, an email with reset instructions will be sent to you. Please check your inbox." - ) == - "If an account for the provided email exists, an email with reset instructions will be sent to you. Please check your inbox." + Nav.assert_info_text( + session, + "If an account for the provided email exists, an email with reset instructions will be sent to you. Please check your inbox." + ) wait_for_emails([forgot_password_email]) @@ -190,8 +182,7 @@ defmodule Registrations.Integration.ClandestineRendezvous.Registrations do assert String.starts_with?(reset_path, "/reset-password/") visit(session, "/reset-password/fake") - assert Nav.error_text(session, "The reset token has expired.") == - "The reset token has expired." + Nav.assert_error_text(session, "The reset token has expired.") visit(session, reset_path) @@ -199,35 +190,32 @@ defmodule Registrations.Integration.ClandestineRendezvous.Registrations do Account.fill_new_password_confirmation(session, "awrongpassword") Account.submit(session) - assert Nav.error_text( - session, - "Oops, something went wrong! Please check the errors below:\nPassword confirmation does not match confirmation" - ) == - "Oops, something went wrong! Please check the errors below:\nPassword confirmation does not match confirmation" + Nav.assert_error_text( + session, + "Oops, something went wrong! Please check the errors below:\nPassword confirmation does not match confirmation" + ) Account.fill_new_password(session, "anewpassword") Account.fill_new_password_confirmation(session, "anewpassword") Account.submit(session) - assert Nav.info_text(session, "The password has been updated.") == - "The password has been updated." + Nav.assert_info_text(session, "The password has been updated.") Login.fill_email(session, "Octavia.butler@example.com") Login.fill_password(session, "anewpassword") Login.submit(session) - assert Nav.logout_link().text(session) == "Log out octavia.butler@example.com" + Nav.assert_logged_in_as(session, "octavia.butler@example.com") Nav.logout_link().click(session) Login.login_as(session, "octavia.butler@example.com", "anewpassword") - assert Nav.logout_link().text(session) == "Log out octavia.butler@example.com" + Nav.assert_logged_in_as(session, "octavia.butler@example.com") Nav.logout_link().click(session) visit(session, reset_path) - assert Nav.error_text(session, "The reset token has expired.") == - "The reset token has expired." + Nav.assert_error_text(session, "The reset token has expired.") end test "delete account", %{session: session} do @@ -239,8 +227,7 @@ defmodule Registrations.Integration.ClandestineRendezvous.Registrations do Nav.edit_details(session) Details.delete_account(session) - assert Nav.info_text(session, "Your account has been deleted. Sorry to see you go!") == - "Your account has been deleted. Sorry to see you go!" + Nav.assert_info_text(session, "Your account has been deleted. Sorry to see you go!") wait_for_emails([admin_email]) @@ -257,8 +244,7 @@ defmodule Registrations.Integration.ClandestineRendezvous.Registrations do Login.fill_password(session, "Xenogenesis") Login.submit(session) - assert Nav.info_text(session, "Your account has been deleted. Sorry to see you go!") == - "Your account has been deleted. Sorry to see you go!" + Nav.assert_info_text(session, "Your account has been deleted. Sorry to see you go!") end test "when registration is closed, a warning is displayed on the registration and details routes", @@ -273,20 +259,18 @@ defmodule Registrations.Integration.ClandestineRendezvous.Registrations do Nav.register_link().click(session) - assert Nav.error_text( - session, - "Registration is closed; however, you may continue and we will email you" - ) == - "Registration is closed; however, you may continue and we will email you" + Nav.assert_error_text( + session, + "Registration is closed; however, you may continue and we will email you" + ) insert(:octavia) Login.login_as_admin(session) - assert Nav.error_text( - session, - "You may change your details but it’s too late to guarantee the changes can be integrated" - ) == - "You may change your details but it’s too late to guarantee the changes can be integrated" + Nav.assert_error_text( + session, + "You may change your details but it’s too late to guarantee the changes can be integrated" + ) end end diff --git a/registrations/test/integration/teams_test.exs b/registrations/test/integration/teams_test.exs index ba1f90bb..42c97047 100644 --- a/registrations/test/integration/teams_test.exs +++ b/registrations/test/integration/teams_test.exs @@ -65,7 +65,7 @@ defmodule Registrations.Integration.Teams do Details.submit(session) - assert Nav.info_text(session, "Your details were saved") == "Your details were saved" + Nav.assert_info_text(session, "Your details were saved") assert Details.accessibility_text(session) == "Some accessibility information" assert Details.comments().value(session) == "Some comments" @@ -229,8 +229,7 @@ defmodule Registrations.Integration.Teams do } do visit(session, "/details") - assert Nav.info_text(session, "Please log in to edit your details") == - "Please log in to edit your details" + Nav.assert_info_text(session, "Please log in to edit your details") Login.fill_email(session, "anemail") end diff --git a/registrations/test/support/pages/nav.ex b/registrations/test/support/pages/nav.ex index d3fcb572..5b6fcefa 100644 --- a/registrations/test/support/pages/nav.ex +++ b/registrations/test/support/pages/nav.ex @@ -16,6 +16,25 @@ defmodule Registrations.Pages.Nav do flash_text(session, ".alert-danger", expected) end + def assert_info_text(session, expected) do + assert_flash_text(session, ".alert-info", expected) + end + + def assert_error_text(session, expected) do + assert_flash_text(session, ".alert-danger", expected) + end + + def assert_logged_in_as(session, email) do + expected = "log out #{email}" + + WaitForIt.wait( + case safe_text(session, "a.logout") do + {:ok, text} -> normalize_text(text) == normalize_text(expected) + :error -> false + end + ) + end + def register_link do Registrations.Pages.Nav.RegisterLink end @@ -159,7 +178,7 @@ defmodule Registrations.Pages.Nav do defp flash_text_matches?(session, selector, expected) do case safe_text(session, selector) do - {:ok, text} -> text == expected + {:ok, text} -> normalize_text(text) == normalize_text(expected) :error -> false end end @@ -172,4 +191,22 @@ defmodule Registrations.Pages.Nav do Wallaby.QueryError -> :error end end + + defp assert_flash_text(session, selector, expected) do + WaitForIt.wait(flash_text_matches?(session, selector, expected)) + + {:ok, text} = safe_text(session, selector) + if normalize_text(text) != normalize_text(expected) do + raise "Expected #{inspect(expected)}, got #{inspect(text)}" + end + + text + end + + defp normalize_text(text) do + text + |> String.downcase() + |> String.replace(~r/\s+/, " ") + |> String.trim() + end end From dd915c8fb3934a88f7994985468bd8f3b1290533 Mon Sep 17 00:00:00 2001 From: Buck Doyle Date: Sat, 17 Jan 2026 12:21:21 -0600 Subject: [PATCH 5/8] Add more test fixes --- registrations/test/integration/admin_test.exs | 1 + registrations/test/integration/teams_test.exs | 12 +++--- registrations/test/support/pages/details.ex | 31 +++++++++----- registrations/test/support/pages/home.ex | 41 ++++++++++--------- registrations/test/support/pages/nav.ex | 8 ++-- 5 files changed, 53 insertions(+), 40 deletions(-) diff --git a/registrations/test/integration/admin_test.exs b/registrations/test/integration/admin_test.exs index 82491d0f..e30f2dbc 100644 --- a/registrations/test/integration/admin_test.exs +++ b/registrations/test/integration/admin_test.exs @@ -265,6 +265,7 @@ defmodule Registrations.Integration.UnmnemonicDevices.Admin do visit(session, "/") Login.login_as_admin(session) + Nav.assert_logged_in_as(session, "octavia.butler@example.com") visit(session, "/api/teams") json = decode_json_from_page(session) diff --git a/registrations/test/integration/teams_test.exs b/registrations/test/integration/teams_test.exs index 42c97047..b328f292 100644 --- a/registrations/test/integration/teams_test.exs +++ b/registrations/test/integration/teams_test.exs @@ -81,7 +81,7 @@ defmodule Registrations.Integration.Teams do assert sent_email.text_body == ~s([accessibility: "Some accessibility information", comments: "Some comments", proposed_team_name: "Simultaneity", risk_aversion: 3, source: "A source", team_emails: "shevek@example.com bedap@example.com sabul@example.com laia@example.com nooo"]) - [bedap, shevek] = Enum.sort_by(Details.mutuals(session), & &1.email) + [bedap, shevek] = Enum.sort_by(Details.mutuals(session, count: 2), & &1.email) assert shevek.email == "shevek@example.com" assert shevek.symbol == "✓" @@ -99,14 +99,14 @@ defmodule Registrations.Integration.Teams do assert bedap.risk_aversion.value == "✓ Don’t hold back" assert bedap.risk_aversion.agreement? - [sadik] = Details.proposers(session) + [sadik] = Details.proposers(session, count: 1) assert sadik.email == "sadik@example.com" assert sadik.symbol == "?" assert sadik.text == "This person has you listed in their team. Add their address to your team emails list if you agree." - [rulag, tuio] = Enum.sort_by(Details.proposals_by_mutuals(session), & &1.email) + [rulag, tuio] = Enum.sort_by(Details.proposals_by_mutuals(session, count: 2), & &1.email) assert rulag.email == "rulag@example.com" assert rulag.symbol == "?" @@ -120,12 +120,12 @@ defmodule Registrations.Integration.Teams do assert tuio.text == "bedap@example.com and shevek@example.com have this address in their team emails lists. Add it if you agree." - [invalid] = Details.invalids(session) + [invalid] = Details.invalids(session, count: 1) assert invalid.email == "nooo" assert invalid.symbol == "✘" assert invalid.text == "This doesn’t seem like a valid email address!" - [laia, sabul] = Enum.sort_by(Details.proposees(session), & &1.email) + [laia, sabul] = Enum.sort_by(Details.proposees(session, count: 2), & &1.email) assert sabul.email == "sabul@example.com" assert sabul.symbol == "✘" @@ -146,7 +146,7 @@ defmodule Registrations.Integration.Teams do sadik.add.() Details.submit(session) - assert length(Details.mutuals(session)) == 3 + assert length(Details.mutuals(session, count: 3)) == 3 end test "team emails can be appended to", %{session: session} do diff --git a/registrations/test/support/pages/details.ex b/registrations/test/support/pages/details.ex index b4561f8a..25907709 100644 --- a/registrations/test/support/pages/details.ex +++ b/registrations/test/support/pages/details.ex @@ -3,6 +3,7 @@ defmodule Registrations.Pages.Details do alias Wallaby.Browser alias Wallaby.Element alias Wallaby.Query + require WaitForIt def edit_account(session) do Browser.click(session, Query.css("a.account")) @@ -14,15 +15,15 @@ defmodule Registrations.Pages.Details do end) end - def proposers(session) do + def proposers(session, opts \\ []) do session - |> Browser.all(Query.css("[data-test-proposers]")) + |> rows_with_wait("[data-test-proposers]", opts) |> Enum.map(&email_and_text_row(&1)) end - def mutuals(session) do + def mutuals(session, opts \\ []) do session - |> Browser.all(Query.css("[data-test-mutuals]")) + |> rows_with_wait("[data-test-mutuals]", opts) |> Enum.map(fn row -> proposed_team_name_element = Browser.find(row, Query.css(".proposed-team-name")) risk_aversion_element = Browser.find(row, Query.css(".risk-aversion")) @@ -44,21 +45,21 @@ defmodule Registrations.Pages.Details do end) end - def proposals_by_mutuals(session) do + def proposals_by_mutuals(session, opts \\ []) do session - |> Browser.all(Query.css("[data-test-proposals-by-mutuals]")) + |> rows_with_wait("[data-test-proposals-by-mutuals]", opts) |> Enum.map(&email_and_text_row(&1)) end - def invalids(session) do + def invalids(session, opts \\ []) do session - |> Browser.all(Query.css("[data-test-invalids]")) + |> rows_with_wait("[data-test-invalids]", opts) |> Enum.map(&email_and_text_row(&1)) end - def proposees(session) do + def proposees(session, opts \\ []) do session - |> Browser.all(Query.css("[data-test-proposees]")) + |> rows_with_wait("[data-test-proposees]", opts) |> Enum.map(&email_and_text_row(&1)) end @@ -216,6 +217,16 @@ defmodule Registrations.Pages.Details do Browser.click(session, Query.css("#submit")) end + defp rows_with_wait(session, selector, opts) do + expected = Keyword.get(opts, :count) + + if expected do + WaitForIt.wait!(length(Browser.all(session, Query.css(selector))) == expected) + end + + Browser.all(session, Query.css(selector)) + end + defp email_and_text_row(row) do %{ email: Element.text(Browser.find(row, Query.css(".email"))), diff --git a/registrations/test/support/pages/home.ex b/registrations/test/support/pages/home.ex index 882a4d0e..8696125b 100644 --- a/registrations/test/support/pages/home.ex +++ b/registrations/test/support/pages/home.ex @@ -43,30 +43,31 @@ defmodule Registrations.Pages.Home do Registrations.Pages.Home.Pi end - defmodule Pi do - @moduledoc false - alias Wallaby.Browser - alias Wallaby.Query - require WaitForIt + defmodule Pi do + @moduledoc false + alias Wallaby.Browser + alias Wallaby.Query + require WaitForIt - @selector "#pi" + @selector "#pi" - def present?(session) do - Browser.has?(session, Query.css(@selector)) - end + def present?(session) do + Browser.has?(session, Query.css(@selector)) + end - def click(session) do - WaitForIt.wait( - try do - Browser.click(session, Query.css(@selector)) - true - rescue - Wallaby.StaleReferenceError -> false - Wallaby.QueryError -> false - end - ) - end + def click(session) do + WaitForIt.wait!( + try do + Browser.click(session, Query.css(@selector)) + true + rescue + Wallaby.StaleReferenceError -> false + Wallaby.QueryError -> false + RuntimeError -> false + end + ) end + end def overlay do Registrations.Pages.Home.Overlay diff --git a/registrations/test/support/pages/nav.ex b/registrations/test/support/pages/nav.ex index 5b6fcefa..5d197e75 100644 --- a/registrations/test/support/pages/nav.ex +++ b/registrations/test/support/pages/nav.ex @@ -27,7 +27,7 @@ defmodule Registrations.Pages.Nav do def assert_logged_in_as(session, email) do expected = "log out #{email}" - WaitForIt.wait( + WaitForIt.wait!( case safe_text(session, "a.logout") do {:ok, text} -> normalize_text(text) == normalize_text(expected) :error -> false @@ -165,12 +165,12 @@ defmodule Registrations.Pages.Nav do end defp flash_text(session, selector, expected) when is_binary(expected) do - WaitForIt.wait(flash_text_matches?(session, selector, expected)) + WaitForIt.wait!(flash_text_matches?(session, selector, expected)) expected end defp flash_text(session, selector, nil) do - WaitForIt.wait(match?({:ok, _}, safe_text(session, selector))) + WaitForIt.wait!(match?({:ok, _}, safe_text(session, selector))) {:ok, text} = safe_text(session, selector) text @@ -193,7 +193,7 @@ defmodule Registrations.Pages.Nav do end defp assert_flash_text(session, selector, expected) do - WaitForIt.wait(flash_text_matches?(session, selector, expected)) + WaitForIt.wait!(flash_text_matches?(session, selector, expected)) {:ok, text} = safe_text(session, selector) if normalize_text(text) != normalize_text(expected) do From 4ca9c45ecd6f484036ae1da5af16c2bb7f82a20c Mon Sep 17 00:00:00 2001 From: Buck Doyle Date: Sat, 17 Jan 2026 12:39:47 -0600 Subject: [PATCH 6/8] Update flash timeout to be longer Is this really the problem? --- registrations/test/support/pages/nav.ex | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/registrations/test/support/pages/nav.ex b/registrations/test/support/pages/nav.ex index 5d197e75..d7290afd 100644 --- a/registrations/test/support/pages/nav.ex +++ b/registrations/test/support/pages/nav.ex @@ -4,6 +4,8 @@ defmodule Registrations.Pages.Nav do alias Wallaby.Query require WaitForIt + @flash_timeout 10_000 + def present?(session) do Browser.has?(session, Query.css(".row.nav")) end @@ -31,7 +33,8 @@ defmodule Registrations.Pages.Nav do case safe_text(session, "a.logout") do {:ok, text} -> normalize_text(text) == normalize_text(expected) :error -> false - end + end, + timeout: @flash_timeout ) end @@ -165,12 +168,12 @@ defmodule Registrations.Pages.Nav do end defp flash_text(session, selector, expected) when is_binary(expected) do - WaitForIt.wait!(flash_text_matches?(session, selector, expected)) + WaitForIt.wait!(flash_text_matches?(session, selector, expected), timeout: @flash_timeout) expected end defp flash_text(session, selector, nil) do - WaitForIt.wait!(match?({:ok, _}, safe_text(session, selector))) + WaitForIt.wait!(match?({:ok, _}, safe_text(session, selector)), timeout: @flash_timeout) {:ok, text} = safe_text(session, selector) text @@ -193,7 +196,7 @@ defmodule Registrations.Pages.Nav do end defp assert_flash_text(session, selector, expected) do - WaitForIt.wait!(flash_text_matches?(session, selector, expected)) + WaitForIt.wait!(flash_text_matches?(session, selector, expected), timeout: @flash_timeout) {:ok, text} = safe_text(session, selector) if normalize_text(text) != normalize_text(expected) do From d65b4e5eed3541dc51acfc06dc064727615da62f Mon Sep 17 00:00:00 2001 From: Buck Doyle Date: Sat, 17 Jan 2026 13:17:35 -0600 Subject: [PATCH 7/8] Add potential test fixes meh --- registrations/test/integration/teams_test.exs | 18 +++++++---- registrations/test/support/json_helpers.ex | 32 ++++++++++++++----- registrations/test/support/pages/details.ex | 20 ++++++++++++ registrations/test/support/pages/nav.ex | 8 ++++- 4 files changed, 63 insertions(+), 15 deletions(-) diff --git a/registrations/test/integration/teams_test.exs b/registrations/test/integration/teams_test.exs index b328f292..c07e3d08 100644 --- a/registrations/test/integration/teams_test.exs +++ b/registrations/test/integration/teams_test.exs @@ -208,20 +208,26 @@ defmodule Registrations.Integration.Teams do Details.submit(session) - assert Error.present?(session), - "Expected an error about the attending field being blank" + Error.assert_present( + session, + "Expected an error about the attending field being blank" + ) Details.Attending.yes(session) Details.submit(session) - refute Error.present?(session), - "Expected no error when the person said they were attending" + Error.assert_absent( + session, + "Expected no error when the person said they were attending" + ) Details.Attending.no(session) Details.submit(session) - refute Error.present?(session), - "Expected no error when the person said they were not attending" + Error.assert_absent( + session, + "Expected no error when the person said they were not attending" + ) end test "visiting the details page redirects to login when there is no session", %{ diff --git a/registrations/test/support/json_helpers.ex b/registrations/test/support/json_helpers.ex index 3391d6b6..b8fc74b2 100644 --- a/registrations/test/support/json_helpers.ex +++ b/registrations/test/support/json_helpers.ex @@ -2,18 +2,34 @@ defmodule Registrations.TestJsonHelpers do @moduledoc false import Wallaby.Browser, only: [page_source: 1] + require WaitForIt def decode_json_from_page(session) do - body = page_source(session) + WaitForIt.wait!(json_ready?(session), timeout: 10_000) - json = - case Floki.find(body, "pre") do - [] -> body - nodes -> Floki.text(nodes) - end - - json + session + |> page_source() + |> extract_json() |> String.trim() |> Jason.decode!() end + + defp json_ready?(session) do + session + |> page_source() + |> extract_json() + |> String.trim() + |> json_prefix?() + end + + defp json_prefix?(json) do + String.starts_with?(json, "{") or String.starts_with?(json, "[") + end + + defp extract_json(body) do + case Floki.find(body, "pre") do + [] -> body + nodes -> Floki.text(nodes) + end + end end diff --git a/registrations/test/support/pages/details.ex b/registrations/test/support/pages/details.ex index 25907709..be24edf3 100644 --- a/registrations/test/support/pages/details.ex +++ b/registrations/test/support/pages/details.ex @@ -163,6 +163,7 @@ defmodule Registrations.Pages.Details do @moduledoc false alias Wallaby.Browser alias Wallaby.Query + require WaitForIt def present?(session) do Browser.has?(session, Query.css(".form-group.attending")) @@ -170,20 +171,39 @@ defmodule Registrations.Pages.Details do def yes(session) do Browser.click(session, Query.css("input.attending-true")) + WaitForIt.wait!(Browser.has?(session, Query.css("input.attending-true:checked"))) end def no(session) do Browser.click(session, Query.css("input.attending-false")) + WaitForIt.wait!(Browser.has?(session, Query.css("input.attending-false:checked"))) end defmodule Error do @moduledoc false alias Wallaby.Browser alias Wallaby.Query + require WaitForIt def present?(session) do Browser.has?(session, Query.css(".errors .attending")) end + + def assert_present(session, message \\ nil) do + WaitForIt.wait!(present?(session)) + + if not present?(session) do + raise(message || "Expected attending error to be present") + end + end + + def assert_absent(session, message \\ nil) do + WaitForIt.wait!(!present?(session)) + + if present?(session) do + raise(message || "Expected attending error to be absent") + end + end end end diff --git a/registrations/test/support/pages/nav.ex b/registrations/test/support/pages/nav.ex index d7290afd..7f447744 100644 --- a/registrations/test/support/pages/nav.ex +++ b/registrations/test/support/pages/nav.ex @@ -79,6 +79,7 @@ defmodule Registrations.Pages.Nav do require WaitForIt @selector "a.logout" + @logout_timeout 10_000 def text(session) do WaitForIt.wait(Browser.has?(session, Query.css(@selector))) @@ -86,8 +87,13 @@ defmodule Registrations.Pages.Nav do end def click(session) do - WaitForIt.wait(Browser.has?(session, Query.css(@selector))) + WaitForIt.wait!(Browser.has?(session, Query.css(@selector)), timeout: @logout_timeout) Browser.click(session, Query.css(@selector)) + WaitForIt.wait!( + not Browser.has?(session, Query.css(@selector)) or + Browser.has?(session, Query.css("a.login")), + timeout: @logout_timeout + ) end end From 5c2ad7aa62b7e268d17e9e145ee9e1ee38bc5d0d Mon Sep 17 00:00:00 2001 From: Buck Doyle Date: Sat, 17 Jan 2026 13:33:29 -0600 Subject: [PATCH 8/8] Add empty commit