test: add tdd tests for group integration in member view #373
Some checks failed
continuous-integration/drone/push Build is failing

This commit is contained in:
Simon 2026-01-29 16:43:05 +01:00
parent d7f6d1c03c
commit f0750aed9d
Signed by: simon
GPG key ID: 40E7A58C4AA1EDB2
7 changed files with 1600 additions and 0 deletions

View file

@ -0,0 +1,189 @@
defmodule MvWeb.MemberLive.IndexGroupsAccessibilityTest do
@moduledoc """
Tests for accessibility of groups feature in the member overview.
Tests cover:
- Badges have role="status" and aria-label
- Filter dropdown has aria-label
- Sort header has aria-label for screen reader
- Keyboard navigation works (Tab through filter, sort header)
"""
# async: false to prevent PostgreSQL deadlocks when creating members and groups
use MvWeb.ConnCase, async: false
import Phoenix.LiveViewTest
require Ash.Query
alias Mv.Membership.{Group, MemberGroup}
setup do
system_actor = Mv.Helpers.SystemActor.get_system_actor()
# Create test members
{:ok, member1} =
Mv.Membership.create_member(
%{first_name: "Alice", last_name: "Anderson", email: "alice@example.com"},
actor: system_actor
)
# Create test groups
{:ok, group1} =
Group
|> Ash.Changeset.for_create(:create, %{name: "Board Members"})
|> Ash.create(actor: system_actor)
# Create member-group associations
{:ok, _mg1} =
MemberGroup
|> Ash.Changeset.for_create(:create, %{member_id: member1.id, group_id: group1.id})
|> Ash.create(actor: system_actor)
%{
member1: member1,
group1: group1
}
end
@tag :ui
test "group badges have role and aria-label", %{
conn: conn,
member1: member1,
group1: group1
} do
conn = conn_with_oidc_user(conn)
{:ok, view, html} = live(conn, "/members")
# Verify badges have accessibility attributes
# Badges should have role="status" and aria-label describing the group
assert html =~ ~r/role=["']status["']/ or html =~ ~r/aria-label=.*#{group1.name}/
assert html =~ group1.name
# Verify member1's row contains the badge
assert html =~ member1.first_name
end
@tag :ui
test "filter dropdown has aria-label", %{
conn: conn
} do
conn = conn_with_oidc_user(conn)
{:ok, view, html} = live(conn, "/members")
# Verify filter dropdown has aria-label
assert html =~ ~r/select.*name=["']group_filter["'].*aria-label=/ or
html =~ ~r/aria-label=.*[Gg]roup/
# Verify dropdown is present
assert has_element?(view, "select[name='group_filter']")
end
@tag :ui
test "sort header has aria-label for screen reader", %{
conn: conn
} do
conn = conn_with_oidc_user(conn)
{:ok, view, html} = live(conn, "/members")
# Verify sort header has aria-label
# Sort header should have aria-label describing the sort state
assert html =~ ~r/aria-label=.*[Gg]roup/ or
has_element?(view, "[data-testid='sort_groups'][aria-label]")
end
@tag :ui
test "keyboard navigation works for filter dropdown", %{
conn: conn,
group1: group1
} do
conn = conn_with_oidc_user(conn)
{:ok, view, _html} = live(conn, "/members")
# Verify dropdown is keyboard accessible
# Tab should focus the dropdown
# Arrow keys should navigate options
# Enter should select option
assert has_element?(view, "select[name='group_filter']")
# Test that dropdown can be focused and changed via keyboard
# (This is a basic accessibility check - actual keyboard testing would require browser automation)
view
|> element("select[name='group_filter']")
|> render_change(%{"group_filter" => group1.id})
# Verify change was applied
html = render(view)
assert html
end
@tag :ui
test "keyboard navigation works for sort header", %{
conn: conn
} do
conn = conn_with_oidc_user(conn)
{:ok, view, _html} = live(conn, "/members")
# Verify sort header is keyboard accessible
# Tab should focus the sort header
# Enter/Space should activate sorting
assert has_element?(view, "[data-testid='sort_groups']")
# Test that sort header can be activated via click (simulating keyboard)
view
|> element("[data-testid='sort_groups']")
|> render_click()
# Verify sort was applied
assert_patch(view, "/members?query=&sort_field=groups&sort_order=asc")
end
@tag :ui
test "screen reader announcements for filter changes", %{
conn: conn,
member1: member1,
group1: group1
} do
conn = conn_with_oidc_user(conn)
{:ok, view, _html} = live(conn, "/members")
# Apply filter
view
|> element("select[name='group_filter']")
|> render_change(%{"group_filter" => group1.id})
# Verify filter change is announced (via aria-live region or similar)
html = render(view)
# Should show filtered results
assert html =~ member1.first_name
# Verify member count or filter status is announced
# (Implementation might use aria-live="polite" for announcements)
assert html
end
@tag :ui
test "multiple badges are announced correctly", %{
conn: conn,
member1: member1
} do
system_actor = Mv.Helpers.SystemActor.get_system_actor()
# Create multiple groups for member1
{:ok, group2} =
Group
|> Ash.Changeset.for_create(:create, %{name: "Active Members"})
|> Ash.create(actor: system_actor)
{:ok, _mg} =
MemberGroup
|> Ash.Changeset.for_create(:create, %{member_id: member1.id, group_id: group2.id})
|> Ash.create(actor: system_actor)
conn = conn_with_oidc_user(conn)
{:ok, view, html} = live(conn, "/members")
# Verify multiple badges are present
assert html =~ member1.first_name
# Both groups should be visible
# Screen reader should be able to distinguish between multiple badges
assert html
end
end