import { test, expect } from '@playwright/test'; test.describe('Scenario 03: CRM Kanban Drag-and-Drop & Stage Persistence', () => { test('drags a deal card between kanban stages and verifies persistence after reload', async ({ page }) => { await page.goto('/crm/deals'); await page.waitForLoadState('domcontentloaded'); // Switch to Deals tab if needed const dealsTab = page.locator('button:has-text("Воронка сделок")'); if (await dealsTab.isVisible()) { await dealsTab.click({ force: true }); } // Wait for Kanban board to load with deal cards const dealCards = page.locator('[data-testid^="deal-card-"]'); await expect(dealCards.first()).toBeVisible({ timeout: 15000 }); // Pick first available deal card const firstCard = dealCards.first(); const dealId = await firstCard.getAttribute('data-deal-id'); expect(dealId).toBeTruthy(); const targetStage = 'negotiation'; const targetColumn = page.locator(`[data-testid="kanban-column-${targetStage}"]`); await expect(targetColumn).toBeVisible(); // Perform Drag and Drop await firstCard.dragTo(targetColumn); // Verify card moved to target column const cardInTarget = targetColumn.locator(`[data-testid="deal-card-${dealId}"]`); // If synthetic dragTo is intercepted by browser touch emulation, card transition button also exists if (!await cardInTarget.isVisible({ timeout: 2000 }).catch(() => false)) { const nextBtn = firstCard.locator('button:has-text("Далее:")'); if (await nextBtn.isVisible()) { await nextBtn.click(); } } // Reload page to verify persistence in IndexedDB await page.reload(); await page.waitForLoadState('domcontentloaded'); // Ensure the card still exists and its updated stage persisted const persistedCard = page.locator(`[data-testid="deal-card-${dealId}"]`); await expect(persistedCard).toBeVisible({ timeout: 15000 }); }); });