test: add tdd tests for group integration in member view #373
Some checks failed
continuous-integration/drone/push Build is failing
Some checks failed
continuous-integration/drone/push Build is failing
This commit is contained in:
parent
d7f6d1c03c
commit
f0750aed9d
7 changed files with 1600 additions and 0 deletions
189
test/mv_web/member_live/index_groups_accessibility_test.exs
Normal file
189
test/mv_web/member_live/index_groups_accessibility_test.exs
Normal 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
|
||||
Loading…
Add table
Add a link
Reference in a new issue