/**
* Guarded consultation-only Form A browser regression.
* Run after a normal live build. Every Jotform request is
* fulfilled or aborted locally; no Jotform request is transmitted.
*/
import { randomBytes } from 'node:crypto';
import { encryptPortalStream, portalAlgorithm } from '../src/utils/portal-crypto.mjs';
import assert from 'node:assert/strict';
import fs from 'node:fs/promises';
import http from 'node:http';
import net from 'node:net';
import path from 'node:path';
import { spawn } from 'node:child_process';
import { fileURLToPath, pathToFileURL } from 'node:url';
import { setTimeout as delay } from 'node:timers/promises';
const forms = process.argv.find(a => a.startsWith('--forms='))?.split('=')[1] ?? 'live';
assert.ok(['live', 'off', 'mock'].includes(forms));
const browserName = process.argv.find(a => a.startsWith('--browser='))?.split('=')[1] ?? 'chromium';
assert.ok(['chromium', 'firefox'].includes(browserName));
const root = fileURLToPath(new URL('../', import.meta.url));
const moduleName = process.env.PLAYWRIGHT_MODULE
? pathToFileURL(path.resolve(process.env.PLAYWRIGHT_MODULE)).href
: 'playwright';
const output = await fs.mkdtemp('/tmp/aia-service-portal-');
const routes = [
{ route: '/client-consultation', locale: 'en', drawer: false, screenshot: 'client-consultation' },
{ route: '/es/client-consultation', locale: 'es', drawer: false, screenshot: 'es-client-consultation' },
{ route: '/schedule-consultation', locale: 'en', drawer: false, screenshot: 'schedule-consultation' },
{ route: '/aba-therapy', locale: 'en', drawer: true, screenshot: 'aba-therapy' },
{ route: '/autism-evaluations', locale: 'en', drawer: true, screenshot: 'autism-evaluations' },
{ route: '/learner-social-club', locale: 'en', drawer: true, screenshot: 'learner-social-club' },
{ route: '/es/aba-therapy', locale: 'es', drawer: true, screenshot: 'es-aba-therapy' },
{ route: '/es/autism-evaluations', locale: 'es', drawer: true, screenshot: 'es-autism-evaluations' },
{ route: '/es/learner-social-club', locale: 'es', drawer: true, screenshot: 'es-learner-social-club' },
];
const widths = [320, 390, 768, 1440];
const evidence = { forms, browserName, routes, widths, checks: 0, blocked: [], jotformAttempts: [], resourceRequests: [], screenshots: [], fallbackChecks: [], status: 'failed' };
const reserve = net.createServer();
await new Promise((resolve, reject) => { reserve.once('error', reject); reserve.listen(0, '127.0.0.1', resolve); });
const port = reserve.address().port;
await new Promise((resolve) => reserve.close(resolve));
const origin = 'http://127.0.0.1:' + port;
let browser;
let preview;
function expectedUrl(locale) {
return 'https://form.jotform.com/262946078314059?formContext=consultation&language=' + locale;
}
try {
const drivers = await import(moduleName);
const driver = drivers[browserName];
const executablePath = browserName === 'chromium' ? process.env.CHROMIUM_EXECUTABLE : process.env.FIREFOX_EXECUTABLE;
browser = await driver.launch(executablePath
? { headless: true, executablePath }
: { headless: true });
evidence.browser = browser.version();
preview = spawn(process.execPath, ['node_modules/astro/bin/astro.mjs', 'preview', '--host', '127.0.0.1', '--port', String(port)], {
cwd: root,
env: { ...process.env, ASTRO_TELEMETRY_DISABLED: '1' },
stdio: 'ignore',
});
const reachable = () => new Promise((resolve) => {
const request = http.get(origin + '/', (response) => { response.resume(); resolve(response.statusCode === 200); });
request.setTimeout(500, () => request.destroy());
request.on('error', () => resolve(false));
});
for (let i = 0; i < 60 && !(await reachable()); i++) await delay(250);
assert.equal(await reachable(), true, 'Loopback preview did not become reachable');
const key = 'aia:service-inquiry:auto-suppressed-until';
const duration = 30 * 86400000;
const staffCode = randomBytes(24).toString('hex');
const managementCode = randomBytes(24).toString('hex');
const staffResourceName = 'a'.repeat(64) + '.pdf';
const managementResourceName = 'b'.repeat(64) + '.docx';
const staffResourcePath = `/staff-resources/${staffResourceName}`;
const managementResourcePath = `/management-resources/${managementResourceName}`;
const styledFixture = ' Operations Monthly Lineup Report - PMSynthetic Directory
Operational reports
Role Contact Fixture role Fixture email Management Templates
Other Staff Resources
Staff fixture only
Staff's Safety & Training: Résumé (2026)!Management fixture only
Management – Policies / Q&A #1` + styledFixture, managementCode), ] }; const expectedAuthorization = { staff: 'Basic ' + Buffer.from('staff:' + staffCode, 'utf8').toString('base64'), management: 'Basic ' + Buffer.from('management:' + managementCode, 'utf8').toString('base64'), }; const guard = async (context, inject = false) => { await context.routeWebSocket('**/*', (socket) => { evidence.blocked.push({ method: 'WEBSOCKET' }); socket.close(); }); await context.route('**/*', async (route) => { const req = route.request(), url = new URL(req.url()); if (url.origin === origin && ['GET', 'HEAD'].includes(req.method())) { const resource = /^\/(staff|management)-resources\/([a-f0-9]{64})[.](pdf|docx)$/.exec(url.pathname); if (resource) { const role = resource[1]; const authorized = req.headers().authorization === expectedAuthorization[role]; evidence.resourceRequests.push({ role, authorized }); if (!authorized) return route.fulfill({ status: 401, headers: { 'www-authenticate': `Basic realm="AIA ${role} resources"`, 'cache-control': 'private, no-store' } }); return route.fulfill({ status: 200, contentType: resource[3] === 'pdf' ? 'application/pdf' : 'application/vnd.openxmlformats-officedocument.wordprocessingml.document', headers: { 'cache-control': 'private, no-store' }, body: resource[3] === 'pdf' ? `%PDF-1.7\nSynthetic ${role} document\n` : `Synthetic ${role} document\n`, }); } if (inject && url.pathname === '/employee-portal') { const response = await route.fetch(); const html = (await response.text()).replace(/(