Files
flights_web/tests/e2e-angular/integration/templates/flight-details.template.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

451 lines
17 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import { test, expect } from '@playwright/test';
import type { Page } from '@playwright/test';
import {
buildFlightDetailsPath,
buildRouteParam,
generateFlight,
generateFlights,
getToday,
getTomorrow,
CITIES,
} from '../support/test-utilities';
const today = getToday();
const tomorrow = getTomorrow();
// ============================================================================
// Flight Details Tests
// ============================================================================
test.describe('Flight Details', () => {
test.describe('Page Navigation', () => {
test('should navigate to flight details page', async ({ page }) => {
const flight = generateFlight({ direction: 'departure', cityCode: 'MOW' });
const slug = `${flight.flightNumber.replace(/\s+/g, '')}-${today.replace(/-/g, '')}`;
await page.goto(`/ru-ru/${slug}`);
await page.waitForLoadState('networkidle');
await expect(page).toHaveURL(new RegExp(`/${slug}`));
await expect(page).toHaveTitle(new RegExp(flight.flightNumber));
});
test('should navigate to flight details for arrival flight', async ({ page }) => {
const flight = generateFlight({ direction: 'arrival', cityCode: 'MOW' });
const slug = `${flight.flightNumber.replace(/\s+/g, '')}-${today.replace(/-/g, '')}`;
await page.goto(`/ru-ru/${slug}`);
await page.waitForLoadState('networkidle');
await expect(page).toHaveURL(new RegExp(`/${slug}`));
});
test('should navigate to flight details for different date', async ({ page }) => {
const flight = generateFlight({ direction: 'departure', cityCode: 'MOW', date: tomorrow });
const slug = `${flight.flightNumber.replace(/\s+/g, '')}-${tomorrow.replace(/-/g, '')}`;
await page.goto(`/ru-ru/${slug}`);
await page.waitForLoadState('networkidle');
await expect(page).toHaveURL(new RegExp(`/${slug}`));
});
});
test.describe('Flight Information', () => {
test('should display flight number', async ({ page }) => {
const flight = generateFlight({ direction: 'departure', cityCode: 'MOW' });
const slug = `${flight.flightNumber.replace(/\s+/g, '')}-${today.replace(/-/g, '')}`;
await page.goto(`/ru-ru/${slug}`);
await page.waitForLoadState('networkidle');
const flightNumber = page.locator('[data-testid="flight-number"]');
await expect(flightNumber).toBeVisible();
await expect(flightNumber).toContainText(flight.flightNumber);
});
test('should display airline name', async ({ page }) => {
const flight = generateFlight({ direction: 'departure', cityCode: 'MOW' });
const slug = `${flight.flightNumber.replace(/\s+/g, '')}-${today.replace(/-/g, '')}`;
await page.goto(`/ru-ru/${slug}`);
await page.waitForLoadState('networkidle');
const airlineName = page.locator('[data-testid="airline-name"]');
await expect(airlineName).toBeVisible();
await expect(airlineName).toContainText(flight.airlineName);
});
test('should display aircraft type', async ({ page }) => {
const flight = generateFlight({ direction: 'departure', cityCode: 'MOW' });
const slug = `${flight.flightNumber.replace(/\s+/g, '')}-${today.replace(/-/g, '')}`;
await page.goto(`/ru-ru/${slug}`);
await page.waitForLoadState('networkidle');
const aircraftType = page.locator('[data-testid="aircraft-type"]');
await expect(aircraftType).toBeVisible();
await expect(aircraftType).toContainText(flight.aircraftType || '');
});
test('should display departure city', async ({ page }) => {
const flight = generateFlight({ direction: 'departure', cityCode: 'MOW' });
const slug = `${flight.flightNumber.replace(/\s+/g, '')}-${today.replace(/-/g, '')}`;
await page.goto(`/ru-ru/${slug}`);
await page.waitForLoadState('networkidle');
const departureCity = page.locator('[data-testid="departure-city"]');
await expect(departureCity).toBeVisible();
await expect(departureCity).toContainText(flight.departure.cityName);
});
test('should display arrival city', async ({ page }) => {
const flight = generateFlight({ direction: 'departure', cityCode: 'MOW' });
const slug = `${flight.flightNumber.replace(/\s+/g, '')}-${today.replace(/-/g, '')}`;
await page.goto(`/ru-ru/${slug}`);
await page.waitForLoadState('networkidle');
const arrivalCity = page.locator('[data-testid="arrival-city"]');
await expect(arrivalCity).toBeVisible();
await expect(arrivalCity).toContainText(flight.arrival.cityName);
});
test('should display scheduled departure time', async ({ page }) => {
const flight = generateFlight({ direction: 'departure', cityCode: 'MOW' });
const slug = `${flight.flightNumber.replace(/\s+/g, '')}-${today.replace(/-/g, '')}`;
await page.goto(`/ru-ru/${slug}`);
await page.waitForLoadState('networkidle');
const depTime = page.locator('[data-testid="scheduled-departure-time"]');
await expect(depTime).toBeVisible();
const depTimeText = flight.departure.time.scheduled.slice(11, 16);
await expect(depTime).toContainText(depTimeText);
});
test('should display scheduled arrival time', async ({ page }) => {
const flight = generateFlight({ direction: 'departure', cityCode: 'MOW' });
const slug = `${flight.flightNumber.replace(/\s+/g, '')}-${today.replace(/-/g, '')}`;
await page.goto(`/ru-ru/${slug}`);
await page.waitForLoadState('networkidle');
const arrTime = page.locator('[data-testid="scheduled-arrival-time"]');
await expect(arrTime).toBeVisible();
const arrTimeText = flight.arrival.time.scheduled.slice(11, 16);
await expect(arrTime).toContainText(arrTimeText);
});
test('should display flight duration', async ({ page }) => {
const flight = generateFlight({ direction: 'departure', cityCode: 'MOW' });
const slug = `${flight.flightNumber.replace(/\s+/g, '')}-${today.replace(/-/g, '')}`;
await page.goto(`/ru-ru/${slug}`);
await page.waitForLoadState('networkidle');
const duration = page.locator('[data-testid="flight-duration"]');
await expect(duration).toBeVisible();
});
test('should display flight status', async ({ page }) => {
const flight = generateFlight({
direction: 'departure',
cityCode: 'MOW',
status: 'scheduled',
});
const slug = `${flight.flightNumber.replace(/\s+/g, '')}-${today.replace(/-/g, '')}`;
await page.goto(`/ru-ru/${slug}`);
await page.waitForLoadState('networkidle');
const status = page.locator('[data-testid="flight-status"]');
await expect(status).toBeVisible();
await expect(status).toContainText(flight.status);
});
});
test.describe('Flight Details', () => {
test('should display terminal information', async ({ page }) => {
const flight = generateFlight({
direction: 'departure',
cityCode: 'MOW',
departure: { terminal: 'B' },
});
const slug = `${flight.flightNumber.replace(/\s+/g, '')}-${today.replace(/-/g, '')}`;
await page.goto(`/ru-ru/${slug}`);
await page.waitForLoadState('networkidle');
const terminal = page.locator('[data-testid="terminal"]');
await expect(terminal).toBeVisible();
await expect(terminal).toContainText('B');
});
test('should display boarding gate information', async ({ page }) => {
const flight = generateFlight({
direction: 'departure',
cityCode: 'MOW',
status: 'boarding',
boarding: { gate: '11', status: 'Идёт посадка' },
});
const slug = `${flight.flightNumber.replace(/\s+/g, '')}-${today.replace(/-/g, '')}`;
await page.goto(`/ru-ru/${slug}`);
await page.waitForLoadState('networkidle');
const boardingGate = page.locator('[data-testid="boarding-gate"]');
await expect(boardingGate).toBeVisible();
await expect(boardingGate).toContainText('11');
});
test('should display baggage belt information', async ({ page }) => {
const flight = generateFlight({
direction: 'arrival',
cityCode: 'MOW',
status: 'arrived',
arrivalInfo: { baggageBelt: '5', transfer: 'Тран' },
});
const slug = `${flight.flightNumber.replace(/\s+/g, '')}-${today.replace(/-/g, '')}`;
await page.goto(`/ru-ru/${slug}`);
await page.waitForLoadState('networkidle');
const baggageBelt = page.locator('[data-testid="baggage-belt"]');
await expect(baggageBelt).toBeVisible();
await expect(baggageBelt).toContainText('5');
});
test('should display check-in information', async ({ page }) => {
const flight = generateFlight({
direction: 'departure',
cityCode: 'MOW',
status: 'checkin',
checkin: { status: 'В процессе' },
});
const slug = `${flight.flightNumber.replace(/\s+/g, '')}-${today.replace(/-/g, '')}`;
await page.goto(`/ru-ru/${slug}`);
await page.waitForLoadState('networkidle');
const checkinInfo = page.locator('[data-testid="checkin-info"]');
await expect(checkinInfo).toBeVisible();
});
test('should display deplaning information', async ({ page }) => {
const flight = generateFlight({
direction: 'arrival',
cityCode: 'MOW',
status: 'arrived',
deplaning: { status: 'В процессе', transfer: 'Трап' },
});
const slug = `${flight.flightNumber.replace(/\s+/g, '')}-${today.replace(/-/g, '')}`;
await page.goto(`/ru-ru/${slug}`);
await page.waitForLoadState('networkidle');
const deplaningInfo = page.locator('[data-testid="deplaning-info"]');
await expect(deplaningInfo).toBeVisible();
});
});
test.describe('Aircraft Information', () => {
test('should display aircraft type', async ({ page }) => {
const flight = generateFlight({ direction: 'departure', cityCode: 'MOW' });
const slug = `${flight.flightNumber.replace(/\s+/g, '')}-${today.replace(/-/g, '')}`;
await page.goto(`/ru-ru/${slug}`);
await page.waitForLoadState('networkidle');
const aircraftType = page.locator('[data-testid="aircraft-type"]');
await expect(aircraftType).toBeVisible();
});
test('should display aircraft name', async ({ page }) => {
const flight = generateFlight({
direction: 'departure',
cityCode: 'MOW',
aircraft: { type: 'Airbus A320', name: 'В. Высоцкий' },
});
const slug = `${flight.flightNumber.replace(/\s+/g, '')}-${today.replace(/-/g, '')}`;
await page.goto(`/ru-ru/${slug}`);
await page.waitForLoadState('networkidle');
const aircraftName = page.locator('[data-testid="aircraft-name"]');
await expect(aircraftName).toBeVisible();
await expect(aircraftName).toContainText('В. Высоцкий');
});
test('should display seat configuration', async ({ page }) => {
const flight = generateFlight({ direction: 'departure', cityCode: 'MOW' });
const slug = `${flight.flightNumber.replace(/\s+/g, '')}-${today.replace(/-/g, '')}`;
await page.goto(`/ru-ru/${slug}`);
await page.waitForLoadState('networkidle');
const seatInfo = page.locator('[data-testid="seat-info"]');
await expect(seatInfo).toBeVisible();
});
});
test.describe('Schedule Information', () => {
test('should display scheduled departure', async ({ page }) => {
const flight = generateFlight({ direction: 'departure', cityCode: 'MOW' });
const slug = `${flight.flightNumber.replace(/\s+/g, '')}-${today.replace(/-/g, '')}`;
await page.goto(`/ru-ru/${slug}`);
await page.waitForLoadState('networkidle');
const scheduledDep = page.locator('[data-testid="scheduled-departure"]');
await expect(scheduledDep).toBeVisible();
});
test('should display scheduled arrival', async ({ page }) => {
const flight = generateFlight({ direction: 'departure', cityCode: 'MOW' });
const slug = `${flight.flightNumber.replace(/\s+/g, '')}-${today.replace(/-/g, '')}`;
await page.goto(`/ru-ru/${slug}`);
await page.waitForLoadState('networkidle');
const scheduledArr = page.locator('[data-testid="scheduled-arrival"]');
await expect(scheduledArr).toBeVisible();
});
test('should display actual departure when available', async ({ page }) => {
const flight = generateFlight({
direction: 'departure',
cityCode: 'MOW',
status: 'departed',
});
const slug = `${flight.flightNumber.replace(/\s+/g, '')}-${today.replace(/-/g, '')}`;
await page.goto(`/ru-ru/${slug}`);
await page.waitForLoadState('networkidle');
const actualDep = page.locator('[data-testid="actual-departure"]');
await expect(actualDep).toBeVisible();
});
test('should display actual arrival when available', async ({ page }) => {
const flight = generateFlight({
direction: 'arrival',
cityCode: 'MOW',
status: 'arrived',
});
const slug = `${flight.flightNumber.replace(/\s+/g, '')}-${today.replace(/-/g, '')}`;
await page.goto(`/ru-ru/${slug}`);
await page.waitForLoadState('networkidle');
const actualArr = page.locator('[data-testid="actual-arrival"]');
await expect(actualArr).toBeVisible();
});
test('should display expected arrival when delayed', async ({ page }) => {
const flight = generateFlight({
direction: 'arrival',
cityCode: 'MOW',
status: 'delayed',
});
const slug = `${flight.flightNumber.replace(/\s+/g, '')}-${today.replace(/-/g, '')}`;
await page.goto(`/ru-ru/${slug}`);
await page.waitForLoadState('networkidle');
const expectedArr = page.locator('[data-testid="expected-arrival"]');
await expect(expectedArr).toBeVisible();
});
});
test.describe('Error Handling', () => {
test('should handle invalid flight number', async ({ page }) => {
await page.goto(`/ru-ru/SU9999-${today.replace(/-/g, '')}`);
await page.waitForLoadState('networkidle');
const errorState = page.locator('[data-testid="error-state"]');
await expect(errorState).toBeVisible();
});
test('should handle flight not found', async ({ page }) => {
await page.goto(`/ru-ru/SU9999-20260406`);
await page.waitForLoadState('networkidle');
const notFound = page.locator('[data-testid="not-found"]');
await expect(notFound).toBeVisible();
});
test('should handle network error', async ({ page }) => {
await page.route('**/api/flights/**', (route) => {
return route.abort('internetdisconnected');
});
const flight = generateFlight({ direction: 'departure', cityCode: 'MOW' });
const slug = `${flight.flightNumber.replace(/\s+/g, '')}-${today.replace(/-/g, '')}`;
await page.goto(`/ru-ru/${slug}`);
await page.waitForLoadState('networkidle');
const networkError = page.locator('[data-testid="network-error"]');
await expect(networkError).toBeVisible();
});
});
test.describe('Navigation', () => {
test('should navigate back to board', async ({ page }) => {
const flight = generateFlight({ direction: 'departure', cityCode: 'MOW' });
const slug = `${flight.flightNumber.replace(/\s+/g, '')}-${today.replace(/-/g, '')}`;
await page.goto(`/ru-ru/${slug}`);
await page.waitForLoadState('networkidle');
const backLink = page.locator('[data-testid="back-link"]');
await backLink.click();
await expect(page).toHaveURL(/onlineboard\/departure\/MOW-\d{8}/);
});
test('should navigate to related flights', async ({ page }) => {
const flight = generateFlight({ direction: 'departure', cityCode: 'MOW' });
const slug = `${flight.flightNumber.replace(/\s+/g, '')}-${today.replace(/-/g, '')}`;
await page.goto(`/ru-ru/${slug}`);
await page.waitForLoadState('networkidle');
const relatedFlights = page.locator('[data-testid="related-flights"]');
await expect(relatedFlights).toBeVisible();
});
});
test.describe('Accessibility', () => {
test('should have proper ARIA labels', async ({ page }) => {
const flight = generateFlight({ direction: 'departure', cityCode: 'MOW' });
const slug = `${flight.flightNumber.replace(/\s+/g, '')}-${today.replace(/-/g, '')}`;
await page.goto(`/ru-ru/${slug}`);
await page.waitForLoadState('networkidle');
const pageContent = page.locator('[data-testid="page-content"]');
await expect(pageContent).toHaveAttribute('role', 'main');
});
test('should be keyboard navigable', async ({ page }) => {
const flight = generateFlight({ direction: 'departure', cityCode: 'MOW' });
const slug = `${flight.flightNumber.replace(/\s+/g, '')}-${today.replace(/-/g, '')}`;
await page.goto(`/ru-ru/${slug}`);
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();
});
});
});