Add Angular→React comparison pipeline design spec
CI / ci (push) Failing after 27s
Deploy / build-and-deploy (push) Failing after 5s

Defines a Playwright-based pipeline for visual screenshot diffing,
behavioral E2E verification, and gap analysis between the Angular
and React implementations. Documents known gaps in flight details,
popular requests logic, and flights map.
This commit is contained in:
2026-04-16 17:25:48 +03:00
parent 8f974c2d07
commit 1fc1880644
@@ -0,0 +1,163 @@
# Angular → React Comparison Pipeline
## Goal
Verify the React rewrite is a pixel-perfect copy of the Angular app (with design-system component exceptions) and that all business logic and features work identically.
## Comparison Standard
- **Pixel-perfect match** is the goal for all UI elements.
- **Exception:** Where React uses PrimeReact (design system) instead of Angular's PrimeNG/custom components, slight inherent visual differences from those library components are acceptable.
- Any other visual difference is a bug.
## Approach
Hybrid: Playwright automated screenshot pipeline for visual diffing + automated behavioral specs for logic verification + manual review for nuanced gaps.
## Architecture
### Layer 1 — Visual Screenshot Diffing
Playwright navigates both apps through every route. Each route captured at 3 viewports:
| Viewport | Width |
|----------|-------|
| Desktop | 1440px |
| Tablet | 768px |
| Mobile | 375px |
Dynamic content (times, dates, live status) is masked or frozen via CSS injection before capture. `pixelmatch` generates diff images. Output is an interactive HTML report with side-by-side Angular / React / Diff columns for each route+viewport.
### Layer 2 — Behavioral Spec Tests
Playwright E2E specs run identical interactions on both apps and assert matching outcomes:
- Search flows (enter criteria → submit → verify results)
- Filter interactions (toggle → verify update)
- Popular requests click (verify destination page filter state pre-fill)
- Navigation (tabs, breadcrumbs, back buttons, search history)
- Calendar/date navigation on result pages
- Live updates (Angular polling vs React SignalR)
Each spec produces pass/fail with screenshots on failure.
### Layer 3 — Gap Report Generator
Script crawls both apps' route trees and compares:
- DOM element counts per section (sidebar, accordion panels, detail rows)
- Missing sections flagged automatically
- API calls per page (network intercept comparison)
Output: Markdown gap report listing every missing feature per page.
### Output Structure
```
comparison-report/
├── visual/
│ ├── screenshots/angular/
│ ├── screenshots/react/
│ ├── diffs/
│ └── report.html
├── behavioral/
│ ├── specs/
│ └── results/
└── gaps/
└── gap-report.md
```
## Route Matrix
### Feature Routes
| Route | Angular Component | React Component | Visual | Logic | Known Status |
|-------|-------------------|-----------------|--------|-------|-------------|
| `/onlineboard` | OnlineBoardStartPage | OnlineBoardStartPage | Check | Check | Implemented |
| `/onlineboard/flight/:p` | FlightNumberSearchPage | OnlineBoardSearchPage (merged) | Check | Check | Implemented |
| `/onlineboard/departure/:p` | DepartureSearchPage | OnlineBoardSearchPage (merged) | Check | Check | Implemented |
| `/onlineboard/arrival/:p` | ArrivalSearchPage | OnlineBoardSearchPage (merged) | Check | Check | Implemented |
| `/onlineboard/route/:p` | RouteSearchPage | OnlineBoardSearchPage (merged) | Check | Check | Implemented |
| `/onlineboard/:p` (details) | OnlineBoardFlightDetailsPage | OnlineBoardDetailsPage | **Incomplete** | **Incomplete** | Skeleton only |
| `/schedule` | ScheduleStartPage | ScheduleStartPage | Check | Check | Implemented |
| `/schedule/route/:p` | ScheduleSearchPage | ScheduleSearchPage | Check | Check | Implemented |
| `/schedule/route/:p/:ret` | ScheduleSearchPage | ScheduleSearchPage | Check | Check | Implemented |
| `/schedule/details (splat)` | ScheduleFlightDetailsPage | ScheduleDetailsPage | **Incomplete** | **Incomplete** | Skeleton only |
| `/flights-map` | FlightsMapStartPage | FlightsMapStartPage | **Broken** | **Broken** | Non-functional |
| `/error/404` | ErrorPage | ErrorPage | Check | Check | Implemented |
| `/error/500` | ErrorPage | ErrorPage | Check | Check | Implemented |
### Cross-Cutting Behavioral Specs
1. **Popular requests click** — Click each type, verify destination filter state is pre-filled. Known gap: React navigates without setting filter state.
2. **Search history** — Perform search → verify in history → click → verify navigation.
3. **Page tabs** — Click each tab, verify navigation.
4. **Breadcrumbs** — Verify trail, click parent, verify navigation.
5. **Scroll-up button** — Scroll → button appears → click → scroll position reset.
6. **Language switching** — Navigate with `ru`, `en` params, verify translations load.
7. **Responsive layout** — Resize viewport, verify layout adapts consistently.
## Known Gaps (Pre-Comparison)
### Flight Details Pages — Skeleton Only
Both Online Board and Schedule details pages are missing:
- Related flights mini-list sidebar
- Date navigation tabs
- Expandable accordion (registration, boarding, deboarding, aircraft, meals, on-board services)
- Flight timeline/schedule view
- Transfer section details between legs
- Operator logo, event alerts, last update timestamp
- Back button, flight action buttons
### Popular Requests — Logic Mismatch
Renders similarly but behaves differently:
- Angular pre-fills destination page filters on click; React just navigates (forms stay empty)
- Angular clears existing filters before applying new values; React has no filter state management
- Angular has mobile location-aware time range defaults; React doesn't
### Flights Map — Non-Functional
Map loads but shows nothing:
- Markers and polylines are hardcoded empty arrays
- No city/airport dictionary data loaded
- Fetched routes never converted to map geometry
- No spider diagram fallback, no connection retry, no zoom-level marker visibility
- Filter checkboxes exist but filtering never applied
- Popups and "Buy Ticket" links not wired
## Component Mapping
### Shared UI
| Angular Component(s) | React Equivalent | Notes |
|-----------------------|------------------|-------|
| PageLayoutComponent | PageLayout | Two-column layout wrapper |
| FlightsPageTabsComponent | PageTabs | Tab navigation |
| BreadcrumbsComponent | Breadcrumbs | Navigation trail |
| SearchHistoryComponent | SearchHistory | Recent searches accordion |
| FeedbackButtonComponent | FeedbackButton | Feedback form trigger |
| ScrollUpComponent | ScrollUpButton | Scroll-to-top |
| FlightItemComponent + 15 sub-components | FlightCard + StationDisplay, TimeGroup, DurationDisplay, FlightStatus | Consolidated |
| PopularRequestsComponent + items | PopularRequestsPanel + PopularRequestItem + RequestInfo | 1:1 structure |
| FlightsMapComponent + markers/polylines | MapCanvas (Leaflet wrapper) | All map logic in single component |
| CityAutocompleteComponent | PrimeReact AutoComplete (inline) | Design system swap |
| Calendar/DatePicker toolkit | PrimeReact Calendar (inline) | Design system swap |
| SeoMetaComponent | SeoHead | SEO metadata (OG, JSON-LD) |
## Test Data
- Both apps hit the same backend API.
- Fix a known flight number + date that returns stable results for deterministic comparisons.
- Parameterize dates so tests stay valid over time.
## Tech Stack
- **Playwright** — browser automation, screenshots, E2E specs
- **pixelmatch** — pixel-level image diffing
- **Node.js script** — report generation, gap analysis
- Output: static HTML report + Markdown gap report