From 30722da89efd374d9c200cb17778d693ebaa7e6a Mon Sep 17 00:00:00 2001 From: ochenstarik Date: Fri, 11 Sep 2026 11:22:52 +0700 Subject: [PATCH] fix(e2e): restore theme toggles and role switcher locators across viewports --- e2e/02-theme.spec.ts | 31 +++++++++++--- e2e/09-rbac.spec.ts | 24 ++++++++--- src/app/shell/MobileMenuDrawer.tsx | 8 ++-- src/app/shell/Topbar.tsx | 67 +++++++++++++++++++++++++----- 4 files changed, 106 insertions(+), 24 deletions(-) diff --git a/e2e/02-theme.spec.ts b/e2e/02-theme.spec.ts index a80029d..43e379d 100644 --- a/e2e/02-theme.spec.ts +++ b/e2e/02-theme.spec.ts @@ -2,12 +2,31 @@ import { test, expect } from '@playwright/test'; test.describe('Scenario 02: Theme Engine & UI Persistence', () => { test('switches themes via real UI clicks and persists across page reloads', async ({ page }) => { - await page.goto('/'); - await page.waitForLoadState('domcontentloaded'); + await page.goto('/', { waitUntil: 'domcontentloaded' }); - const darkToggle = page.locator('[data-testid="theme-toggle-dark"]'); - const lightToggle = page.locator('[data-testid="theme-toggle-light"]'); - const softToggle = page.locator('[data-testid="theme-toggle-soft"]'); + const isMobile = await page.locator('[data-testid="mobile-menu-btn"]').isVisible(); + + const openThemeControls = async () => { + if (isMobile) { + const drawer = page.locator('[data-testid="mobile-menu-drawer"]'); + if (!(await drawer.isVisible())) { + await page.locator('[data-testid="mobile-menu-btn"]').click(); + await expect(drawer).toBeVisible(); + } + } + }; + + await openThemeControls(); + + const darkToggle = isMobile + ? page.locator('[data-testid="mobile-menu-drawer"]').locator('[data-testid="theme-toggle-dark"]') + : page.locator('[data-testid="theme-toggle-dark"]'); + const lightToggle = isMobile + ? page.locator('[data-testid="mobile-menu-drawer"]').locator('[data-testid="theme-toggle-light"]') + : page.locator('[data-testid="theme-toggle-light"]'); + const softToggle = isMobile + ? page.locator('[data-testid="mobile-menu-drawer"]').locator('[data-testid="theme-toggle-soft"]') + : page.locator('[data-testid="theme-toggle-soft"]'); await expect(darkToggle).toBeVisible({ timeout: 15000 }); await expect(lightToggle).toBeVisible(); @@ -22,6 +41,8 @@ test.describe('Scenario 02: Theme Engine & UI Persistence', () => { await page.waitForLoadState('domcontentloaded'); await expect(page.locator('html')).toHaveAttribute('data-theme', 'dark'); + await openThemeControls(); + // 3. Switch to Light Theme await lightToggle.click(); await expect(page.locator('html')).toHaveAttribute('data-theme', 'light'); diff --git a/e2e/09-rbac.spec.ts b/e2e/09-rbac.spec.ts index 69150d2..7a56e44 100644 --- a/e2e/09-rbac.spec.ts +++ b/e2e/09-rbac.spec.ts @@ -2,17 +2,29 @@ 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'); - await page.waitForLoadState('domcontentloaded'); + await page.goto('/settings', { waitUntil: 'domcontentloaded' }); - // 1. Switch to restricted role: Cashier via Settings or Topbar + // 1. Switch to restricted role: Cashier via Settings, Topbar or Mobile Menu const cashierRoleBtn = page.locator('[data-testid="settings-role-cashier"]'); - if (await cashierRoleBtn.isVisible()) { + 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 { - const roleSwitcher = page.locator('[data-testid="role-switcher-btn"]'); + await expect(roleSwitcher).toBeVisible({ timeout: 10000 }); await roleSwitcher.click(); - const roleOption = page.locator('[data-testid="role-option-cashier"]'); + const roleOption = page.locator('header').locator('[data-testid="role-option-cashier"]'); + await expect(roleOption).toBeVisible({ timeout: 5000 }); await roleOption.click(); } diff --git a/src/app/shell/MobileMenuDrawer.tsx b/src/app/shell/MobileMenuDrawer.tsx index 3162655..9bbb380 100644 --- a/src/app/shell/MobileMenuDrawer.tsx +++ b/src/app/shell/MobileMenuDrawer.tsx @@ -173,6 +173,7 @@ export const MobileMenuDrawer: React.FC = ({ isOpen, onCl return ( -
+
Переключение роли
@@ -229,7 +240,11 @@ export const Topbar: React.FC = () => { return ( - {/* Theme switcher */} -
+ {/* Theme switcher (3 buttons) */} +
+ +