Files
flights_web/tests/e2e-angular/console-audit.spec.ts
T
gnezim 20c19d15f4
CI / ci (push) Failing after 23s
Deploy / build-and-deploy (push) Failing after 5s
Add standalone API proxy via curl (bypasses WAF TLS fingerprinting)
Modern.js SSR intercepts all routes before any Express middleware,
so the API proxy runs as a separate Express server on port 8080.
Modern.js runs on 8081. The proxy uses curl subprocesses which go
through the system HTTPS proxy (GOST) with a proper TLS fingerprint
that the Aeroflot WAF accepts.

Usage: node scripts/dev-server.mjs (replaces pnpm dev for full-stack)

Also: remove stray e2e-angular test directory, fix env default to
same-origin /api.
2026-04-15 23:04:24 +03:00

183 lines
5.4 KiB
TypeScript

import { test, expect } from '@playwright/test';
test.describe('Console Error-Free Audit (US-11)', () => {
let consoleMessages: Array<{ type: string; text: string }> = [];
test.beforeEach(async ({ page }) => {
consoleMessages = [];
// Capture console messages
page.on('console', (msg) => {
consoleMessages.push({
type: msg.type(),
text: msg.text(),
});
});
// Capture page errors
page.on('pageerror', (error) => {
consoleMessages.push({
type: 'error',
text: error.toString(),
});
});
});
test('online board page should be error-free', async ({ page }) => {
await page.goto('http://localhost:3002/ru-ru/onlineboard');
await page.waitForLoadState('networkidle');
// Perform interactions
const flightTab = page.locator('[data-testid="search-tab-flight"]');
if ((await flightTab.count()) > 0) {
await flightTab.click();
await page.waitForTimeout(500);
}
const routeTab = page.locator('[data-testid="search-tab-route"]');
if ((await routeTab.count()) > 0) {
await routeTab.click();
await page.waitForTimeout(500);
}
// Check for errors
const errors = consoleMessages.filter((m) => m.type === 'error');
expect(errors).toEqual([]);
});
test('schedule page should be error-free', async ({ page }) => {
await page.goto('http://localhost:3002/ru-ru/schedule');
await page.waitForLoadState('networkidle');
// Check for errors
const errors = consoleMessages.filter((m) => m.type === 'error');
expect(errors).toEqual([]);
});
test('flights map page should be error-free', async ({ page }) => {
await page.goto('http://localhost:3002/ru-ru/flights-map');
await page.waitForLoadState('networkidle');
// Check for errors
const errors = consoleMessages.filter((m) => m.type === 'error');
expect(errors).toEqual([]);
});
test('language switching should not cause errors', async ({ page }) => {
await page.goto('http://localhost:3002/ru-ru/onlineboard');
await page.waitForLoadState('networkidle');
// Try to switch languages
const localeEn = page.locator('[data-testid="locale-en-us"]');
if ((await localeEn.count()) > 0) {
await localeEn.click();
await page.waitForLoadState('networkidle');
}
const localeRu = page.locator('[data-testid="locale-ru-ru"]');
if ((await localeRu.count()) > 0) {
await localeRu.click();
await page.waitForLoadState('networkidle');
}
// Check for errors
const errors = consoleMessages.filter((m) => m.type === 'error');
expect(errors).toEqual([]);
});
test('tab navigation should not cause errors', async ({ page }) => {
await page.goto('http://localhost:3002/ru-ru/onlineboard');
await page.waitForLoadState('networkidle');
const tabs = [
page.locator('[data-testid="tab-onlineboard"]'),
page.locator('[data-testid="tab-schedule"]'),
page.locator('[data-testid="tab-map"]'),
];
for (const tab of tabs) {
if ((await tab.count()) > 0) {
await tab.click();
await page.waitForLoadState('networkidle');
}
}
// Check for errors
const errors = consoleMessages.filter((m) => m.type === 'error');
expect(errors).toEqual([]);
});
test('scroll interactions should not cause errors', async ({ page }) => {
await page.goto('http://localhost:3002/ru-ru/onlineboard');
await page.waitForLoadState('networkidle');
// Scroll down
await page.evaluate(() => window.scrollBy(0, 500));
await page.waitForTimeout(300);
// Scroll up
await page.evaluate(() => window.scrollTo(0, 0));
await page.waitForTimeout(300);
// Check for errors
const errors = consoleMessages.filter((m) => m.type === 'error');
expect(errors).toEqual([]);
});
test('should have no JavaScript errors during full user flow', async ({ page }) => {
const errors: string[] = [];
page.on('console', (msg) => {
if (msg.type() === 'error') {
errors.push(msg.text());
}
});
page.on('pageerror', (error) => {
errors.push(error.toString());
});
// Online Board flow
await page.goto('http://localhost:3002/ru-ru/onlineboard');
await page.waitForLoadState('networkidle');
const flightInput = page.locator('[data-testid="search-flight-number"]');
if ((await flightInput.count()) > 0) {
await flightInput.fill('SU1402');
await page.waitForTimeout(500);
}
// Schedule flow
const scheduleTab = page.locator('[data-testid="tab-schedule"]');
if ((await scheduleTab.count()) > 0) {
await scheduleTab.click();
await page.waitForLoadState('networkidle');
await page.waitForTimeout(500);
}
// Map flow (if available)
const mapTab = page.locator('[data-testid="tab-map"]');
if ((await mapTab.count()) > 0) {
await mapTab.click();
await page.waitForLoadState('networkidle');
}
// Language switch
const localeEn = page.locator('[data-testid="locale-en-us"]');
if ((await localeEn.count()) > 0) {
await localeEn.click();
await page.waitForLoadState('networkidle');
}
// Back to Russian
const localeRu = page.locator('[data-testid="locale-ru-ru"]');
if ((await localeRu.count()) > 0) {
await localeRu.click();
await page.waitForLoadState('networkidle');
}
// Final check
expect(errors).toEqual([]);
});
});