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>
67 lines
2.4 KiB
TypeScript
67 lines
2.4 KiB
TypeScript
/**
|
|
* The console is built to work at phone width. These checks guard the layout
|
|
* rules that make that true -- chiefly that nothing forces a horizontal scroll.
|
|
*/
|
|
import { expect, test } from '../fixtures/test';
|
|
import { SKYLINE_AGENT } from '../fixtures/accounts';
|
|
|
|
/** True when the document is wider than the viewport. */
|
|
async function scrollsSideways(page: import('@playwright/test').Page): Promise<boolean> {
|
|
return page.evaluate(() => document.documentElement.scrollWidth > window.innerWidth + 1);
|
|
}
|
|
|
|
test.describe('Layout', () => {
|
|
test('the sign-in screen fits without sideways scrolling', async ({ page, login }) => {
|
|
await page.setViewportSize({ width: 390, height: 844 });
|
|
await login.goto();
|
|
|
|
expect(await scrollsSideways(page)).toBe(false);
|
|
// The decorative panel is hidden rather than squeezed.
|
|
await expect(page.locator('.hero')).toBeHidden();
|
|
await expect(login.submit).toBeVisible();
|
|
});
|
|
|
|
test('the console screens fit at phone width', async ({ page, signInAs, shell, search }) => {
|
|
await page.setViewportSize({ width: 390, height: 844 });
|
|
await signInAs(SKYLINE_AGENT);
|
|
|
|
expect(await scrollsSideways(page)).toBe(false);
|
|
|
|
await shell.goToSearch();
|
|
await search.settled();
|
|
expect(await scrollsSideways(page)).toBe(false);
|
|
await expect(search.results.first()).toBeVisible();
|
|
|
|
await shell.goToBookings();
|
|
expect(await scrollsSideways(page)).toBe(false);
|
|
});
|
|
|
|
test('wide tables scroll inside their own container', async ({ page, signInAs, shell }) => {
|
|
await page.setViewportSize({ width: 390, height: 844 });
|
|
await signInAs(SKYLINE_AGENT);
|
|
await shell.goToBookings();
|
|
|
|
const wrapper = page.locator('.table-wrap').first();
|
|
await expect(wrapper).toBeVisible();
|
|
|
|
// The table may overflow; the page must not.
|
|
expect(await scrollsSideways(page)).toBe(false);
|
|
});
|
|
|
|
test('the sidebar collapses into a top bar on narrow screens', async ({ page, signInAs }) => {
|
|
await page.setViewportSize({ width: 390, height: 844 });
|
|
await signInAs(SKYLINE_AGENT);
|
|
|
|
const sidebar = page.locator('.sidebar');
|
|
const content = page.locator('.content');
|
|
|
|
const sidebarBox = await sidebar.boundingBox();
|
|
const contentBox = await content.boundingBox();
|
|
|
|
expect(sidebarBox).not.toBeNull();
|
|
expect(contentBox).not.toBeNull();
|
|
// Stacked, not side by side.
|
|
expect(contentBox!.y).toBeGreaterThan(sidebarBox!.y);
|
|
});
|
|
});
|