{ "generatedAt": "2026-10-10T09:15:03.203Z", "baseUrl": "http://localhost:4200", "auth": { "type": "basic", "tenantHeader": "X-Tenant", "note": "Credentials verified within the named tenant; take accounts from e2e/fixtures/accounts.ts, never hardcode.", "accounts": [ { "name": "SKYLINE_AGENT", "email": "agent@skyline.test", "tenant": "skyline", "role": "agent" }, { "name": "SKYLINE_ADMIN", "email": "admin@skyline.test", "tenant": "skyline", "role": "admin" }, { "name": "GLOBETROTTER_AGENT", "email": "agent@globetrotter.test", "tenant": "globetrotter", "role": "agent" }, { "name": "GLOBETROTTER_ADMIN", "email": "admin@globetrotter.test", "tenant": "globetrotter", "role": "admin" } ] }, "routes": [ "/login", "/dashboard", "/search", "/book/:flightId", "/bookings", "/bookings/:bookingId" ], "areas": [ { "spec": "auth.spec.ts", "title": "Signing in and sessions" }, { "spec": "search.spec.ts", "title": "Searching for flights" }, { "spec": "booking.spec.ts", "title": "Booking and cancelling" }, { "spec": "tenant-isolation.spec.ts", "title": "Keeping agencies separate" }, { "spec": "dashboard.spec.ts", "title": "Agency dashboard" }, { "spec": "simulation.spec.ts", "title": "Behaviour when things go wrong" }, { "spec": "responsive.spec.ts", "title": "Phones and small screens" } ], "api": [ { "method": "GET", "path": "/api/session", "auth": true }, { "method": "GET", "path": "/api/flights", "auth": true }, { "method": "GET", "path": "/api/flights/{id}", "auth": true }, { "method": "GET", "path": "/api/airports", "auth": true }, { "method": "GET", "path": "/api/airlines", "auth": true }, { "method": "GET", "path": "/api/bookings", "auth": true }, { "method": "POST", "path": "/api/bookings", "auth": true }, { "method": "GET", "path": "/api/bookings/{id}", "auth": true }, { "method": "POST", "path": "/api/bookings/{id}/cancel", "auth": true }, { "method": "GET", "path": "/api/dashboard", "auth": true }, { "method": "GET", "path": "/api/health", "auth": false }, { "method": "GET", "path": "/api/tenants", "auth": false } ], "pageObjects": [ { "file": "e2e/pages/bookings.page.ts", "classes": [ "BookingsPage", "BookingDetailPage" ], "locators": [ "rows", "emptyState", "filterAll", "filterConfirmed", "filterCancelled", "confirmationBanner", "reference", "statusBadge", "travellerRows", "totalPaid", "cancelButton", "confirmCancelButton", "keepButton", "cancelledNotice" ], "methods": [ "goto()", "settled()", "rowFor(reference: string)", "open(reference: string)", "filterBy(status: 'all' | 'confirmed' | 'cancelled')", "bookingReference()", "cancel(expectedReference: string)" ] }, { "file": "e2e/pages/checkout.page.ts", "classes": [ "CheckoutPage" ], "locators": [ "travellerFieldsets", "addTraveller", "contactEmail", "contactPhone", "confirm", "total", "error", "seatsLeft" ], "methods": [ "waitUntilReady()", "totalAmount()", "fillTraveller(index: number, traveller: Traveller)", "fillTravellers(travellers: Traveller[])", "removeTraveller(index: number)", "confirmBooking()" ] }, { "file": "e2e/pages/dashboard.page.ts", "classes": [ "DashboardPage" ], "locators": [ "greeting", "tiles", "recentRows", "topRoutes" ], "methods": [ "goto()", "settled()", "tileValue(label: string)" ] }, { "file": "e2e/pages/login.page.ts", "classes": [ "LoginPage" ], "locators": [ "tenantSelect", "email", "password", "submit", "error", "demoChips" ], "methods": [ "goto()", "useDemoChip(account: Account)", "fill(account: Account, password = account.password)", "signIn(account: Account)", "signInExpectingFailure(account: Account, password: string)" ] }, { "file": "e2e/pages/search.page.ts", "classes": [ "FlightCard", "SearchPage" ], "locators": [ "root", "origin", "destination", "date", "cabin", "travellers", "searchButton", "resetButton", "sort", "resultSummary", "results", "emptyState", "nextPage", "prevPage" ], "methods": [ "fare()", "seatsLeft()", "flightNumber()", "durationMinutes()", "goto()", "card(index = 0)", "settled()", "searchRoute(from: string, to: string)", "setTravellers(n: number)", "sortBy(value: 'price' | 'duration' | 'departure')", "totalResults()", "cardForFlight(flightNumber: string)" ] }, { "file": "e2e/pages/shell.page.ts", "classes": [ "ShellPage" ], "locators": [ "agencyName", "agencySlug", "accountName", "accountMeta", "signOut" ], "methods": [ "goToDashboard()", "goToSearch()", "goToBookings()", "signOutAndWait()" ] } ], "conventions": "e2e/CLAUDE.md" }