import { test, expect } from '@playwright/test'; test.describe('Scenario 11: Universal Modules Catalog & Profiles', () => { test.beforeEach(async ({ page }) => { await page.goto('/', { waitUntil: 'domcontentloaded' }); }); test('1. First open immediately displays all 18 modules with "Все модули" active by default', async ({ page }) => { const container = page.locator('[data-testid="modules-catalog-container"]'); await expect(container).toBeVisible({ timeout: 15000 }); await expect(page.locator('h1')).toContainText('Единый каталог модулей Krona'); const allProfileBtn = page.locator('[data-testid="profile-filter-all"]'); await expect(allProfileBtn).toBeVisible(); await expect(allProfileBtn).toContainText('Все модули (18)'); const cards = page.locator('[data-testid^="module-card-"]'); await expect(cards).toHaveCount(18); await expect(page.locator('[data-testid="module-card-crm"]')).toBeVisible(); await expect(page.locator('[data-testid="module-card-procurement"]')).toBeVisible(); await expect(page.locator('[data-testid="module-card-operations"]')).toBeVisible(); await expect(page.locator('[data-testid="module-card-finance"]')).toBeVisible(); }); test('2. Industry profile highlights recommended modules without hiding the rest', async ({ page }) => { const restaurantBtn = page.locator('[data-testid="profile-filter-restaurant_hall_delivery"]'); await expect(restaurantBtn).toBeVisible(); await restaurantBtn.click(); const recommendedSection = page.locator('[data-testid="recommended-section"]'); const otherSection = page.locator('[data-testid="other-modules-section"]'); await expect(recommendedSection).toBeVisible(); await expect(otherSection).toBeVisible(); // Recommended section must contain restaurant modules (e.g. operations) await expect(recommendedSection.locator('[data-testid="module-card-operations"]')).toBeVisible(); // Other section must contain non-restaurant recommended modules (e.g. helpdesk, not hidden!) await expect(otherSection.locator('[data-testid="module-card-helpdesk"]')).toBeVisible(); // Total count of modules across both sections must still be 18 const totalCards = page.locator('[data-testid^="module-card-"]'); await expect(totalCards).toHaveCount(18); // Reset button returns to "Все модули" const resetBtn = page.locator('[data-testid="reset-profile-filter-btn"]'); await expect(resetBtn).toBeVisible(); await resetBtn.click(); await expect(page.locator('[data-testid="all-modules-grid"]')).toBeVisible(); }); test('3. Search and category filters work properly', async ({ page }) => { const goodsCategoryBtn = page.locator('[data-testid="category-filter-inventory"]'); await expect(goodsCategoryBtn).toBeVisible(); await goodsCategoryBtn.click(); const filteredCards = page.locator('[data-testid^="module-card-"]'); await expect(filteredCards).toHaveCount(2); await expect(page.locator('[data-testid="module-card-inventory"]')).toBeVisible(); await expect(page.locator('[data-testid="module-card-procurement"]')).toBeVisible(); const searchInput = page.locator('[data-testid="catalog-search-input"]'); await searchInput.fill('закупки'); await expect(filteredCards).toHaveCount(1); await expect(page.locator('[data-testid="module-card-procurement"]')).toBeVisible(); const resetAllBtn = page.locator('[data-testid="reset-all-filters-btn"]'); await expect(resetAllBtn).toBeVisible(); await resetAllBtn.click(); await expect(page.locator('[data-testid^="module-card-"]')).toHaveCount(18); }); test('4. Module cards navigate directly to module route', async ({ page }) => { const crmOpenBtn = page.locator('[data-testid="module-open-btn-crm"]'); await expect(crmOpenBtn).toBeVisible(); await crmOpenBtn.click(); await page.waitForURL('**/crm'); await expect(page.locator('h1, h2').first()).toBeVisible(); await page.goto('/'); await page.waitForLoadState('domcontentloaded'); const procOpenBtn = page.locator('[data-testid="module-open-btn-procurement"]'); await expect(procOpenBtn).toBeVisible(); await procOpenBtn.click(); await page.waitForURL('**/procurement'); await expect(page.locator('h1')).toContainText('Закупки и управление поставщиками'); await expect(page.getByTestId('maturity-badge-planned')).toBeVisible(); }); test('5. "О модуле" opens informative details modal', async ({ page }) => { const detailsBtn = page.locator('[data-testid="module-details-btn-procurement"]'); await expect(detailsBtn).toBeVisible(); await detailsBtn.click(); const modal = page.locator('[data-testid="module-info-modal"]'); await expect(modal).toBeVisible(); await expect(modal).toContainText('Закупки и поставщики'); await expect(modal).toContainText('Назначение модуля'); await expect(modal).toContainText('Ключевые функциональные возможности'); await expect(modal).toContainText('Статус реализации'); await expect(modal).toContainText('Запланированные интеграции'); const closeBtn = page.locator('[data-testid="close-module-info-modal"]'); await closeBtn.click(); await expect(modal).not.toBeVisible(); }); test('6. Database reset in Settings restores "Все модули" filter mode', async ({ page }) => { const retailBtn = page.locator('[data-testid="profile-filter-retail"]'); await expect(retailBtn).toBeVisible(); await retailBtn.click(); await expect(page.locator('[data-testid="recommended-section"]')).toBeVisible(); await page.goto('/settings/entities'); await page.waitForLoadState('domcontentloaded'); const resetBtn = page.getByRole('button', { name: /Сбросить базу данных/i }); await expect(resetBtn).toBeVisible({ timeout: 10000 }); await resetBtn.click(); const confirmBtn = page.getByRole('button', { name: /Да, сбросить/i }); if (await confirmBtn.isVisible()) { await confirmBtn.click(); } await page.waitForTimeout(1000); await page.goto('/'); await page.waitForLoadState('domcontentloaded'); const allProfileBtn = page.locator('[data-testid="profile-filter-all"]'); await expect(allProfileBtn).toBeVisible(); await expect(page.locator('[data-testid="all-modules-grid"]')).toBeVisible(); await expect(page.locator('[data-testid^="module-card-"]')).toHaveCount(18); }); test('7. Catalog renders with zero horizontal overflow across viewport', async ({ page }) => { const isOverflowing = await page.evaluate(() => { return document.documentElement.scrollWidth > document.documentElement.clientWidth; }); expect(isOverflowing).toBe(false); const kpiTab = page.locator('[data-testid="view-tab-dashboard"]'); await expect(kpiTab).toBeVisible(); await kpiTab.click(); await expect(page.locator('text=Выручка').first()).toBeVisible({ timeout: 10000 }); const catalogTab = page.locator('[data-testid="view-tab-catalog"]'); await catalogTab.click(); await expect(page.locator('[data-testid="modules-catalog-container"]')).toBeVisible(); }); });