8bdc105a7a
qa/live-visitor.mjs is read-only against production: a visitor on any ID-keyed shared link must see no modal, no invitation, no 401 and no page errors. It is the check that the optional-profile change did not disturb anyone who is not signed in. Passing 9/9 against rmcircle.team. docs/for-manson-optional-profiles.md is the note to send him before anything goes to the team, since he asked to see it first. It leads with his objection being right, states plainly that nothing is required, and is honest about the trade: we accept lower coverage rather than mandate identity. It also covers the level-8 question, where the pay rules were already fine and only the ladder graphic was misleading. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
33 lines
1.8 KiB
JavaScript
33 lines
1.8 KiB
JavaScript
// Read-only smoke check against PRODUCTION: a visitor on any ID-keyed shared link
|
|
// must see no profile prompt of any kind, and no errors. Anonymous, GET only.
|
|
// Run: node qa/live-visitor.mjs
|
|
import { pathToFileURL } from 'node:url';
|
|
const PW = 'D:/Projects/MarketingAgent/qa-tester/node_modules/playwright';
|
|
const { chromium } = (await import(pathToFileURL(PW + '/index.js').href)).default;
|
|
const B = process.env.LIVE || 'https://rmcircle.team';
|
|
const ok = [], bad = [];
|
|
const t = (n, c, extra) => { (c ? ok : bad).push(n + (c || !extra ? '' : ' -> ' + extra)); };
|
|
const browser = await chromium.launch();
|
|
const ctx = await browser.newContext({ viewport: { width: 1280, height: 950 } });
|
|
const p = await ctx.newPage();
|
|
const errs = [], bad401 = [];
|
|
p.on('pageerror', e => errs.push(String(e.message).slice(0, 140)));
|
|
p.on('response', r => { if (r.status() === 401 && /\/profile|\/reach/.test(r.url())) bad401.push(r.url()); });
|
|
|
|
for (const u of ['/my/21', '/my/49', '/my/787', '/join/21', '/fast-start?id=21', '/generation-pay?id=21', '/flyers?id=21']) {
|
|
await p.goto(B + u, { waitUntil: 'domcontentloaded' }).catch(() => {});
|
|
await p.waitForTimeout(2600);
|
|
const modal = await p.evaluate(() => !!document.querySelector('#pgCard'));
|
|
const invite = await p.evaluate(() => !!document.getElementById('pcGo'));
|
|
const txt = await p.evaluate(() => document.body.innerText);
|
|
t('visitor ' + u + ': renders, no modal, no invitation',
|
|
!modal && !invite && txt.length > 300, 'modal=' + modal + ' invite=' + invite + ' len=' + txt.length);
|
|
}
|
|
t('no 401s on profile/reach for a visitor', bad401.length === 0, bad401.join(','));
|
|
t('no uncaught page errors', errs.length === 0, errs.slice(0, 3).join(' | '));
|
|
|
|
console.log('LIVE PASS ' + ok.length);
|
|
for (const b of bad) console.log('LIVE FAIL ' + b);
|
|
await browser.close();
|
|
process.exit(bad.length ? 1 : 0);
|