proposal-system/scripts/screenshot-pages.mjs

132 lines
4.1 KiB
JavaScript
Raw Normal View History

import puppeteer from 'puppeteer';
const BASE = 'http://localhost:5173';
const OUT = process.env.HOME + '/Desktop/proposal-system-screenshots';
const ROLES = [
{ label: 'SysAdmin', prefix: 'sysadmin', isAdmin: true, isSysAdmin: true },
{ label: 'Admin', prefix: 'admin', isAdmin: true, isSysAdmin: false },
{ label: 'Dispatcher', prefix: 'dispatcher', isAdmin: false, isSysAdmin: false },
];
async function wait(ms) { return new Promise(r => setTimeout(r, ms)); }
async function screenshot(page, name) {
await wait(1500);
await page.screenshot({ path: `${OUT}/${name}.png`, fullPage: true });
console.log(` captured ${name}.png`);
}
async function getToken(page) {
return page.evaluate(() => {
const raw = localStorage.getItem('proposal_system_token');
if (!raw) return null;
try {
const parsed = JSON.parse(raw);
return parsed?.token ?? null;
} catch { return null; }
});
}
async function fetchProposalId(page) {
const token = await getToken(page);
if (!token) return null;
return page.evaluate(async (t) => {
try {
const r = await fetch('/api/proposals?page=1&pageSize=1', {
headers: { 'Authorization': `Bearer ${t}` },
});
if (!r.ok) return null;
const data = await r.json();
return data.items?.[0]?.id ?? null;
} catch { return null; }
}, token);
}
async function run() {
const browser = await puppeteer.launch({
headless: true,
defaultViewport: { width: 1440, height: 900 },
});
for (const role of ROLES) {
console.log(`\n--- ${role.prefix} ---`);
const context = await browser.createBrowserContext();
const page = await context.newPage();
// Login page
await page.goto(BASE + '/login', { waitUntil: 'networkidle2' });
await screenshot(page, `${role.prefix}-01-login`);
// Click the role button
const buttons = await page.$$('button');
let clicked = false;
for (const b of buttons) {
const text = await b.evaluate(el => el.textContent.trim());
if (text.startsWith(role.label)) {
await b.click();
clicked = true;
break;
}
}
if (!clicked) {
console.log(` ERROR: could not find button "${role.label}"`);
await context.close();
continue;
}
await page.waitForNavigation({ waitUntil: 'networkidle2', timeout: 10000 }).catch(() => {});
await wait(1000);
// Dashboard
await screenshot(page, `${role.prefix}-02-dashboard`);
// My Proposals list
await page.goto(BASE + '/proposals', { waitUntil: 'networkidle2' });
await screenshot(page, `${role.prefix}-03-proposals-list`);
// New Proposal form
await page.goto(BASE + '/proposals/new', { waitUntil: 'networkidle2' });
await screenshot(page, `${role.prefix}-04-new-proposal`);
// Detail page
const proposalId = await fetchProposalId(page);
if (proposalId) {
await page.goto(BASE + `/proposals/${proposalId}`, { waitUntil: 'networkidle2' });
await screenshot(page, `${role.prefix}-05-proposal-detail`);
} else {
console.log(' no proposals found, skipping detail');
}
if (role.isAdmin) {
await page.goto(BASE + '/admin', { waitUntil: 'networkidle2' });
await screenshot(page, `${role.prefix}-06-admin-queue`);
await page.goto(BASE + '/admin/proposals', { waitUntil: 'networkidle2' });
await screenshot(page, `${role.prefix}-07-admin-all-proposals`);
const workspaceId = proposalId ?? await fetchProposalId(page);
if (workspaceId) {
await page.goto(BASE + `/admin/proposals/${workspaceId}`, { waitUntil: 'networkidle2' });
await wait(2000);
await screenshot(page, `${role.prefix}-08-admin-workspace`);
} else {
console.log(' no proposals for workspace');
}
if (role.isSysAdmin) {
await page.goto(BASE + '/admin/users', { waitUntil: 'networkidle2' });
await screenshot(page, `${role.prefix}-09-user-management`);
}
}
await context.close();
}
await browser.close();
console.log(`\nDone — screenshots in ${OUT}`);
}
run().catch(e => { console.error(e); process.exit(1); });