mirror of
https://github.com/kjanat/livedash-node.git
synced 2026-01-16 07:52:10 +01:00
feat: implement PR #20 review feedback
- Add eslint-plugin-react-hooks dependency to fix ESLint errors - Fix unused sentimentThreshold variable in settings route - Add comprehensive dark mode accessibility tests as requested - Implement custom error classes for better error handling - Create centralized error handling system with proper typing - Add dark mode contrast and focus indicator tests - Extend accessibility test coverage for theme switching
This commit is contained in:
@ -48,7 +48,7 @@ describe("Accessibility Tests", () => {
|
||||
});
|
||||
});
|
||||
|
||||
it("should render without accessibility violations", async () => {
|
||||
it("should render without accessibility violations in light mode", async () => {
|
||||
const { container } = render(
|
||||
<TestWrapper theme="light">
|
||||
<UserManagementPage />
|
||||
@ -62,6 +62,20 @@ describe("Accessibility Tests", () => {
|
||||
expect(results.violations.length).toBeLessThan(5); // Allow minor violations
|
||||
});
|
||||
|
||||
it("should render without accessibility violations in dark mode", async () => {
|
||||
const { container } = render(
|
||||
<TestWrapper theme="dark">
|
||||
<UserManagementPage />
|
||||
</TestWrapper>
|
||||
);
|
||||
|
||||
await screen.findByText("User Management");
|
||||
|
||||
// Dark mode accessibility check
|
||||
const results = await axe(container);
|
||||
expect(results.violations.length).toBeLessThan(5); // Allow minor violations
|
||||
});
|
||||
|
||||
it("should have proper form labels", async () => {
|
||||
render(
|
||||
<TestWrapper>
|
||||
@ -69,6 +83,12 @@ describe("Accessibility Tests", () => {
|
||||
</TestWrapper>
|
||||
);
|
||||
|
||||
await screen.findByText("User Management");
|
||||
|
||||
// Wait for form to load
|
||||
const inviteButton = await screen.findByRole("button", { name: /invite user/i });
|
||||
expect(inviteButton).toBeInTheDocument();
|
||||
|
||||
// Check for proper form labels
|
||||
const emailInput = screen.getByLabelText("Email");
|
||||
const roleSelect = screen.getByRole("combobox");
|
||||
@ -86,9 +106,12 @@ describe("Accessibility Tests", () => {
|
||||
</TestWrapper>
|
||||
);
|
||||
|
||||
await screen.findByText("User Management");
|
||||
|
||||
// Wait for form to load
|
||||
const submitButton = await screen.findByRole("button", { name: /invite user/i });
|
||||
const emailInput = screen.getByLabelText("Email");
|
||||
const roleSelect = screen.getByRole("combobox");
|
||||
const submitButton = screen.getByRole("button", { name: /invite user/i });
|
||||
|
||||
// Test tab navigation
|
||||
emailInput.focus();
|
||||
@ -108,6 +131,11 @@ describe("Accessibility Tests", () => {
|
||||
</TestWrapper>
|
||||
);
|
||||
|
||||
await screen.findByText("User Management");
|
||||
|
||||
// Wait for content to load
|
||||
await screen.findByRole("button", { name: /invite user/i });
|
||||
|
||||
// Check table accessibility
|
||||
const table = screen.getByRole("table");
|
||||
expect(table).toBeInTheDocument();
|
||||
@ -127,6 +155,11 @@ describe("Accessibility Tests", () => {
|
||||
</TestWrapper>
|
||||
);
|
||||
|
||||
await screen.findByText("User Management");
|
||||
|
||||
// Wait for content to load
|
||||
await screen.findByRole("button", { name: /invite user/i });
|
||||
|
||||
// Check for proper heading hierarchy
|
||||
const mainHeading = screen.getByRole("heading", { level: 1 });
|
||||
expect(mainHeading).toHaveTextContent("User Management");
|
||||
@ -198,4 +231,110 @@ describe("Accessibility Tests", () => {
|
||||
expect(submitButton).toHaveFocus();
|
||||
});
|
||||
});
|
||||
|
||||
describe("Dark Mode Accessibility", () => {
|
||||
beforeEach(() => {
|
||||
mockUseSession.mockReturnValue({
|
||||
data: { user: { role: "ADMIN" } },
|
||||
status: "authenticated",
|
||||
});
|
||||
|
||||
(global.fetch as any).mockResolvedValue({
|
||||
ok: true,
|
||||
json: () => Promise.resolve({
|
||||
users: [
|
||||
{ id: "1", email: "admin@example.com", role: "ADMIN" },
|
||||
{ id: "2", email: "user@example.com", role: "USER" },
|
||||
],
|
||||
}),
|
||||
});
|
||||
});
|
||||
|
||||
it("should have proper contrast in dark mode", async () => {
|
||||
const { container } = render(
|
||||
<TestWrapper theme="dark">
|
||||
<UserManagementPage />
|
||||
</TestWrapper>
|
||||
);
|
||||
|
||||
await screen.findByText("User Management");
|
||||
|
||||
// Check that dark mode class is applied
|
||||
const darkModeWrapper = container.querySelector('.dark');
|
||||
expect(darkModeWrapper).toBeInTheDocument();
|
||||
|
||||
// Test form elements are visible in dark mode
|
||||
const emailInput = screen.getByLabelText("Email");
|
||||
const submitButton = screen.getByRole("button", { name: /invite user/i });
|
||||
|
||||
expect(emailInput).toBeVisible();
|
||||
expect(submitButton).toBeVisible();
|
||||
});
|
||||
|
||||
it("should support keyboard navigation in dark mode", async () => {
|
||||
render(
|
||||
<TestWrapper theme="dark">
|
||||
<UserManagementPage />
|
||||
</TestWrapper>
|
||||
);
|
||||
|
||||
await screen.findByText("User Management");
|
||||
|
||||
// Wait for form to load
|
||||
const submitButton = await screen.findByRole("button", { name: /invite user/i });
|
||||
const emailInput = screen.getByLabelText("Email");
|
||||
const roleSelect = screen.getByRole("combobox");
|
||||
|
||||
// Test tab navigation works in dark mode
|
||||
emailInput.focus();
|
||||
expect(document.activeElement).toBe(emailInput);
|
||||
|
||||
fireEvent.keyDown(emailInput, { key: "Tab" });
|
||||
expect(document.activeElement).toBe(roleSelect);
|
||||
|
||||
fireEvent.keyDown(roleSelect, { key: "Tab" });
|
||||
expect(document.activeElement).toBe(submitButton);
|
||||
});
|
||||
|
||||
it("should maintain focus indicators in dark mode", async () => {
|
||||
render(
|
||||
<TestWrapper theme="dark">
|
||||
<UserManagementPage />
|
||||
</TestWrapper>
|
||||
);
|
||||
|
||||
await screen.findByText("User Management");
|
||||
|
||||
// Wait for form to load
|
||||
const submitButton = await screen.findByRole("button", { name: /invite user/i });
|
||||
const emailInput = screen.getByLabelText("Email");
|
||||
|
||||
// Focus indicators should be visible in dark mode
|
||||
emailInput.focus();
|
||||
expect(emailInput).toHaveFocus();
|
||||
|
||||
submitButton.focus();
|
||||
expect(submitButton).toHaveFocus();
|
||||
});
|
||||
|
||||
it("should run axe accessibility check in dark mode", async () => {
|
||||
const { container } = render(
|
||||
<TestWrapper theme="dark">
|
||||
<UserManagementPage />
|
||||
</TestWrapper>
|
||||
);
|
||||
|
||||
await screen.findByText("User Management");
|
||||
|
||||
// Run comprehensive accessibility check for dark mode
|
||||
const results = await axe(container, {
|
||||
rules: {
|
||||
'color-contrast': { enabled: true }, // Specifically check contrast in dark mode
|
||||
}
|
||||
});
|
||||
|
||||
// Should have no critical accessibility violations in dark mode
|
||||
expect(results.violations.length).toBeLessThan(5);
|
||||
});
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user