Rejoin Game In Progress
When a user has at least one active game, they will see a Games in Progress section on their authenticated home page. This list only shows the join code string for each active game which isn’t too helpful unless the user knows how to plug in the code to the correct URL path. The next feature I’m building is to add clickable links which take the user to the associated game page.
I start by writing a feature test using Wallaby for how I expect this scenario to behave, not worrying that the setup functions do not yet exist.
defmodule MinotaurWeb.Home.UserJoinsActiveGameTest do
@moduledoc false
use Minotaur.FeatureCase
describe "user clicks join link in active games list" do
setup [:create_user, :start_games, :sign_in_user, :click_join_link]
test "redirects user to game view for chosen game", ctx do
assert current_path(ctx.session) == "/games/#{ctx.join_code}"
end
end
end
I then start the cycle of running the test, getting a compilation error, fixing the compilation error, and repeating until the test fully compiles.
defmodule MinotaurWeb.Home.UserJoinsActiveGameTest do
@moduledoc false
use Minotaur.FeatureCase
import Minotaur.GameEngineFixtures
alias Minotaur.GameEngine
describe "user clicks join button in active games list" do
setup [:create_user, :start_games, :sign_in_user, :click_join_button]
test "redirects user to game view for chosen game", ctx do
assert current_path(ctx.session) == "/games/#{ctx.game2_join_code}"
end
end
defp create_user(_ctx) do
[user: user_fixture()]
end
defp start_game(join_code, user) do
players = [
player_fixture(%{user_id: user.id}),
player_fixture(%{user_id: user_fixture().id})
]
game = game_fixture(players: players)
{:ok, _pid} = GameEngine.continue_game(join_code, game)
game
end
defp start_games(%{user: user}) do
game1_join_code = "AABB"
game2_join_code = "CCDD"
start_game(game1_join_code, user)
start_game(game2_join_code, user)
[game2_join_code: game2_join_code]
end
defp sign_in_user(%{session: session, user: user}) do
sign_in(session, as: user)
:ok
end
defp click_join_link(ctx) do
:ok
end
end
I next add logic for click_join_link
which will help me design the way links will be added to the page in a testable way.
defp click_join_button(%{session: session, game2_join_code: join_code}) do
session =
session
|> find(Query.css("#games-in-progress #game_#{join_code}"), fn element ->
click(element, Query.link("Join"))
end)
[session: session]
end
The test is still failing since the join link does not yet exist. I update the HEEx template for the home live page to match the elements expected by the feature test helper function. I won’t worry about styling until after the functionality is complete first.
<%= for game <- @games_in_progress do %>
<li id={"game_#{game.join_code}"}>
<%= game.join_code %>
<.link navigate={~p"/game/#{game.join_code}"}>Join</.link>
</li>
<% end %>
The test is now finding the join link, but the assertion on the URL path is failing.
After debugging with Wallaby’s take_screenshot
call after the click event, I see the test probably needs more time for the browser to load the view.
I update the test with a find
call to look for the round timer in the game view which will block until the queried element is found.
test "redirects user to game view for chosen game", ctx do
ctx.session
|> find(Query.css("#round-timer"), fn element ->
assert_text(element, "00:")
end)
assert current_path(ctx.session) == "/game/#{ctx.game2_join_code}"
end
With that change, the test is passing!