krona-front/e2e/09-rbac.spec.ts

53 lines
2.6 KiB
TypeScript

import { test, expect } from '@playwright/test';
test.describe('Scenario 09: RBAC Guard & 403 Forbidden Handling', () => {
test('denies restricted role access to protected module and restores access upon switching back to Owner', async ({ page }) => {
await page.goto('/settings', { waitUntil: 'domcontentloaded' });
// 1. Switch to restricted role: Cashier via Settings, Topbar or Mobile Menu
const cashierRoleBtn = page.locator('[data-testid="settings-role-cashier"]');
const mobileMenuBtn = page.locator('[data-testid="mobile-menu-btn"]');
const roleSwitcher = page.locator('[data-testid="role-switcher-btn"]');
if (await cashierRoleBtn.isVisible({ timeout: 5000 }).catch(() => false)) {
await cashierRoleBtn.click();
} else if (await mobileMenuBtn.isVisible()) {
await mobileMenuBtn.click();
const roleOption = page.locator('[data-testid="mobile-menu-drawer"]').locator('[data-testid="role-option-cashier"]');
await expect(roleOption).toBeVisible({ timeout: 5000 });
await roleOption.click();
const closeBtn = page.locator('[data-testid="close-mobile-menu"]');
if (await closeBtn.isVisible()) {
await closeBtn.click();
}
} else {
await expect(roleSwitcher).toBeVisible({ timeout: 10000 });
await roleSwitcher.click();
const roleOption = page.locator('header').locator('[data-testid="role-option-cashier"]');
await expect(roleOption).toBeVisible({ timeout: 5000 });
await roleOption.click();
}
// 2. Navigate to protected route /finance (Cashier has no permission to Finance)
await page.goto('/finance');
await page.waitForLoadState('domcontentloaded');
// 3. Verify 403 Forbidden page is displayed
const forbiddenPage = page.locator('[data-testid="forbidden-page"]');
await expect(forbiddenPage).toBeVisible({ timeout: 15000 });
await expect(page.locator('text=403 Доступ ограничен').first()).toBeVisible();
// 4. Switch back to Owner using Forbidden Page quick recovery button
const switchToOwnerBtn = page.locator('[data-testid="switch-to-owner-btn"]');
await expect(switchToOwnerBtn).toBeVisible();
await switchToOwnerBtn.click();
// 5. Navigate back to /finance and verify access restored
await page.goto('/finance');
await page.waitForLoadState('domcontentloaded');
// Finance content should now be visible without 403
await expect(page.locator('[data-testid="forbidden-page"]')).not.toBeVisible();
await expect(page.locator('main').locator('text=Финансы').first()).toBeVisible({ timeout: 15000 });
});
});