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>
99 lines
3.2 KiB
JavaScript
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);
|
|
});
|