- Implemented `OrganizationMembersContent`, `OrganizationMembersTable`, and `AddMemberDialog` components for organization members management. - Added unit tests for `OrganizationMembersContent` and `OrganizationMembersTable`, covering rendering, state handling, and edge cases. - Enhanced `useOrganizationMembers` and `useGetOrganization` hooks to support members list and pagination data integration. - Updated E2E tests to include organization members page interactions and improved reliability.
120 lines
4.3 KiB
TypeScript
120 lines
4.3 KiB
TypeScript
/**
|
|
* E2E Tests for Admin Organization Members Management
|
|
* Tests basic navigation to organization members page
|
|
*
|
|
* Note: Interactive member management tests are covered by comprehensive unit tests (43 tests).
|
|
* E2E tests focus on navigation and page structure due to backend API mock limitations.
|
|
*/
|
|
|
|
import { test, expect } from '@playwright/test';
|
|
import { setupSuperuserMocks, loginViaUI } from './helpers/auth';
|
|
|
|
test.describe('Admin Organization Members - Navigation from Organizations List', () => {
|
|
test.beforeEach(async ({ page }) => {
|
|
await setupSuperuserMocks(page);
|
|
await loginViaUI(page);
|
|
await page.goto('/admin/organizations');
|
|
await page.waitForSelector('table tbody tr', { timeout: 10000 });
|
|
});
|
|
|
|
test('should navigate to members page when clicking view members in action menu', async ({ page }) => {
|
|
// Click first organization's action menu
|
|
const actionButton = page.getByRole('button', { name: /Actions for/i }).first();
|
|
await actionButton.click();
|
|
|
|
// Click "View Members"
|
|
await Promise.all([
|
|
page.waitForURL(/\/admin\/organizations\/[^/]+\/members/, { timeout: 10000 }),
|
|
page.getByText('View Members').click()
|
|
]);
|
|
|
|
// Should be on members page
|
|
await expect(page).toHaveURL(/\/admin\/organizations\/[^/]+\/members/);
|
|
});
|
|
|
|
test('should navigate to members page when clicking member count', async ({ page }) => {
|
|
// Find first organization row with members
|
|
const firstRow = page.locator('table tbody tr').first();
|
|
const memberButton = firstRow.locator('button').filter({ hasText: /^\d+$/ });
|
|
|
|
// Click on member count
|
|
await Promise.all([
|
|
page.waitForURL(/\/admin\/organizations\/[^/]+\/members/, { timeout: 10000 }),
|
|
memberButton.click()
|
|
]);
|
|
|
|
// Should be on members page
|
|
await expect(page).toHaveURL(/\/admin\/organizations\/[^/]+\/members/);
|
|
});
|
|
});
|
|
|
|
test.describe('Admin Organization Members - Page Structure', () => {
|
|
test.beforeEach(async ({ page }) => {
|
|
await setupSuperuserMocks(page);
|
|
await loginViaUI(page);
|
|
await page.goto('/admin/organizations');
|
|
await page.waitForSelector('table tbody tr', { timeout: 10000 });
|
|
|
|
// Navigate to members page
|
|
const actionButton = page.getByRole('button', { name: /Actions for/i }).first();
|
|
await actionButton.click();
|
|
|
|
await Promise.all([
|
|
page.waitForURL(/\/admin\/organizations\/[^/]+\/members/, { timeout: 10000 }),
|
|
page.getByText('View Members').click()
|
|
]);
|
|
});
|
|
|
|
test('should display organization members page', async ({ page }) => {
|
|
await expect(page).toHaveURL(/\/admin\/organizations\/[^/]+\/members/);
|
|
|
|
// Wait for page to load
|
|
await page.waitForSelector('table', { timeout: 10000 });
|
|
|
|
// Should show organization name in heading
|
|
await expect(page.getByRole('heading', { name: /Members/i })).toBeVisible();
|
|
});
|
|
|
|
test('should display page description', async ({ page }) => {
|
|
await expect(page.getByText('Manage members and their roles within the organization')).toBeVisible();
|
|
});
|
|
|
|
test('should display add member button', async ({ page }) => {
|
|
const addButton = page.getByRole('button', { name: /Add Member/i });
|
|
await expect(addButton).toBeVisible();
|
|
});
|
|
|
|
test('should display back to organizations button', async ({ page }) => {
|
|
const backButton = page.getByRole('link', { name: /Back to Organizations/i });
|
|
await expect(backButton).toBeVisible();
|
|
});
|
|
|
|
|
|
test('should have proper heading hierarchy', async ({ page }) => {
|
|
// Wait for page to load
|
|
await page.waitForSelector('table', { timeout: 10000 });
|
|
|
|
// Page should have h2 with organization name
|
|
const heading = page.getByRole('heading', { name: /Members/i });
|
|
await expect(heading).toBeVisible();
|
|
});
|
|
|
|
test('should have proper table structure', async ({ page }) => {
|
|
await page.waitForSelector('table', { timeout: 10000 });
|
|
|
|
// Table should have thead and tbody
|
|
const table = page.locator('table');
|
|
await expect(table.locator('thead')).toBeVisible();
|
|
await expect(table.locator('tbody')).toBeVisible();
|
|
});
|
|
|
|
test('should have accessible back button', async ({ page }) => {
|
|
const backButton = page.getByRole('link', { name: /Back to Organizations/i });
|
|
await expect(backButton).toBeVisible();
|
|
|
|
// Should have an icon
|
|
const icon = backButton.locator('svg');
|
|
await expect(icon).toBeVisible();
|
|
});
|
|
});
|