krona-front/e2e/07-configuration-engine.spec.ts

77 lines
3.7 KiB
TypeScript

import { test, expect } from '@playwright/test';
test.describe('Scenario 07: Configuration Engine (Entity Creation & Custom Records)', () => {
test('creates custom entity in Catalog, adds record at runtime, and verifies persistence', async ({ page }) => {
await page.goto('/settings/entities', { waitUntil: 'domcontentloaded' });
await page.waitForLoadState('domcontentloaded');
// 1. Open Create Entity Modal
const createEntityBtn = page.locator('[data-testid="create-entity-btn"]');
await expect(createEntityBtn).toBeVisible({ timeout: 15000 });
await createEntityBtn.click();
// Unique code for the entity
const suffix = `${Date.now().toString().slice(-6)}_${Math.floor(Math.random() * 10000)}`;
const entityName = `Оборудование ${suffix}`;
const modal = page.getByRole('dialog', { name: 'Создание новой сущности' });
await expect(modal).toBeVisible();
// Fill entity name (auto-populates API code)
await modal.locator('[data-testid="new-entity-name-input"]').fill(entityName);
// Read the system-generated API code
const codeInput = modal.locator('[data-testid="new-entity-code-input"]');
await expect(codeInput).not.toHaveValue('');
const entityCode = await codeInput.inputValue();
// Submit entity creation
const submitEntityBtn = modal.locator('[data-testid="submit-create-entity-btn"]');
await submitEntityBtn.scrollIntoViewIfNeeded();
await submitEntityBtn.click();
await expect(modal).not.toBeVisible({ timeout: 10000 });
// Wait for the new entity card to appear in the catalog
await expect(page.locator(`h3:has-text("${entityName}")`)).toBeVisible({ timeout: 10000 });
// 2. Navigate to the dynamic entity route via catalog button
const openEntityBtn = page.locator(`[data-testid="open-entity-${entityCode}-btn"]`);
await expect(openEntityBtn).toBeVisible({ timeout: 10000 });
await openEntityBtn.click();
// Wait for the entity page header to appear
await expect(page.locator('h1').filter({ hasText: entityName })).toBeVisible({ timeout: 15000 });
// 3. Create a new record in this entity
const createRecordBtn = page.locator('[data-testid="create-record-btn"]');
await expect(createRecordBtn).toBeVisible({ timeout: 15000 });
await createRecordBtn.click();
const recordModal = page.getByRole('dialog');
await expect(recordModal).toBeVisible({ timeout: 10000 });
const recordTitle = `Кофемашина La Marzocco ${suffix}`;
const recordNameInput = recordModal.locator('input[type="text"]').first();
await recordNameInput.fill(recordTitle);
const submitRecordBtn = recordModal.locator('[data-testid="dynamic-form-submit"]');
await submitRecordBtn.click();
await expect(recordModal).not.toBeVisible({ timeout: 10000 });
// 4. Verify record in table (scope to active responsive view: mobile cards vs desktop table)
const isMobile = await page.locator('[data-testid="mobile-menu-btn"]').isVisible();
const recordItem = isMobile
? page.locator('[data-testid="mobile-table-cards"]').locator(`text=${recordTitle}`).first()
: page.locator('table').locator(`text=${recordTitle}`).first();
await expect(recordItem).toBeVisible({ timeout: 10000 });
// 5. Reload and verify persistence from IndexedDB
await page.reload({ waitUntil: 'domcontentloaded' });
await page.waitForLoadState('domcontentloaded');
const recordItemAfterReload = isMobile
? page.locator('[data-testid="mobile-table-cards"]').locator(`text=${recordTitle}`).first()
: page.locator('table').locator(`text=${recordTitle}`).first();
await expect(recordItemAfterReload).toBeVisible({ timeout: 10000 });
});
});