mirror of
https://github.com/Sea-Haven-Industries/proposal-system.git
synced 2026-09-30 15:53:15 +00:00
132 lines
4.1 KiB
JavaScript
132 lines
4.1 KiB
JavaScript
|
|
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); });
|