Files
flights_web/tests/e2e-angular/ru-ru/persistent-state.spec.ts
T
gnezim 375bcfb0fa Add e2e test suite from flights-front with Angular API mocks
Copies Playwright e2e tests (58 specs, 300+ tests) designed for cross-app
testing. Adapts API mocks to match real Aeroflot dictionary format (title
objects with multilingual keys), adds board/schedule/days endpoint mocks,
and provides Angular-specific Playwright config on port 4203.
2026-04-15 23:07:44 +03:00

118 lines
3.6 KiB
TypeScript

import { test, expect } from '@playwright/test';
test.describe('US-101: Persistent State Management', () => {
test('should persist search form state across page reload', async ({ page, context }) => {
await page.goto('http://localhost:3002/ru-ru/schedule');
await page.waitForLoadState('networkidle');
// Fill search form
await page
.locator('input[placeholder*="city"], [aria-label*="город отправления"]')
.first()
.fill('Moscow');
await page
.locator('input[placeholder*="city"], [aria-label*="город прибытия"]')
.nth(1)
.fill('St Petersburg');
// Reload page
await page.reload();
await page.waitForLoadState('networkidle');
// Check that form values are still there
const fromInput = await page.locator('input').first().inputValue();
const toInput = await page.locator('input').nth(1).inputValue();
expect(fromInput).toBe('Moscow');
expect(toInput).toBe('St Petersburg');
});
test('should respect 30-day expiration for persisted state', async ({ page }) => {
await page.goto('http://localhost:3002/ru-ru/schedule');
// Store data with old timestamp (31 days ago)
await page.evaluate(() => {
const thirtyOneDaysAgo = Date.now() - 31 * 24 * 60 * 60 * 1000;
const data = JSON.stringify({
value: { test: 'data' },
timestamp: thirtyOneDaysAgo,
});
localStorage.setItem('aeroflot_expiredTest', data);
});
// Reload and check if expired data is gone
await page.reload();
await page.waitForLoadState('networkidle');
const expiredData = await page.evaluate(() => {
return localStorage.getItem('aeroflot_expiredTest');
});
expect(expiredData).toBeNull();
});
test('should handle localStorage quota gracefully', async ({ page }) => {
await page.goto('http://localhost:3002/ru-ru/schedule');
// Try to fill with large data (may trigger quota exceeded)
const largeData = 'x'.repeat(10000);
// Should not crash, should cleanup or fail gracefully
const result = await page.evaluate(async (data) => {
try {
localStorage.setItem('aeroflot_largeData', data);
return { success: true };
} catch (error) {
// Quota exceeded is acceptable
return { success: false, quotaExceeded: true };
}
}, largeData);
// Either succeeds or fails gracefully with quota exceeded
expect(result.success || result.quotaExceeded).toBe(true);
});
test('should clear state when requested', async ({ page }) => {
await page.goto('http://localhost:3002/ru-ru/schedule');
// Store data
await page.evaluate(() => {
localStorage.setItem(
'aeroflot_clearTest',
JSON.stringify({
value: { test: 'data' },
timestamp: Date.now(),
}),
);
});
// Clear it
await page.evaluate(() => {
localStorage.removeItem('aeroflot_clearTest');
});
// Verify it's gone
const cleared = await page.evaluate(() => {
return localStorage.getItem('aeroflot_clearTest');
});
expect(cleared).toBeNull();
});
test('should console have zero errors', async ({ page }) => {
const errors: string[] = [];
page.on('console', (msg) => {
if (msg.type() === 'error') errors.push(msg.text());
});
await page.goto('http://localhost:3002/ru-ru/schedule');
await page.waitForLoadState('networkidle');
// Interact with persistent state
await page.locator('input').first().fill('Moscow');
await page.reload();
expect(errors).toHaveLength(0);
});
});