nomadweb/scripts/shot_diagnose.js
eric ff7b721acb feat: NomadCNA community layer, social matching, payments, and ebook
Port meetups, discussions, gigs, dating/chat, VIP pay (ZPay/XorPay), MiroTalk live, digital academy, and ebook reader. Add persistent community_store, git-first deploy docs, and env template for production secrets.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-08-30 09:38:13 -05:00

99 lines
3.2 KiB
JavaScript

const { chromium } = require('playwright');
const fs = require('fs');
const path = require('path');
(async () => {
const outDir = path.join(__dirname, '..', 'tmp-screenshots');
fs.mkdirSync(outDir, { recursive: true });
const browser = await chromium.launch({ headless: true });
const page = await browser.newPage({ viewport: { width: 1440, height: 900 } });
await page.goto('https://nomadweb.nomadro.com/book/read#01-first-remote', {
waitUntil: 'networkidle',
timeout: 60000,
});
await page.waitForTimeout(1000);
const info = await page.evaluate(() => {
const chrome = document.querySelector('.reader-chrome');
const box = (el) => {
if (!el) return null;
const r = el.getBoundingClientRect();
const s = getComputedStyle(el);
return {
t: Math.round(r.top),
b: Math.round(r.bottom),
l: Math.round(r.left),
r: Math.round(r.right),
position: s.position,
top: s.top,
overflow: s.overflow,
ox: s.overflowX,
oy: s.overflowY,
cls: (el.className || '').toString().slice(0, 70),
tag: el.tagName,
};
};
const chain = [];
let el = chrome;
while (el) {
const s = getComputedStyle(el);
chain.push({
tag: el.tagName,
id: el.id || '',
cls: (el.className || '').toString().slice(0, 60),
ox: s.overflowX,
oy: s.overflowY,
o: s.overflow,
position: s.position,
transform: s.transform,
contain: s.contain,
filter: s.filter,
h: el === document.documentElement ? 'html' : el === document.body ? 'body' : '',
});
el = el.parentElement;
}
const sidebar = document.querySelector('.chapter-sidebar');
const main = document.querySelector('.scroll-reader-main');
const paper = document.querySelector('.reader-paper');
const sb = sidebar?.getBoundingClientRect();
const mn = main?.getBoundingClientRect();
const pp = paper?.getBoundingClientRect();
return {
chrome: box(chrome),
scrollY: Math.round(window.scrollY),
leftGap: sb && mn ? Math.round(mn.left - sb.right) : null,
rightGap: mn ? Math.round(window.innerWidth - mn.right) : null,
paperLeftGap: sb && pp ? Math.round(pp.left - sb.right) : null,
paperRightGap: pp ? Math.round(window.innerWidth - pp.right) : null,
chain,
};
});
await page.screenshot({ path: path.join(outDir, 'diag-hash.png'), fullPage: false });
// scroll further like user mid-read
await page.evaluate(() => window.scrollBy(0, 200));
await page.waitForTimeout(400);
const after = await page.evaluate(() => {
const chrome = document.querySelector('.reader-chrome');
const r = chrome?.getBoundingClientRect();
return {
scrollY: Math.round(window.scrollY),
chromeTop: r ? Math.round(r.top) : null,
chromeBottom: r ? Math.round(r.bottom) : null,
chromeHeight: r ? Math.round(r.height) : null,
};
});
await page.screenshot({ path: path.join(outDir, 'diag-scrolled.png'), fullPage: false });
console.log(JSON.stringify({ info, after }, null, 2));
await browser.close();
})().catch((e) => {
console.error(e);
process.exit(1);
});