375bcfb0fa
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.
335 lines
12 KiB
TypeScript
335 lines
12 KiB
TypeScript
import { test, expect } from '@playwright/test';
|
|
import type { Page } from '@playwright/test';
|
|
import {
|
|
buildFlightsMapPath,
|
|
buildRouteParam,
|
|
generateFlight,
|
|
generateFlights,
|
|
getToday,
|
|
getTomorrow,
|
|
CITIES,
|
|
} from '@e2e/support/test-utilities';
|
|
|
|
const today = getToday();
|
|
const tomorrow = getTomorrow();
|
|
|
|
// ============================================================================
|
|
// Flights Map Tests
|
|
// ============================================================================
|
|
|
|
test.describe('Flights Map', () => {
|
|
test.describe('Page Navigation', () => {
|
|
test('should navigate to flights map page', async ({ page }) => {
|
|
await page.goto(`/ru-ru${buildFlightsMapPath()}`);
|
|
await page.waitForLoadState('networkidle');
|
|
|
|
await expect(page).toHaveURL(/flights-map/);
|
|
await expect(page).toHaveTitle(/Карта полетов/);
|
|
});
|
|
|
|
test('should display map container', async ({ page }) => {
|
|
await page.goto(`/ru-ru${buildFlightsMapPath()}`);
|
|
await page.waitForLoadState('networkidle');
|
|
|
|
const mapContainer = page.locator('[data-testid="map-container"]');
|
|
await expect(mapContainer).toBeVisible();
|
|
});
|
|
});
|
|
|
|
test.describe('Map Display', () => {
|
|
test('should display flight markers', async ({ page }) => {
|
|
await page.goto(`/ru-ru${buildFlightsMapPath()}`);
|
|
await page.waitForLoadState('networkidle');
|
|
|
|
const markers = page.locator('[data-testid="flight-marker"]');
|
|
await expect(markers).toHaveCount(20);
|
|
});
|
|
|
|
test('should display flight popup on marker click', async ({ page }) => {
|
|
await page.goto(`/ru-ru${buildFlightsMapPath()}`);
|
|
await page.waitForLoadState('networkidle');
|
|
|
|
const marker = page.locator('[data-testid="flight-marker"]').first();
|
|
await marker.click();
|
|
|
|
const popup = page.locator('[data-testid="flight-popup"]');
|
|
await expect(popup).toBeVisible();
|
|
});
|
|
|
|
test('should display flight details in popup', async ({ page }) => {
|
|
await page.goto(`/ru-ru${buildFlightsMapPath()}`);
|
|
await page.waitForLoadState('networkidle');
|
|
|
|
const marker = page.locator('[data-testid="flight-marker"]').first();
|
|
await marker.click();
|
|
|
|
const flightNumber = page.locator('[data-testid="popup-flight-number"]');
|
|
await expect(flightNumber).toBeVisible();
|
|
});
|
|
|
|
test('should display route line between airports', async ({ page }) => {
|
|
await page.goto(`/ru-ru${buildFlightsMapPath()}`);
|
|
await page.waitForLoadState('networkidle');
|
|
|
|
const routeLine = page.locator('[data-testid="route-line"]');
|
|
await expect(routeLine).toBeVisible();
|
|
});
|
|
});
|
|
|
|
test.describe('Filtering', () => {
|
|
test('should filter by departure city', async ({ page }) => {
|
|
await page.goto(`/ru-ru${buildFlightsMapPath()}`);
|
|
await page.waitForLoadState('networkidle');
|
|
|
|
const departureFilter = page.locator('[data-testid="departure-filter"]');
|
|
await departureFilter.click();
|
|
|
|
const moscowOption = page.locator('[data-testid="filter-option-MOW"]');
|
|
await moscowOption.click();
|
|
|
|
const markers = page.locator('[data-testid="flight-marker"]');
|
|
await expect(markers).toHaveCount(20);
|
|
});
|
|
|
|
test('should filter by arrival city', async ({ page }) => {
|
|
await page.goto(`/ru-ru${buildFlightsMapPath()}`);
|
|
await page.waitForLoadState('networkidle');
|
|
|
|
const arrivalFilter = page.locator('[data-testid="arrival-filter"]');
|
|
await arrivalFilter.click();
|
|
|
|
const sochiOption = page.locator('[data-testid="filter-option-AER"]');
|
|
await sochiOption.click();
|
|
|
|
const markers = page.locator('[data-testid="flight-marker"]');
|
|
await expect(markers).toHaveCount(20);
|
|
});
|
|
|
|
test('should filter by status', async ({ page }) => {
|
|
await page.goto(`/ru-ru${buildFlightsMapPath()}`);
|
|
await page.waitForLoadState('networkidle');
|
|
|
|
const statusFilter = page.locator('[data-testid="status-filter"]');
|
|
await statusFilter.click();
|
|
|
|
const scheduledOption = page.locator('[data-testid="filter-option-scheduled"]');
|
|
await scheduledOption.click();
|
|
|
|
const markers = page.locator('[data-testid="flight-marker"]');
|
|
await expect(markers).toHaveCount(20);
|
|
});
|
|
|
|
test('should clear all filters', async ({ page }) => {
|
|
await page.goto(`/ru-ru${buildFlightsMapPath()}`);
|
|
await page.waitForLoadState('networkidle');
|
|
|
|
const clearFilters = page.locator('[data-testid="clear-filters"]');
|
|
await clearFilters.click();
|
|
|
|
const markers = page.locator('[data-testid="flight-marker"]');
|
|
await expect(markers).toHaveCount(20);
|
|
});
|
|
});
|
|
|
|
test.describe('Flight Details Panel', () => {
|
|
test('should display flight details panel', async ({ page }) => {
|
|
await page.goto(`/ru-ru${buildFlightsMapPath()}`);
|
|
await page.waitForLoadState('networkidle');
|
|
|
|
const panel = page.locator('[data-testid="flight-details-panel"]');
|
|
await expect(panel).toBeVisible();
|
|
});
|
|
|
|
test('should display flight number in panel', async ({ page }) => {
|
|
await page.goto(`/ru-ru${buildFlightsMapPath()}`);
|
|
await page.waitForLoadState('networkidle');
|
|
|
|
const flightNumber = page.locator('[data-testid="panel-flight-number"]');
|
|
await expect(flightNumber).toBeVisible();
|
|
});
|
|
|
|
test('should display airline name in panel', async ({ page }) => {
|
|
await page.goto(`/ru-ru${buildFlightsMapPath()}`);
|
|
await page.waitForLoadState('networkidle');
|
|
|
|
const airlineName = page.locator('[data-testid="panel-airline-name"]');
|
|
await expect(airlineName).toBeVisible();
|
|
});
|
|
|
|
test('should display departure and arrival cities in panel', async ({ page }) => {
|
|
await page.goto(`/ru-ru${buildFlightsMapPath()}`);
|
|
await page.waitForLoadState('networkidle');
|
|
|
|
const departureCity = page.locator('[data-testid="panel-departure-city"]');
|
|
await expect(departureCity).toBeVisible();
|
|
|
|
const arrivalCity = page.locator('[data-testid="panel-arrival-city"]');
|
|
await expect(arrivalCity).toBeVisible();
|
|
});
|
|
|
|
test('should display scheduled times in panel', async ({ page }) => {
|
|
await page.goto(`/ru-ru${buildFlightsMapPath()}`);
|
|
await page.waitForLoadState('networkidle');
|
|
|
|
const depTime = page.locator('[data-testid="panel-departure-time"]');
|
|
await expect(depTime).toBeVisible();
|
|
|
|
const arrTime = page.locator('[data-testid="panel-arrival-time"]');
|
|
await expect(arrTime).toBeVisible();
|
|
});
|
|
|
|
test('should display aircraft type in panel', async ({ page }) => {
|
|
await page.goto(`/ru-ru${buildFlightsMapPath()}`);
|
|
await page.waitForLoadState('networkidle');
|
|
|
|
const aircraftType = page.locator('[data-testid="panel-aircraft-type"]');
|
|
await expect(aircraftType).toBeVisible();
|
|
});
|
|
|
|
test('should display flight status in panel', async ({ page }) => {
|
|
await page.goto(`/ru-ru${buildFlightsMapPath()}`);
|
|
await page.waitForLoadState('networkidle');
|
|
|
|
const status = page.locator('[data-testid="panel-status"]');
|
|
await expect(status).toBeVisible();
|
|
});
|
|
});
|
|
|
|
test.describe('Map Controls', () => {
|
|
test('should have zoom in button', async ({ page }) => {
|
|
await page.goto(`/ru-ru${buildFlightsMapPath()}`);
|
|
await page.waitForLoadState('networkidle');
|
|
|
|
const zoomIn = page.locator('[data-testid="zoom-in"]');
|
|
await expect(zoomIn).toBeVisible();
|
|
});
|
|
|
|
test('should have zoom out button', async ({ page }) => {
|
|
await page.goto(`/ru-ru${buildFlightsMapPath()}`);
|
|
await page.waitForLoadState('networkidle');
|
|
|
|
const zoomOut = page.locator('[data-testid="zoom-out"]');
|
|
await expect(zoomOut).toBeVisible();
|
|
});
|
|
|
|
test('should have full screen button', async ({ page }) => {
|
|
await page.goto(`/ru-ru${buildFlightsMapPath()}`);
|
|
await page.waitForLoadState('networkidle');
|
|
|
|
const fullScreen = page.locator('[data-testid="full-screen"]');
|
|
await expect(fullScreen).toBeVisible();
|
|
});
|
|
|
|
test('should have layer toggle', async ({ page }) => {
|
|
await page.goto(`/ru-ru${buildFlightsMapPath()}`);
|
|
await page.waitForLoadState('networkidle');
|
|
|
|
const layerToggle = page.locator('[data-testid="layer-toggle"]');
|
|
await expect(layerToggle).toBeVisible();
|
|
});
|
|
});
|
|
|
|
test.describe('Cluster Markers', () => {
|
|
test('should display cluster markers for multiple flights', async ({ page }) => {
|
|
await page.goto(`/ru-ru${buildFlightsMapPath()}`);
|
|
await page.waitForLoadState('networkidle');
|
|
|
|
const cluster = page.locator('[data-testid="cluster-marker"]');
|
|
if ((await cluster.count()) > 0) {
|
|
await expect(cluster).toBeVisible();
|
|
}
|
|
});
|
|
|
|
test('should expand cluster on click', async ({ page }) => {
|
|
await page.goto(`/ru-ru${buildFlightsMapPath()}`);
|
|
await page.waitForLoadState('networkidle');
|
|
|
|
const cluster = page.locator('[data-testid="cluster-marker"]').first();
|
|
if ((await cluster.count()) > 0) {
|
|
await cluster.click();
|
|
await page.waitForTimeout(500);
|
|
|
|
const markers = page.locator('[data-testid="flight-marker"]');
|
|
await expect(markers).toHaveCount(20);
|
|
}
|
|
});
|
|
});
|
|
|
|
test.describe('Error Handling', () => {
|
|
test('should handle network error', async ({ page }) => {
|
|
await page.route('**/api/flights-map/**', (route) => {
|
|
return route.abort('internetdisconnected');
|
|
});
|
|
|
|
await page.goto(`/ru-ru${buildFlightsMapPath()}`);
|
|
await page.waitForLoadState('networkidle');
|
|
|
|
const networkError = page.locator('[data-testid="network-error"]');
|
|
await expect(networkError).toBeVisible();
|
|
});
|
|
|
|
test('should handle map loading error', async ({ page }) => {
|
|
await page.route('**/api/maps/**', (route) => {
|
|
return route.abort('internetdisconnected');
|
|
});
|
|
|
|
await page.goto(`/ru-ru${buildFlightsMapPath()}`);
|
|
await page.waitForLoadState('networkidle');
|
|
|
|
const mapError = page.locator('[data-testid="map-error"]');
|
|
await expect(mapError).toBeVisible();
|
|
});
|
|
});
|
|
|
|
test.describe('Accessibility', () => {
|
|
test('should have proper ARIA labels', async ({ page }) => {
|
|
await page.goto(`/ru-ru${buildFlightsMapPath()}`);
|
|
await page.waitForLoadState('networkidle');
|
|
|
|
const mapContainer = page.locator('[data-testid="map-container"]');
|
|
await expect(mapContainer).toHaveAttribute('role', 'application');
|
|
});
|
|
|
|
test('should be keyboard navigable', async ({ page }) => {
|
|
await page.goto(`/ru-ru${buildFlightsMapPath()}`);
|
|
await page.waitForLoadState('networkidle');
|
|
|
|
await page.keyboard.press('Tab');
|
|
await page.keyboard.press('Tab');
|
|
await page.keyboard.press('Tab');
|
|
|
|
const focusedElement = page.locator(':focus');
|
|
await expect(focusedElement).toBeVisible();
|
|
});
|
|
});
|
|
|
|
test.describe('Responsive Design', () => {
|
|
test('should be responsive on mobile', async ({ page }) => {
|
|
await page.setViewportSize({ width: 375, height: 667 });
|
|
await page.goto(`/ru-ru${buildFlightsMapPath()}`);
|
|
await page.waitForLoadState('networkidle');
|
|
|
|
const mapContainer = page.locator('[data-testid="map-container"]');
|
|
await expect(mapContainer).toBeVisible();
|
|
});
|
|
|
|
test('should be responsive on tablet', async ({ page }) => {
|
|
await page.setViewportSize({ width: 768, height: 1024 });
|
|
await page.goto(`/ru-ru${buildFlightsMapPath()}`);
|
|
await page.waitForLoadState('networkidle');
|
|
|
|
const mapContainer = page.locator('[data-testid="map-container"]');
|
|
await expect(mapContainer).toBeVisible();
|
|
});
|
|
|
|
test('should be responsive on desktop', async ({ page }) => {
|
|
await page.setViewportSize({ width: 1920, height: 1080 });
|
|
await page.goto(`/ru-ru${buildFlightsMapPath()}`);
|
|
await page.waitForLoadState('networkidle');
|
|
|
|
const mapContainer = page.locator('[data-testid="map-container"]');
|
|
await expect(mapContainer).toBeVisible();
|
|
});
|
|
});
|
|
});
|