godcrm/scripts/shot-table.mjs
GOD CRM Release f89e074dd1
Some checks failed
CI / Lint / Typecheck / Test / Build (push) Has been cancelled
CI / PostgreSQL Integration Tests (push) Has been cancelled
GOD CRM — public scrubbed snapshot
Governed substrate for autonomous agents: scoped identity (passports),
audited actions, MCP workspace. Infra IPs and secrets redacted for public release.
2026-08-10 04:01:45 +03:00

84 lines
2.8 KiB
JavaScript

#!/usr/bin/env node
/**
* Authenticated screenshot of a UniversalTable page.
* Mints a JWT for the given USER_ID using JWT_SECRET from .env,
* injects it into localStorage('god-crm-auth'), and screenshots the
* resulting /tables/<id> view.
*
* node scripts/shot-table.mjs # default: table 1708
* SHOT_TABLE=1784 node scripts/shot-table.mjs
*/
import 'dotenv/config';
import jwt from 'jsonwebtoken';
import { chromium } from 'playwright';
const BASE = process.env.SHOT_BASE || 'https://crm.hltrn.cc';
const TABLE = process.env.SHOT_TABLE || '1708';
const USER_ID = Number(process.env.SHOT_USER || 1);
const USER_EMAIL = process.env.SHOT_EMAIL || 'geramonnn@gmail.com';
const OUT = process.env.SHOT_OUT || '/tmp/table-state.png';
const VW = Number(process.env.SHOT_VW || 1600);
const VH = Number(process.env.SHOT_VH || 900);
const SECRET = process.env.JWT_SECRET;
if (!SECRET) {
console.error('JWT_SECRET not in env');
process.exit(1);
}
const token = jwt.sign(
{ id: USER_ID, userId: USER_ID, email: USER_EMAIL, role: 'admin' },
SECRET,
{ expiresIn: '10m' }
);
const browser = await chromium.launch({ headless: true });
const ctx = await browser.newContext({ viewport: { width: VW, height: VH } });
const page = await ctx.newPage();
page.on('console', (m) => {
if (m.type() === 'error') console.error('[console]', m.text().slice(0, 200));
});
// Prime localStorage on the target origin BEFORE every navigation so the
// app boots already authenticated. addInitScript runs in every new page
// before any user script, including on the first goto.
const persisted = JSON.stringify({
state: { token, user: { id: USER_ID, email: USER_EMAIL, role: 'admin' } },
version: 0,
});
await ctx.addInitScript(`window.localStorage.setItem('god-crm-auth', ${JSON.stringify(persisted)});`);
await page.goto(`${BASE}/tables/${TABLE}`, { waitUntil: 'networkidle', timeout: 30_000 });
await page
.locator('table, [role="grid"]')
.first()
.waitFor({ timeout: 15_000 })
.catch(() => {});
await page.waitForTimeout(1500);
await page.screenshot({ path: OUT, fullPage: false });
const info = await page.evaluate(() => {
const tables = [...document.querySelectorAll('table')];
return tables.map((t, i) => {
const tr = t.getBoundingClientRect();
const ths = [...t.querySelectorAll('thead th')].map((th) => ({
text: (th.innerText || '').trim().slice(0, 28),
w: Math.round(th.getBoundingClientRect().width),
}));
let p = t.parentElement;
while (p && getComputedStyle(p).overflowX === 'visible') p = p.parentElement;
return {
idx: i,
tableW: Math.round(tr.width),
containerW: p ? Math.round(p.getBoundingClientRect().width) : null,
ths,
};
});
});
console.log(JSON.stringify(info, null, 2));
console.log('url=', page.url());
console.log('screenshot=', OUT);
await browser.close();