mitgliederverwaltung/test/mv_web/member_live/index_groups_accessibility_test.exs
Simon 5fd7c0e7f6
Some checks failed
continuous-integration/drone/push Build is failing
feat: improve groups fillter
2026-02-13 17:45:51 +01:00

181 lines
4.9 KiB
Elixir

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 group presence section with legend", %{
conn: conn
} do
conn = conn_with_oidc_user(conn)
{:ok, view, _html} = live(conn, "/members")
# Open filter dropdown
view
|> element("button[aria-label='Filter members']")
|> render_click()
html = render(view)
# Groups section: legend "Member has groups" and radios (Any / Yes / No)
assert html =~ ~r/[Gg]roups/
assert has_element?(view, "[data-testid='member-filter-form']")
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='groups'][aria-label]")
end
@tag :ui
test "keyboard navigation works for filter dropdown", %{
conn: conn,
member1: member1,
group1: group1
} do
conn = conn_with_oidc_user(conn)
{:ok, view, _html} = live(conn, "/members")
view
|> element("button[aria-label='Filter members']")
|> render_click()
view
|> element("[data-testid='member-filter-form']")
|> render_change(%{"group_#{group1.id}" => "in", "payment_filter" => "all"})
html = render(view)
assert html =~ member1.first_name
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")
assert has_element?(view, "[data-testid='groups']")
view
|> element("[data-testid='groups']")
|> render_click()
# Verify sort was applied (URL may include other params)
assert has_element?(view, "[data-testid='groups'][aria-label*='ascending']")
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")
view
|> element("button[aria-label='Filter members']")
|> render_click()
view
|> element("[data-testid='member-filter-form']")
|> render_change(%{"group_#{group1.id}" => "in", "payment_filter" => "all"})
html = render(view)
assert html =~ member1.first_name
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