mirror of
https://github.com/Kpa-clawbot/meshcore-analyzer.git
synced 2026-10-23 16:32:22 +00:00
Moves 290 root test-*.js into tests/unit (177, listed in test-all.sh) and tests/e2e (113, classified in scripts/non-unit-tests.json), per #1981 and PR-D of #1385. Root goes from 348 entries to 48. test-all.sh and test-fixtures/ stay put. The inventory guard now fails if a test reappears in the root or sits in the wrong folder.
Verified independently of the diff: the invoked sets are unchanged (test-all.sh 177 before and after, deploy.yml 96 before and after, both identical as sets), and a full local run of test-all.sh on master and on the branch produced 4702 output lines each whose only differences are absolute paths, stack-trace line numbers shifted by the REPO_ROOT line, the inventory wording and two perf ratios. The guard was mutation-checked: a test back in the root, a unit suite in tests/e2e, and a suite dropped from test-all.sh each make it exit 1. CI run 35246304316 ran 97 suites from tests/e2e and is green.
Follow-up 9335c51d finished the instruction files: no bare root test command is left in AGENTS.md, the squad charters, .github or docs, and every tests/ path they name resolves.
Merged by the interim maintainer without a second human reviewer: CI and the local runs above are the independent checks.
Known and deliberately out of scope: 18 of the 113 files in tests/e2e are invoked by no runner at all, and one of them cannot run anywhere because it requires jsdom, which is not a declared dependency. Tracked separately.
113 lines
4.9 KiB
JavaScript
113 lines
4.9 KiB
JavaScript
/**
|
|
* #1267 — VCR bar invisible on mobile /live (iOS Safari ~375x812).
|
|
*
|
|
* RED first: at a 375x812 mobile viewport, the `.vcr-bar` must be visible
|
|
* between the map and bottom-nav. Asserts measured height > 0, display !==
|
|
* 'none', visibility !== 'hidden', and that its top edge is within the
|
|
* viewport (not pushed below the visible area).
|
|
*
|
|
* Usage: BASE_URL=http://localhost:13581 node test-e2e-1267-mobile-vcr.js
|
|
*/
|
|
const { chromium, devices } = require('playwright');
|
|
|
|
const BASE = process.env.BASE_URL || 'http://localhost:13581';
|
|
|
|
(async () => {
|
|
const browser = await chromium.launch({
|
|
headless: true,
|
|
executablePath: process.env.CHROMIUM_PATH || '/usr/bin/chromium',
|
|
args: ['--no-sandbox', '--disable-gpu', '--disable-dev-shm-usage']
|
|
});
|
|
const context = await browser.newContext({
|
|
viewport: { width: 375, height: 812 },
|
|
deviceScaleFactor: 2,
|
|
isMobile: true,
|
|
hasTouch: true,
|
|
userAgent: 'Mozilla/5.0 (iPhone; CPU iPhone OS 17_0 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/17.0 Mobile/15E148 Safari/604.1',
|
|
});
|
|
const page = await context.newPage();
|
|
page.setDefaultTimeout(15000);
|
|
|
|
let failed = false;
|
|
function fail(msg) { failed = true; console.log(' \u274c', msg); }
|
|
function pass(msg) { console.log(' \u2705', msg); }
|
|
|
|
console.log(`\n#1267 mobile VCR-bar visibility against ${BASE} (375x812)\n`);
|
|
|
|
await page.goto(`${BASE}/#/live`, { waitUntil: 'domcontentloaded' });
|
|
// Allow live page mount + initial render + VCR bar ResizeObserver publish.
|
|
await page.waitForSelector('.live-page', { timeout: 15000 });
|
|
await page.waitForSelector('#vcrBar', { timeout: 15000 });
|
|
// Wait until markers populate — #1267 only manifests after marker render.
|
|
// We poll for >=1 leaflet-marker-icon to appear in the DOM, then settle.
|
|
await page.waitForFunction(
|
|
() => document.querySelectorAll('#liveMap .leaflet-marker-icon, #liveMap .leaflet-marker-pane > *').length > 0,
|
|
null,
|
|
{ timeout: 15000 }
|
|
).catch(() => {});
|
|
await page.waitForTimeout(4000);
|
|
|
|
const info = await page.evaluate(() => {
|
|
const bar = document.getElementById('vcrBar');
|
|
if (!bar) return { missing: true };
|
|
const r = bar.getBoundingClientRect();
|
|
const cs = getComputedStyle(bar);
|
|
const page = document.querySelector('.live-page');
|
|
const pageR = page ? page.getBoundingClientRect() : null;
|
|
const bn = document.querySelector('.bottom-nav');
|
|
const bnR = bn ? bn.getBoundingClientRect() : null;
|
|
const bnCs = bn ? getComputedStyle(bn) : null;
|
|
const rootCs = getComputedStyle(document.documentElement);
|
|
return {
|
|
rect: { top: r.top, bottom: r.bottom, height: r.height, width: r.width, left: r.left, right: r.right },
|
|
display: cs.display,
|
|
visibility: cs.visibility,
|
|
opacity: cs.opacity,
|
|
position: cs.position,
|
|
zIndex: cs.zIndex,
|
|
viewportH: window.innerHeight,
|
|
viewportW: window.innerWidth,
|
|
pageRect: pageR ? { top: pageR.top, bottom: pageR.bottom, height: pageR.height } : null,
|
|
bottomNav: bnR ? { top: bnR.top, bottom: bnR.bottom, height: bnR.height, display: bnCs.display } : null,
|
|
bottomNavReserve: rootCs.getPropertyValue('--bottom-nav-reserve'),
|
|
vcrBarHeightVar: getComputedStyle(page || document.body).getPropertyValue('--vcr-bar-height'),
|
|
};
|
|
});
|
|
|
|
console.log('VCR bar measurement:', JSON.stringify(info, null, 2));
|
|
|
|
if (info.missing) {
|
|
fail('#vcrBar element not in DOM');
|
|
} else {
|
|
if (info.display === 'none') fail(`display:none on .vcr-bar`);
|
|
else pass(`display is ${info.display}`);
|
|
|
|
if (info.visibility === 'hidden') fail(`visibility:hidden on .vcr-bar`);
|
|
else pass(`visibility is ${info.visibility}`);
|
|
|
|
if (info.rect.height <= 0) fail(`getBoundingClientRect().height = ${info.rect.height} (expected > 0)`);
|
|
else pass(`height ${info.rect.height}px > 0`);
|
|
|
|
if (info.rect.top >= info.viewportH) fail(`bar top ${info.rect.top} >= viewport height ${info.viewportH} (pushed off-screen)`);
|
|
else pass(`bar top ${info.rect.top} < viewport height ${info.viewportH}`);
|
|
|
|
// #1267 root assertion: the VCR bar must not be occluded by the
|
|
// fixed bottom-nav (z=1200 > vcr-bar z=1000). The bar's bottom edge
|
|
// must sit AT OR ABOVE the bottom-nav's top edge.
|
|
if (info.bottomNav && info.bottomNav.display !== 'none') {
|
|
if (info.rect.bottom > info.bottomNav.top + 0.5) {
|
|
fail(`VCR bar bottom ${info.rect.bottom} overlaps bottom-nav top ${info.bottomNav.top} (hidden behind bottom-nav — #1267)`);
|
|
} else {
|
|
pass(`VCR bar bottom ${info.rect.bottom} ≤ bottom-nav top ${info.bottomNav.top}`);
|
|
}
|
|
}
|
|
|
|
// Sanity: the bar should occupy width across most of the viewport.
|
|
if (info.rect.width < info.viewportW * 0.5) fail(`bar width ${info.rect.width} < 50% of viewport ${info.viewportW}`);
|
|
else pass(`bar width ${info.rect.width} spans >50% viewport`);
|
|
}
|
|
|
|
await browser.close();
|
|
process.exit(failed ? 1 : 0);
|
|
})().catch(err => { console.error(err); process.exit(2); });
|