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', { waitUntil: 'domcontentloaded' }); 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', { waitUntil: 'domcontentloaded' }); 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 }); }); });