190 lines
8.5 KiB
TypeScript
190 lines
8.5 KiB
TypeScript
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();
|
||
});
|
||
|
||
test('8. Mobile filter drawer, density switcher, and quick access block function smoothly', async ({ page }) => {
|
||
// Quick access block
|
||
const quickAccess = page.locator('[data-testid="quick-access-block"]');
|
||
await expect(quickAccess).toBeVisible();
|
||
await expect(page.locator('[data-testid="quick-access-crm"]')).toBeVisible();
|
||
|
||
// Density toggle
|
||
const compactToggle = page.locator('[data-testid="density-toggle-compact"]');
|
||
const detailedToggle = page.locator('[data-testid="density-toggle-detailed"]');
|
||
await expect(compactToggle).toBeVisible();
|
||
await expect(detailedToggle).toBeVisible();
|
||
|
||
await compactToggle.click();
|
||
await expect(page.locator('text=Ключевые возможности:').first()).not.toBeVisible();
|
||
|
||
await detailedToggle.click();
|
||
await expect(page.locator('text=Ключевые возможности:').first()).toBeVisible();
|
||
|
||
// Filter drawer
|
||
const filterDrawerBtn = page.locator('[data-testid="mobile-filter-drawer-btn"]');
|
||
await expect(filterDrawerBtn).toBeVisible();
|
||
await filterDrawerBtn.click();
|
||
|
||
const applyDrawerBtn = page.locator('[data-testid="apply-filters-drawer-btn"]');
|
||
await expect(applyDrawerBtn).toBeVisible();
|
||
await applyDrawerBtn.click();
|
||
await expect(applyDrawerBtn).not.toBeVisible();
|
||
});
|
||
});
|