more fixes
This commit is contained in:
95
tests/cpad/navigation-discovery.spec.ts
Normal file
95
tests/cpad/navigation-discovery.spec.ts
Normal file
@@ -0,0 +1,95 @@
|
||||
/**
|
||||
* Navigation Discovery — scans the cPad sidebar and collects all /cp links.
|
||||
*
|
||||
* This test acts as both:
|
||||
* 1. A standalone spec that validates the nav scan returns ≥ 1 link.
|
||||
* 2. A data producer: it writes the discovered URLs to
|
||||
* tests/.discovered/cpad-links.json so that navigation.spec.ts can
|
||||
* consume them dynamically.
|
||||
*
|
||||
* Ignored links:
|
||||
* • /cp/logout
|
||||
* • javascript:void / # anchors
|
||||
* • External URLs (not starting with /cp)
|
||||
*
|
||||
* Run:
|
||||
* npx playwright test tests/cpad/navigation-discovery.spec.ts --project=cpad
|
||||
*/
|
||||
|
||||
import { test, expect } from '@playwright/test';
|
||||
import { DASHBOARD_PATH, CP_PATH } from '../helpers/auth';
|
||||
import fs from 'fs';
|
||||
import path from 'path';
|
||||
|
||||
const DISCOVERED_DIR = path.join('tests', '.discovered');
|
||||
const DISCOVERED_FILE = path.join(DISCOVERED_DIR, 'cpad-links.json');
|
||||
|
||||
// ─────────────────────────────────────────────────────────────────────────────
|
||||
// Helpers
|
||||
// ─────────────────────────────────────────────────────────────────────────────
|
||||
|
||||
/** Returns true if the href should be included in navigation tests */
|
||||
function isNavigableLink(href: string | null): boolean {
|
||||
if (!href) return false;
|
||||
if (!href.startsWith(CP_PATH)) return false;
|
||||
if (href.includes('/logout')) return false;
|
||||
if (href.startsWith('javascript:')) return false;
|
||||
if (href === CP_PATH || href === CP_PATH + '/') return false; // exclude root (same as dashboard)
|
||||
return true;
|
||||
}
|
||||
|
||||
/** Remove query strings and anchors for clean deduplication */
|
||||
function normalise(href: string): string {
|
||||
try {
|
||||
const u = new URL(href, 'http://placeholder');
|
||||
return u.pathname;
|
||||
} catch {
|
||||
return href.split('?')[0].split('#')[0];
|
||||
}
|
||||
}
|
||||
|
||||
// ─────────────────────────────────────────────────────────────────────────────
|
||||
// Discovery test
|
||||
// ─────────────────────────────────────────────────────────────────────────────
|
||||
|
||||
test.describe('cPad Navigation Discovery', () => {
|
||||
test('scan sidebar and collect all /cp navigation links', async ({ page }) => {
|
||||
await page.goto(DASHBOARD_PATH);
|
||||
await page.waitForLoadState('networkidle');
|
||||
|
||||
// Ensure we're not on the login page
|
||||
expect(page.url()).not.toContain('/login');
|
||||
|
||||
// ── Widen the scan to cover lazy-loaded submenu items ──────────────────
|
||||
// Hover over sidebar nav items to expand hidden submenus
|
||||
const menuItems = page.locator('.nav-item, .sidebar-item, .menu-item, li.nav-item');
|
||||
const menuCount = await menuItems.count();
|
||||
for (let i = 0; i < Math.min(menuCount, 30); i++) {
|
||||
await menuItems.nth(i).hover().catch(() => null);
|
||||
}
|
||||
|
||||
// ── Collect all anchor hrefs ───────────────────────────────────────────
|
||||
const rawHrefs: string[] = await page.$$eval('a[href]', (anchors) =>
|
||||
anchors.map((a) => (a as HTMLAnchorElement).getAttribute('href') ?? ''),
|
||||
);
|
||||
|
||||
const discovered = [...new Set(
|
||||
rawHrefs
|
||||
.map((h) => normalise(h))
|
||||
.filter(isNavigableLink),
|
||||
)].sort();
|
||||
|
||||
console.log(`[discovery] Found ${discovered.length} navigable /cp links`);
|
||||
discovered.forEach((l) => console.log(' •', l));
|
||||
|
||||
// Must find at least a few links — if not, something is wrong with auth
|
||||
expect(discovered.length, 'Expected to find /cp navigation links').toBeGreaterThanOrEqual(1);
|
||||
|
||||
// ── Persist for navigation.spec.ts ────────────────────────────────────
|
||||
if (!fs.existsSync(DISCOVERED_DIR)) {
|
||||
fs.mkdirSync(DISCOVERED_DIR, { recursive: true });
|
||||
}
|
||||
fs.writeFileSync(DISCOVERED_FILE, JSON.stringify(discovered, null, 2), 'utf8');
|
||||
console.log(`[discovery] Links saved to ${DISCOVERED_FILE}`);
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user