fix(e2e): use domcontentloaded navigation across all test suites to prevent preview server load timeouts
This commit is contained in:
parent
e40b935f43
commit
0c479f568c
12 changed files with 32 additions and 28 deletions
|
|
@ -9,7 +9,7 @@ test.describe('Scenario 01: Dashboard Integrity & Viewport Matrix', () => {
|
|||
}
|
||||
});
|
||||
|
||||
await page.goto('/');
|
||||
await page.goto('/', { waitUntil: 'domcontentloaded' });
|
||||
await page.waitForLoadState('domcontentloaded');
|
||||
|
||||
// Verify dashboard title / header
|
||||
|
|
|
|||
|
|
@ -37,7 +37,7 @@ test.describe('Scenario 02: Theme Engine & UI Persistence', () => {
|
|||
await expect(page.locator('html')).toHaveAttribute('data-theme', 'dark');
|
||||
|
||||
// 2. Reload and verify Dark Theme persistence
|
||||
await page.reload();
|
||||
await page.reload({ waitUntil: 'domcontentloaded' });
|
||||
await page.waitForLoadState('domcontentloaded');
|
||||
await expect(page.locator('html')).toHaveAttribute('data-theme', 'dark');
|
||||
|
||||
|
|
@ -52,7 +52,7 @@ test.describe('Scenario 02: Theme Engine & UI Persistence', () => {
|
|||
await expect(page.locator('html')).toHaveAttribute('data-theme', 'soft-light');
|
||||
|
||||
// 5. Reload and verify Soft Light Theme persistence
|
||||
await page.reload();
|
||||
await page.reload({ waitUntil: 'domcontentloaded' });
|
||||
await page.waitForLoadState('domcontentloaded');
|
||||
await expect(page.locator('html')).toHaveAttribute('data-theme', 'soft-light');
|
||||
});
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@ 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.goto('/crm/deals', { waitUntil: 'domcontentloaded' });
|
||||
await page.waitForLoadState('domcontentloaded');
|
||||
|
||||
// Switch to Deals tab if needed
|
||||
|
|
@ -17,11 +17,13 @@ test.describe('Scenario 03: CRM Kanban Drag-and-Drop & Stage Persistence', () =>
|
|||
|
||||
// Pick first available deal card
|
||||
const firstCard = dealCards.first();
|
||||
await firstCard.scrollIntoViewIfNeeded().catch(() => {});
|
||||
const dealId = await firstCard.getAttribute('data-deal-id');
|
||||
expect(dealId).toBeTruthy();
|
||||
|
||||
const targetStage = 'negotiation';
|
||||
const targetColumn = page.locator(`[data-testid="kanban-column-${targetStage}"]`);
|
||||
await targetColumn.scrollIntoViewIfNeeded().catch(() => {});
|
||||
await expect(targetColumn).toBeVisible();
|
||||
|
||||
// Perform Drag and Drop (with short timeout and fallback to transition button if intercepted)
|
||||
|
|
@ -32,16 +34,18 @@ test.describe('Scenario 03: CRM Kanban Drag-and-Drop & Stage Persistence', () =>
|
|||
if (!await cardInTarget.isVisible({ timeout: 2000 }).catch(() => false)) {
|
||||
const nextBtn = page.locator(`[data-testid="deal-card-${dealId}"] button:has-text("Далее:")`).first();
|
||||
if (await nextBtn.isVisible({ timeout: 2000 }).catch(() => false)) {
|
||||
await nextBtn.scrollIntoViewIfNeeded().catch(() => {});
|
||||
await nextBtn.click({ force: true }).catch(() => {});
|
||||
}
|
||||
}
|
||||
|
||||
// Reload page to verify persistence in IndexedDB
|
||||
await page.reload();
|
||||
await page.reload({ waitUntil: 'domcontentloaded' });
|
||||
await page.waitForLoadState('domcontentloaded');
|
||||
|
||||
// Ensure the card still exists and its updated stage persisted
|
||||
const persistedCard = page.locator(`[data-testid="deal-card-${dealId}"]`);
|
||||
await persistedCard.scrollIntoViewIfNeeded().catch(() => {});
|
||||
await expect(persistedCard).toBeVisible({ timeout: 15000 });
|
||||
});
|
||||
});
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@ import { test, expect } from '@playwright/test';
|
|||
|
||||
test.describe('Scenario 04: CRM Lead Creation & Full Conversion Flow', () => {
|
||||
test('creates a new lead, converts it into contact and deal, and verifies both', async ({ page }) => {
|
||||
await page.goto('/crm/leads');
|
||||
await page.goto('/crm/leads', { waitUntil: 'domcontentloaded' });
|
||||
await page.waitForLoadState('domcontentloaded');
|
||||
|
||||
// Ensure Leads tab is active
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@ import { test, expect } from '@playwright/test';
|
|||
test.describe('Scenario 05: CRM Deal Won -> Commercial Order Flow', () => {
|
||||
test('advances deal to Won, confirms linked Order creation, and verifies order in Sales', async ({ page }) => {
|
||||
test.setTimeout(60000);
|
||||
await page.goto('/crm/deals');
|
||||
await page.goto('/crm/deals', { waitUntil: 'domcontentloaded' });
|
||||
await page.waitForLoadState('domcontentloaded');
|
||||
|
||||
// Switch to Deals tab if needed
|
||||
|
|
@ -39,7 +39,7 @@ test.describe('Scenario 05: CRM Deal Won -> Commercial Order Flow', () => {
|
|||
await page.waitForTimeout(500);
|
||||
|
||||
// Navigate to Sales module
|
||||
await page.goto('/sales');
|
||||
await page.goto('/sales', { waitUntil: 'domcontentloaded' });
|
||||
await page.waitForLoadState('domcontentloaded');
|
||||
|
||||
// Verify order exists in the Commerce Orders table
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@ import { test, expect } from '@playwright/test';
|
|||
|
||||
test.describe('Scenario 06: Commercial Order Fulfillment (Confirm -> Payment -> Shipment)', () => {
|
||||
test('executes end-to-end order lifecycle and verifies finance and inventory sync', async ({ page }) => {
|
||||
await page.goto('/sales');
|
||||
await page.goto('/sales', { waitUntil: 'domcontentloaded' });
|
||||
await page.waitForLoadState('domcontentloaded');
|
||||
|
||||
// 1. Select an order from the list
|
||||
|
|
@ -38,13 +38,13 @@ test.describe('Scenario 06: Commercial Order Fulfillment (Confirm -> Payment ->
|
|||
}
|
||||
|
||||
// 5. Navigate to Finance: Verify Cash Flow / DDS Reflection in main area
|
||||
await page.goto('/finance');
|
||||
await page.goto('/finance', { waitUntil: 'domcontentloaded' });
|
||||
await page.waitForLoadState('domcontentloaded');
|
||||
await expect(page.locator('main').locator('text=Финансы').or(page.locator('main').locator('text=ДДС')).first()).toBeVisible({ timeout: 15000 });
|
||||
await expect(page.locator('tbody tr').first()).toBeVisible({ timeout: 10000 });
|
||||
|
||||
// 6. Navigate to Inventory: Verify warehouse stock view in main area
|
||||
await page.goto('/inventory');
|
||||
await page.goto('/inventory', { waitUntil: 'domcontentloaded' });
|
||||
await page.waitForLoadState('domcontentloaded');
|
||||
await expect(page.locator('main').locator('text=Склад').or(page.locator('main').locator('text=Остатки')).first()).toBeVisible({ timeout: 15000 });
|
||||
});
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@ 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');
|
||||
await page.goto('/settings/entities', { waitUntil: 'domcontentloaded' });
|
||||
await page.waitForLoadState('domcontentloaded');
|
||||
|
||||
// 1. Open Create Entity Modal
|
||||
|
|
@ -66,7 +66,7 @@ test.describe('Scenario 07: Configuration Engine (Entity Creation & Custom Recor
|
|||
await expect(recordItem).toBeVisible({ timeout: 10000 });
|
||||
|
||||
// 5. Reload and verify persistence from IndexedDB
|
||||
await page.reload();
|
||||
await page.reload({ waitUntil: 'domcontentloaded' });
|
||||
await page.waitForLoadState('domcontentloaded');
|
||||
const recordItemAfterReload = isMobile
|
||||
? page.locator('[data-testid="mobile-table-cards"]').locator(`text=${recordTitle}`).first()
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@ import { test, expect } from '@playwright/test';
|
|||
|
||||
test.describe('Scenario 08: View Builder & Column Reordering', () => {
|
||||
test('reorders columns in View Builder, saves view, and verifies persistence across reload', async ({ page }) => {
|
||||
await page.goto('/settings/entities/deal/views');
|
||||
await page.goto('/settings/entities/deal/views', { waitUntil: 'domcontentloaded' });
|
||||
await page.waitForLoadState('domcontentloaded');
|
||||
|
||||
// Wait for view builder to load
|
||||
|
|
@ -35,7 +35,7 @@ test.describe('Scenario 08: View Builder & Column Reordering', () => {
|
|||
await expect(page.locator('text=сохранено').first()).toBeVisible({ timeout: 10000 });
|
||||
|
||||
// Reload page to verify persistence
|
||||
await page.reload();
|
||||
await page.reload({ waitUntil: 'domcontentloaded' });
|
||||
await page.waitForLoadState('domcontentloaded');
|
||||
|
||||
await expect(page.locator('text=Конструктор представлений').first()).toBeVisible({ timeout: 15000 });
|
||||
|
|
|
|||
|
|
@ -29,7 +29,7 @@ test.describe('Scenario 09: RBAC Guard & 403 Forbidden Handling', () => {
|
|||
}
|
||||
|
||||
// 2. Navigate to protected route /finance (Cashier has no permission to Finance)
|
||||
await page.goto('/finance');
|
||||
await page.goto('/finance', { waitUntil: 'domcontentloaded' });
|
||||
await page.waitForLoadState('domcontentloaded');
|
||||
|
||||
// 3. Verify 403 Forbidden page is displayed
|
||||
|
|
@ -43,7 +43,7 @@ test.describe('Scenario 09: RBAC Guard & 403 Forbidden Handling', () => {
|
|||
await switchToOwnerBtn.click();
|
||||
|
||||
// 5. Navigate back to /finance and verify access restored
|
||||
await page.goto('/finance');
|
||||
await page.goto('/finance', { waitUntil: 'domcontentloaded' });
|
||||
await page.waitForLoadState('domcontentloaded');
|
||||
|
||||
// Finance content should now be visible without 403
|
||||
|
|
|
|||
|
|
@ -35,7 +35,7 @@ test.describe('Scenario 10: IndexedDB Snapshots (Export, Reset, Import)', () =>
|
|||
}
|
||||
|
||||
// 5. Reload page to ensure restored state persists
|
||||
await page.reload();
|
||||
await page.reload({ waitUntil: 'domcontentloaded' });
|
||||
await page.waitForLoadState('domcontentloaded');
|
||||
|
||||
const retryBtn = page.locator('button:has-text("Попробовать снова")');
|
||||
|
|
|
|||
|
|
@ -83,7 +83,7 @@ test.describe('Scenario 11: Universal Modules Catalog & Profiles', () => {
|
|||
await page.waitForURL('**/crm');
|
||||
await expect(page.locator('h1, h2').first()).toBeVisible();
|
||||
|
||||
await page.goto('/');
|
||||
await page.goto('/', { waitUntil: 'domcontentloaded' });
|
||||
await page.waitForLoadState('domcontentloaded');
|
||||
|
||||
const procOpenBtn = page.locator('[data-testid="module-open-btn-procurement"]');
|
||||
|
|
@ -119,7 +119,7 @@ test.describe('Scenario 11: Universal Modules Catalog & Profiles', () => {
|
|||
await retailBtn.click();
|
||||
await expect(page.locator('[data-testid="recommended-section"]')).toBeVisible();
|
||||
|
||||
await page.goto('/settings/entities');
|
||||
await page.goto('/settings/entities', { waitUntil: 'domcontentloaded' });
|
||||
await page.waitForLoadState('domcontentloaded');
|
||||
|
||||
const resetBtn = page.getByRole('button', { name: /Сбросить базу данных/i });
|
||||
|
|
@ -133,7 +133,7 @@ test.describe('Scenario 11: Universal Modules Catalog & Profiles', () => {
|
|||
|
||||
await page.waitForTimeout(1000);
|
||||
|
||||
await page.goto('/');
|
||||
await page.goto('/', { waitUntil: 'domcontentloaded' });
|
||||
await page.waitForLoadState('domcontentloaded');
|
||||
|
||||
const allProfileBtn = page.locator('[data-testid="profile-filter-all"]');
|
||||
|
|
|
|||
|
|
@ -105,7 +105,7 @@ test.describe('Scenario 12: Mobile-First and Tablet Architecture Overhaul', () =
|
|||
expect(isOverflowing).toBe(false);
|
||||
|
||||
// Verify on /crm
|
||||
await page.goto('/crm');
|
||||
await page.goto('/crm', { waitUntil: 'domcontentloaded' });
|
||||
await page.waitForLoadState('domcontentloaded');
|
||||
const isCrmOverflowing = await page.evaluate(() => {
|
||||
return document.documentElement.scrollWidth > document.documentElement.clientWidth;
|
||||
|
|
@ -113,7 +113,7 @@ test.describe('Scenario 12: Mobile-First and Tablet Architecture Overhaul', () =
|
|||
expect(isCrmOverflowing).toBe(false);
|
||||
|
||||
// Verify on /settings/entities
|
||||
await page.goto('/settings/entities');
|
||||
await page.goto('/settings/entities', { waitUntil: 'domcontentloaded' });
|
||||
await page.waitForLoadState('domcontentloaded');
|
||||
const isSettingsOverflowing = await page.evaluate(() => {
|
||||
return document.documentElement.scrollWidth > document.documentElement.clientWidth;
|
||||
|
|
@ -122,7 +122,7 @@ test.describe('Scenario 12: Mobile-First and Tablet Architecture Overhaul', () =
|
|||
});
|
||||
|
||||
test('5. DynamicTable renders responsive card list on mobile screens', async ({ page, viewport }) => {
|
||||
await page.goto('/crm');
|
||||
await page.goto('/crm', { waitUntil: 'domcontentloaded' });
|
||||
await page.waitForLoadState('domcontentloaded');
|
||||
|
||||
const isMobileViewport = viewport && viewport.width < 768;
|
||||
|
|
@ -136,7 +136,7 @@ test.describe('Scenario 12: Mobile-First and Tablet Architecture Overhaul', () =
|
|||
});
|
||||
|
||||
test('6. FormBuilder supports touch-friendly up and down field reordering', async ({ page }) => {
|
||||
await page.goto('/settings/entities/contact/form-builder');
|
||||
await page.goto('/settings/entities/contact/form-builder', { waitUntil: 'domcontentloaded' });
|
||||
await page.waitForLoadState('domcontentloaded');
|
||||
|
||||
// Locate field move buttons
|
||||
|
|
@ -170,7 +170,7 @@ test.describe('Scenario 12: Mobile-First and Tablet Architecture Overhaul', () =
|
|||
window.localStorage.setItem('krona_theme_mode', 'light');
|
||||
document.documentElement.setAttribute('data-theme', 'light');
|
||||
});
|
||||
await page.reload();
|
||||
await page.reload({ waitUntil: 'domcontentloaded' });
|
||||
let currentTheme = await page.evaluate(() => document.documentElement.getAttribute('data-theme'));
|
||||
expect(currentTheme).toBe('light');
|
||||
|
||||
|
|
@ -179,7 +179,7 @@ test.describe('Scenario 12: Mobile-First and Tablet Architecture Overhaul', () =
|
|||
window.localStorage.setItem('krona_theme_mode', 'dark');
|
||||
document.documentElement.setAttribute('data-theme', 'dark');
|
||||
});
|
||||
await page.reload();
|
||||
await page.reload({ waitUntil: 'domcontentloaded' });
|
||||
currentTheme = await page.evaluate(() => document.documentElement.getAttribute('data-theme'));
|
||||
expect(currentTheme).toBe('dark');
|
||||
|
||||
|
|
@ -188,7 +188,7 @@ test.describe('Scenario 12: Mobile-First and Tablet Architecture Overhaul', () =
|
|||
window.localStorage.setItem('krona_theme_mode', 'soft-light');
|
||||
document.documentElement.setAttribute('data-theme', 'soft-light');
|
||||
});
|
||||
await page.reload();
|
||||
await page.reload({ waitUntil: 'domcontentloaded' });
|
||||
currentTheme = await page.evaluate(() => document.documentElement.getAttribute('data-theme'));
|
||||
expect(currentTheme).toBe('soft-light');
|
||||
});
|
||||
|
|
|
|||
Loading…
Reference in a new issue