Angular + Go + PostgreSQL sample with strict per-tenant isolation. - Backend: Go API (basic auth, tenant-scoped repository layer, pgx pool) - Frontend: Angular 22 SPA (search, checkout, bookings, dashboard) - Database: schema, seed data and demo bookings migrations - Tests: 311 across Go (integration), Angular (unit) and Playwright (e2e), plus a generated evidence report with PDF export - Security: whitebox VAPT report under security/ Secrets (.env, tokens, DB credentials) are git-ignored. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
44 lines
1.4 KiB
TypeScript
44 lines
1.4 KiB
TypeScript
import { Locator, Page } from '@playwright/test';
|
|
|
|
/** The signed-in chrome: sidebar navigation and the account bar. */
|
|
export class ShellPage {
|
|
readonly agencyName: Locator;
|
|
readonly agencySlug: Locator;
|
|
readonly accountName: Locator;
|
|
readonly accountMeta: Locator;
|
|
readonly signOut: Locator;
|
|
|
|
constructor(private readonly page: Page) {
|
|
this.agencyName = page.locator('.tenant-name');
|
|
this.agencySlug = page.locator('.tenant-slug');
|
|
this.accountName = page.locator('.account-name');
|
|
this.accountMeta = page.locator('.account-meta');
|
|
this.signOut = page.getByRole('button', { name: 'Sign out' });
|
|
}
|
|
|
|
/**
|
|
* Navigates by sidebar link. The href selector is deliberate: several screens
|
|
* also carry a "Search flights" call-to-action button, and matching by role
|
|
* and name alone would be ambiguous.
|
|
*/
|
|
async goToDashboard(): Promise<void> {
|
|
await this.page.locator('.nav-link[href="/dashboard"]').click();
|
|
await this.page.waitForURL('**/dashboard');
|
|
}
|
|
|
|
async goToSearch(): Promise<void> {
|
|
await this.page.locator('.nav-link[href="/search"]').click();
|
|
await this.page.waitForURL('**/search');
|
|
}
|
|
|
|
async goToBookings(): Promise<void> {
|
|
await this.page.locator('.nav-link[href="/bookings"]').click();
|
|
await this.page.waitForURL('**/bookings');
|
|
}
|
|
|
|
async signOutAndWait(): Promise<void> {
|
|
await this.signOut.click();
|
|
await this.page.waitForURL('**/login');
|
|
}
|
|
}
|