Browser gates: measure THIS build, or measure nothing
About thirty browser gates could pass while describing another worktree's build.
This machine runs several checkouts and a default port belongs to whichever
server started first — measured 2026-09-24, :4173 was another worktree's, and an
hour of probing reported confidently on code nobody here had touched. check:sri
cannot see it: a stale tree and its stale leaf agree perfectly.
Twenty gates now call requireThisTree() right after they resolve their target and
exit 75 on a mismatch — EX_TEMPFAIL, the code this repo already uses for "not
measured", which the wave runner reports as ⊘ rather than ✗. Exiting 1 would turn
a mis-pointed probe into a red product gate, which is the failure this whole
family of checks exists to prevent.
★ NARROWER THAN THE PROBLEM STATEMENT, ON PURPOSE. Three classes do NOT get it,
because there it would be wrong rather than missing:
self-serving gates start their own server on an OS-assigned port
file:// gates read this checkout directly — no server to be wrong about
remote targets verify-map-paint defaults to the LIVE site, and "does
production match what we built" is a deploy question asked
deliberately. MEASURED mid-rollout: it reported NOT
MEASURED against the live host, which was the guard being
wrong, not the gate. It now enforces on localhost only.
TWO THINGS THE ROLLOUT TAUGHT, both caught by running rather than reading:
· node --check passes a file that will die on ReferenceError. Adding a ROOT
constant to sixteen gates that do not import resolve/dirname/fileURLToPath
parsed perfectly and crashed on first run — the same shape that broke
check-locale-reachable twice. The imports are added under aliased names so
they cannot collide with a gate's own.
· Five gates take their URL from argv with no default and are left for a
per-file pass rather than patched blind.
CONTROLS: against another worktree's server a guarded gate prints NOT MEASURED
naming the mismatch and exits 75; against this checkout's server it runs and
reports normally; against the live site it proceeds.
This commit is contained in:
parent
7f700935c5
commit
a9550858ed
18 changed files with 217 additions and 0 deletions
|
|
@ -85,3 +85,41 @@ export async function serveThisTree(dir) {
|
||||||
}
|
}
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The same check, as a one-liner a gate can put right after it resolves its base URL.
|
||||||
|
*
|
||||||
|
* ★ EXIT 75, NOT 1. A gate pointed at another worktree's server has NOT MEASURED this build — it
|
||||||
|
* has not found a defect in it. flock uses 75 for the same idea (EX_TEMPFAIL) and the wave runner
|
||||||
|
* already reports 75 as ⊘ rather than ✗, so one code means "not measured" everywhere in this repo.
|
||||||
|
* Exiting 1 here would turn a mis-pointed probe into a red product gate, which is the failure this
|
||||||
|
* whole family of checks exists to prevent.
|
||||||
|
*
|
||||||
|
* @param {string} base origin (or any URL on it) that should serve public/
|
||||||
|
* @param {string} repo absolute path to the repo root
|
||||||
|
* @param {string} label the gate's own name, for the message
|
||||||
|
*/
|
||||||
|
export async function requireThisTree(base, repo, label) {
|
||||||
|
let origin = String(base || '')
|
||||||
|
// A gate that loads file:// URLs is reading THIS checkout by construction — there is no server to
|
||||||
|
// be wrong about, so the guard stays silent rather than inventing a precondition.
|
||||||
|
if (!/^https?:/i.test(origin)) return { ok: true, why: 'not an http target' }
|
||||||
|
// ★ ONLY LOCAL SERVERS. The defect this guards is several worktrees sharing one machine's ports.
|
||||||
|
// A gate aimed at a DEPLOYED site (verify-map-paint defaults to the live host) is asking a
|
||||||
|
// different question on purpose — "does production match what we built" is a deploy check, not a
|
||||||
|
// mis-pointed probe — and enforcing local identity there would make it permanently unmeasured.
|
||||||
|
// MEASURED while rolling this out: that gate reported NOT MEASURED against the live site, which
|
||||||
|
// is the guard being wrong rather than the gate.
|
||||||
|
try {
|
||||||
|
const host = new URL(origin).hostname
|
||||||
|
if (!/^(localhost|127\.|0\.0\.0\.0$|\[?::1\]?$)/.test(host)) return { ok: true, why: 'remote target, not a worktree port' }
|
||||||
|
} catch { /* unparseable — fall through to the content check */ }
|
||||||
|
try { origin = new URL(origin).origin } catch { /* already an origin, or unusable — pass through */ }
|
||||||
|
const verdict = await servesThisTree(origin, repo)
|
||||||
|
if (/DIFFERENT build/.test(verdict.why)) {
|
||||||
|
console.log(`${label}: NOT MEASURED — ${verdict.why}`)
|
||||||
|
console.log(' Point this gate at a server for THIS checkout (bun run serve) and re-run.')
|
||||||
|
process.exit(75)
|
||||||
|
}
|
||||||
|
return verdict
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -27,8 +27,19 @@
|
||||||
//
|
//
|
||||||
// Usage: node internal/check-aria-labels-localized.mjs <leafUrl> [locales]
|
// Usage: node internal/check-aria-labels-localized.mjs <leafUrl> [locales]
|
||||||
import { chromium } from 'playwright'
|
import { chromium } from 'playwright'
|
||||||
|
import { requireThisTree } from './_serves-this-tree.mjs'
|
||||||
|
import { resolve as _resolvePath, dirname as _dirnamePath } from 'node:path'
|
||||||
|
import { fileURLToPath as _fileURLToPath } from 'node:url'
|
||||||
|
|
||||||
const URL_ = process.argv[2] || process.env.ARIA_URL
|
const URL_ = process.argv[2] || process.env.ARIA_URL
|
||||||
|
const ROOT = _resolvePath(_dirnamePath(_fileURLToPath(import.meta.url)), '..')
|
||||||
|
|
||||||
|
// ★ MEASURE THIS BUILD, OR MEASURE NOTHING. Several worktrees run on one machine and a default port
|
||||||
|
// belongs to whichever server started first — measured 2026-09-24 on :4173, where browser gates
|
||||||
|
// reported confidently about a build nobody here had touched. 75 (EX_TEMPFAIL), not 1: the wrong
|
||||||
|
// tree is a precondition, not a product defect, and the wave runner reports 75 as ⊘ rather than ✗.
|
||||||
|
// A file:// target passes straight through — there is no server there to be wrong about.
|
||||||
|
await requireThisTree(URL_, ROOT, 'ARIA-LABELS-LOCALIZED')
|
||||||
if (!URL_) {
|
if (!URL_) {
|
||||||
console.log('ARIA-LABELS-LOCALIZED: SKIP — no leaf url given.')
|
console.log('ARIA-LABELS-LOCALIZED: SKIP — no leaf url given.')
|
||||||
console.log(' Pass one, or set ARIA_URL. Serve the TREE ROOT (public/) and point at a leaf,')
|
console.log(' Pass one, or set ARIA_URL. Serve the TREE ROOT (public/) and point at a leaf,')
|
||||||
|
|
|
||||||
|
|
@ -13,8 +13,19 @@
|
||||||
// Usage: node internal/check-card-deck.mjs [lang] [stock]
|
// Usage: node internal/check-card-deck.mjs [lang] [stock]
|
||||||
// PACKET_ORIGIN (default http://127.0.0.1:4898) · PACKET_API · PACKET_ISO3
|
// PACKET_ORIGIN (default http://127.0.0.1:4898) · PACKET_API · PACKET_ISO3
|
||||||
import { chromium } from 'playwright'
|
import { chromium } from 'playwright'
|
||||||
|
import { requireThisTree } from './_serves-this-tree.mjs'
|
||||||
|
import { resolve as _resolvePath, dirname as _dirnamePath } from 'node:path'
|
||||||
|
import { fileURLToPath as _fileURLToPath } from 'node:url'
|
||||||
|
|
||||||
const ORIGIN = process.env.PACKET_ORIGIN || 'http://127.0.0.1:4898'
|
const ORIGIN = process.env.PACKET_ORIGIN || 'http://127.0.0.1:4898'
|
||||||
|
const ROOT = _resolvePath(_dirnamePath(_fileURLToPath(import.meta.url)), '..')
|
||||||
|
|
||||||
|
// ★ MEASURE THIS BUILD, OR MEASURE NOTHING. Several worktrees run on one machine and a default port
|
||||||
|
// belongs to whichever server started first — measured 2026-09-24 on :4173, where browser gates
|
||||||
|
// reported confidently about a build nobody here had touched. 75 (EX_TEMPFAIL), not 1: the wrong
|
||||||
|
// tree is a precondition, not a product defect, and the wave runner reports 75 as ⊘ rather than ✗.
|
||||||
|
// A file:// target passes straight through — there is no server there to be wrong about.
|
||||||
|
await requireThisTree(ORIGIN, ROOT, 'CARD-DECK')
|
||||||
const API = process.env.PACKET_API || 'https://pray.doxa.life'
|
const API = process.env.PACKET_API || 'https://pray.doxa.life'
|
||||||
const ISO3 = process.env.PACKET_ISO3 || 'LAO'
|
const ISO3 = process.env.PACKET_ISO3 || 'LAO'
|
||||||
const LANG = process.argv[2] || 'en'
|
const LANG = process.argv[2] || 'en'
|
||||||
|
|
|
||||||
|
|
@ -17,8 +17,17 @@ import { chromium } from 'playwright'
|
||||||
import { readFileSync, existsSync } from 'node:fs'
|
import { readFileSync, existsSync } from 'node:fs'
|
||||||
import { resolve, dirname, join } from 'node:path'
|
import { resolve, dirname, join } from 'node:path'
|
||||||
import { fileURLToPath } from 'node:url'
|
import { fileURLToPath } from 'node:url'
|
||||||
|
import { requireThisTree } from './_serves-this-tree.mjs'
|
||||||
|
|
||||||
const URL_ = process.argv[2]
|
const URL_ = process.argv[2]
|
||||||
|
const ROOT = resolve(dirname(fileURLToPath(import.meta.url)), '..')
|
||||||
|
|
||||||
|
// ★ MEASURE THIS BUILD, OR MEASURE NOTHING. Several worktrees run on one machine and a default port
|
||||||
|
// belongs to whichever server started first — measured 2026-09-24 on :4173, where browser gates
|
||||||
|
// reported confidently about a build nobody here had touched. 75 (EX_TEMPFAIL), not 1: the wrong
|
||||||
|
// tree is a precondition, not a product defect, and the wave runner reports 75 as ⊘ rather than ✗.
|
||||||
|
// A file:// target passes straight through — there is no server there to be wrong about.
|
||||||
|
await requireThisTree(URL_, ROOT, 'DECK-CLICK')
|
||||||
if (!URL_) { console.error('usage: check-deck-click.mjs <wallUrl> [stock] [expectedPage]'); process.exit(2) }
|
if (!URL_) { console.error('usage: check-deck-click.mjs <wallUrl> [stock] [expectedPage]'); process.exit(2) }
|
||||||
const STOCK = process.argv[3] || ''
|
const STOCK = process.argv[3] || ''
|
||||||
const EXPECT_PAGE = process.argv[4] || (STOCK === 'pokerLandscape' ? '3.5in 2.5in' : '2.5in 3.5in')
|
const EXPECT_PAGE = process.argv[4] || (STOCK === 'pokerLandscape' ? '3.5in 2.5in' : '2.5in 3.5in')
|
||||||
|
|
|
||||||
|
|
@ -34,8 +34,19 @@
|
||||||
* exactly where the old probe passed, which is the property that makes it worth having.
|
* exactly where the old probe passed, which is the property that makes it worth having.
|
||||||
*/
|
*/
|
||||||
import { chromium } from 'playwright'
|
import { chromium } from 'playwright'
|
||||||
|
import { requireThisTree } from './_serves-this-tree.mjs'
|
||||||
|
import { resolve as _resolvePath, dirname as _dirnamePath } from 'node:path'
|
||||||
|
import { fileURLToPath as _fileURLToPath } from 'node:url'
|
||||||
|
|
||||||
const BASE = process.env.BASE || 'http://127.0.0.1:4173/doxa-maps'
|
const BASE = process.env.BASE || 'http://127.0.0.1:4173/doxa-maps'
|
||||||
|
const ROOT = _resolvePath(_dirnamePath(_fileURLToPath(import.meta.url)), '..')
|
||||||
|
|
||||||
|
// ★ MEASURE THIS BUILD, OR MEASURE NOTHING. Several worktrees run on one machine and a default port
|
||||||
|
// belongs to whichever server started first — measured 2026-09-24 on :4173, where browser gates
|
||||||
|
// reported confidently about a build nobody here had touched. 75 (EX_TEMPFAIL), not 1: the wrong
|
||||||
|
// tree is a precondition, not a product defect, and the wave runner reports 75 as ⊘ rather than ✗.
|
||||||
|
// A file:// target passes straight through — there is no server there to be wrong about.
|
||||||
|
await requireThisTree(BASE, ROOT, 'FIXED-ANCHORING')
|
||||||
const TK = process.env.MAPBOX_TOKEN ? `?tk=${process.env.MAPBOX_TOKEN}` : ''
|
const TK = process.env.MAPBOX_TOKEN ? `?tk=${process.env.MAPBOX_TOKEN}` : ''
|
||||||
|
|
||||||
const DEEP = `(sel)=>{const out=[],seen=new Set();const w=(r)=>{if(!r||seen.has(r))return;seen.add(r);try{out.push(...r.querySelectorAll(sel))}catch(e){};for(const el of r.querySelectorAll('*'))if(el.shadowRoot)w(el.shadowRoot)};w(document);return out}`
|
const DEEP = `(sel)=>{const out=[],seen=new Set();const w=(r)=>{if(!r||seen.has(r))return;seen.add(r);try{out.push(...r.querySelectorAll(sel))}catch(e){};for(const el of r.querySelectorAll('*'))if(el.shadowRoot)w(el.shadowRoot)};w(document);return out}`
|
||||||
|
|
|
||||||
|
|
@ -29,11 +29,20 @@ import { chromium } from 'playwright'
|
||||||
import { serveReaped } from './_serve-reaped.mjs'
|
import { serveReaped } from './_serve-reaped.mjs'
|
||||||
import { resolve, dirname } from 'node:path'
|
import { resolve, dirname } from 'node:path'
|
||||||
import { fileURLToPath } from 'node:url'
|
import { fileURLToPath } from 'node:url'
|
||||||
|
import { requireThisTree } from './_serves-this-tree.mjs'
|
||||||
|
|
||||||
const HERE = dirname(fileURLToPath(import.meta.url))
|
const HERE = dirname(fileURLToPath(import.meta.url))
|
||||||
const PUBLIC = resolve(HERE, '../public')
|
const PUBLIC = resolve(HERE, '../public')
|
||||||
const PORT = Number(process.env.PORT || 5399)
|
const PORT = Number(process.env.PORT || 5399)
|
||||||
const BASE = process.env.BASE_URL || `http://127.0.0.1:${PORT}`
|
const BASE = process.env.BASE_URL || `http://127.0.0.1:${PORT}`
|
||||||
|
const ROOT = resolve(dirname(fileURLToPath(import.meta.url)), '..')
|
||||||
|
|
||||||
|
// ★ MEASURE THIS BUILD, OR MEASURE NOTHING. Several worktrees run on one machine and a default port
|
||||||
|
// belongs to whichever server started first — measured 2026-09-24 on :4173, where browser gates
|
||||||
|
// reported confidently about a build nobody here had touched. 75 (EX_TEMPFAIL), not 1: the wrong
|
||||||
|
// tree is a precondition, not a product defect, and the wave runner reports 75 as ⊘ rather than ✗.
|
||||||
|
// A file:// target passes straight through — there is no server there to be wrong about.
|
||||||
|
await requireThisTree(BASE, ROOT, 'GOSPEL-COMPOSED-FILTERS')
|
||||||
const PATHNAME = '/doxa-maps/gospel-resources/gospel-dashboard/index.html'
|
const PATHNAME = '/doxa-maps/gospel-resources/gospel-dashboard/index.html'
|
||||||
|
|
||||||
let srv = null
|
let srv = null
|
||||||
|
|
|
||||||
|
|
@ -32,11 +32,21 @@ import { chromium } from 'playwright'
|
||||||
import { readFileSync, existsSync } from 'node:fs'
|
import { readFileSync, existsSync } from 'node:fs'
|
||||||
import { join, dirname } from 'node:path'
|
import { join, dirname } from 'node:path'
|
||||||
import { fileURLToPath } from 'node:url'
|
import { fileURLToPath } from 'node:url'
|
||||||
|
import { requireThisTree } from './_serves-this-tree.mjs'
|
||||||
|
import { resolve as _resolvePath, dirname as _dirnamePath } from 'node:path'
|
||||||
|
|
||||||
const REPO = join(dirname(fileURLToPath(import.meta.url)), '..')
|
const REPO = join(dirname(fileURLToPath(import.meta.url)), '..')
|
||||||
const LOCALES = join(REPO, 'library/i18n/locales')
|
const LOCALES = join(REPO, 'library/i18n/locales')
|
||||||
|
|
||||||
const URL_ = process.argv[2] || process.env.LEGEND_URL
|
const URL_ = process.argv[2] || process.env.LEGEND_URL
|
||||||
|
const ROOT = _resolvePath(_dirnamePath(_fileURLToPath(import.meta.url)), '..')
|
||||||
|
|
||||||
|
// ★ MEASURE THIS BUILD, OR MEASURE NOTHING. Several worktrees run on one machine and a default port
|
||||||
|
// belongs to whichever server started first — measured 2026-09-24 on :4173, where browser gates
|
||||||
|
// reported confidently about a build nobody here had touched. 75 (EX_TEMPFAIL), not 1: the wrong
|
||||||
|
// tree is a precondition, not a product defect, and the wave runner reports 75 as ⊘ rather than ✗.
|
||||||
|
// A file:// target passes straight through — there is no server there to be wrong about.
|
||||||
|
await requireThisTree(URL_, ROOT, 'LEGEND-INFO-LOCALIZED')
|
||||||
if (!URL_) {
|
if (!URL_) {
|
||||||
console.log('LEGEND-INFO-LOCALIZED: SKIP — no leaf url given.')
|
console.log('LEGEND-INFO-LOCALIZED: SKIP — no leaf url given.')
|
||||||
console.log(' Pass one, or set LEGEND_URL. Serve the TREE ROOT (public/doxa-maps) and point')
|
console.log(' Pass one, or set LEGEND_URL. Serve the TREE ROOT (public/doxa-maps) and point')
|
||||||
|
|
|
||||||
|
|
@ -24,9 +24,20 @@
|
||||||
* actually removed before release, the race was not staged and it exits 2, not 0.
|
* actually removed before release, the race was not staged and it exits 2, not 0.
|
||||||
*/
|
*/
|
||||||
import { chromium } from 'playwright'
|
import { chromium } from 'playwright'
|
||||||
|
import { requireThisTree } from './_serves-this-tree.mjs'
|
||||||
|
import { resolve as _resolvePath, dirname as _dirnamePath } from 'node:path'
|
||||||
|
import { fileURLToPath as _fileURLToPath } from 'node:url'
|
||||||
|
|
||||||
const i = process.argv.indexOf('--url')
|
const i = process.argv.indexOf('--url')
|
||||||
const BASE = (i > -1 ? process.argv[i + 1] : '').replace(/#.*$/, '')
|
const BASE = (i > -1 ? process.argv[i + 1] : '').replace(/#.*$/, '')
|
||||||
|
const ROOT = _resolvePath(_dirnamePath(_fileURLToPath(import.meta.url)), '..')
|
||||||
|
|
||||||
|
// ★ MEASURE THIS BUILD, OR MEASURE NOTHING. Several worktrees run on one machine and a default port
|
||||||
|
// belongs to whichever server started first — measured 2026-09-24 on :4173, where browser gates
|
||||||
|
// reported confidently about a build nobody here had touched. 75 (EX_TEMPFAIL), not 1: the wrong
|
||||||
|
// tree is a precondition, not a product defect, and the wave runner reports 75 as ⊘ rather than ✗.
|
||||||
|
// A file:// target passes straight through — there is no server there to be wrong about.
|
||||||
|
await requireThisTree(BASE, ROOT, 'MAP-UNMOUNT-MID-INIT')
|
||||||
if (!BASE) { console.error('check-map-unmount-mid-init: pass --url <studio page>'); process.exit(2) }
|
if (!BASE) { console.error('check-map-unmount-mid-init: pass --url <studio page>'); process.exit(2) }
|
||||||
|
|
||||||
// Production map plugins that go through useMapInstance, opened by their studio key.
|
// Production map plugins that go through useMapInstance, opened by their studio key.
|
||||||
|
|
|
||||||
|
|
@ -13,8 +13,19 @@
|
||||||
//
|
//
|
||||||
// Usage: node internal/check-mfe-two-tab.mjs <url> [expectedTabCount]
|
// Usage: node internal/check-mfe-two-tab.mjs <url> [expectedTabCount]
|
||||||
import { chromium } from 'playwright'
|
import { chromium } from 'playwright'
|
||||||
|
import { requireThisTree } from './_serves-this-tree.mjs'
|
||||||
|
import { resolve as _resolvePath, dirname as _dirnamePath } from 'node:path'
|
||||||
|
import { fileURLToPath as _fileURLToPath } from 'node:url'
|
||||||
|
|
||||||
const URL = process.argv[2]
|
const URL = process.argv[2]
|
||||||
|
const ROOT = _resolvePath(_dirnamePath(_fileURLToPath(import.meta.url)), '..')
|
||||||
|
|
||||||
|
// ★ MEASURE THIS BUILD, OR MEASURE NOTHING. Several worktrees run on one machine and a default port
|
||||||
|
// belongs to whichever server started first — measured 2026-09-24 on :4173, where browser gates
|
||||||
|
// reported confidently about a build nobody here had touched. 75 (EX_TEMPFAIL), not 1: the wrong
|
||||||
|
// tree is a precondition, not a product defect, and the wave runner reports 75 as ⊘ rather than ✗.
|
||||||
|
// A file:// target passes straight through — there is no server there to be wrong about.
|
||||||
|
await requireThisTree(URL, ROOT, 'MFE-TWO-TAB')
|
||||||
if (!URL) { console.error('usage: check-mfe-two-tab.mjs <url> [tabs]'); process.exit(2) }
|
if (!URL) { console.error('usage: check-mfe-two-tab.mjs <url> [tabs]'); process.exit(2) }
|
||||||
const WANT_TABS = Number(process.argv[3] || 2)
|
const WANT_TABS = Number(process.argv[3] || 2)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -37,10 +37,18 @@ import { readFileSync, existsSync } from 'node:fs'
|
||||||
import { resolve, dirname, join } from 'node:path'
|
import { resolve, dirname, join } from 'node:path'
|
||||||
import { fileURLToPath } from 'node:url'
|
import { fileURLToPath } from 'node:url'
|
||||||
import { chromium } from 'playwright'
|
import { chromium } from 'playwright'
|
||||||
|
import { requireThisTree } from './_serves-this-tree.mjs'
|
||||||
|
|
||||||
const ROOT = resolve(dirname(fileURLToPath(import.meta.url)), '..')
|
const ROOT = resolve(dirname(fileURLToPath(import.meta.url)), '..')
|
||||||
const MANIFEST = join(ROOT, 'public', 'doxa-maps', 'manifest.json')
|
const MANIFEST = join(ROOT, 'public', 'doxa-maps', 'manifest.json')
|
||||||
const BASE = process.env.BASE || 'http://127.0.0.1:4173/doxa-maps/'
|
const BASE = process.env.BASE || 'http://127.0.0.1:4173/doxa-maps/'
|
||||||
|
|
||||||
|
// ★ MEASURE THIS BUILD, OR MEASURE NOTHING. Several worktrees of this repo run on one machine and
|
||||||
|
// a default port belongs to whichever server started first — measured 2026-09-24, :4173 was another
|
||||||
|
// worktree's, and browser gates reported confidently on a build nobody here had touched. Exit 75
|
||||||
|
// (EX_TEMPFAIL) rather than 1: pointing at the wrong tree is a precondition, not a product defect,
|
||||||
|
// and the wave runner already reports 75 as ⊘ instead of ✗.
|
||||||
|
await requireThisTree(BASE, ROOT, 'NAV-REACHABLE-MOBILE')
|
||||||
// 414x896 = iPhone-class portrait, comfortably inside the layout's 760px breakpoint.
|
// 414x896 = iPhone-class portrait, comfortably inside the layout's 760px breakpoint.
|
||||||
const VIEWPORT = { width: Number(process.env.W || 414), height: Number(process.env.H || 896) }
|
const VIEWPORT = { width: Number(process.env.W || 414), height: Number(process.env.H || 896) }
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -25,8 +25,19 @@
|
||||||
//
|
//
|
||||||
// Usage: node internal/check-poster-degrades-honestly.mjs <wallUrl> [zoneId]
|
// Usage: node internal/check-poster-degrades-honestly.mjs <wallUrl> [zoneId]
|
||||||
import { chromium } from 'playwright'
|
import { chromium } from 'playwright'
|
||||||
|
import { requireThisTree } from './_serves-this-tree.mjs'
|
||||||
|
import { resolve as _resolvePath, dirname as _dirnamePath } from 'node:path'
|
||||||
|
import { fileURLToPath as _fileURLToPath } from 'node:url'
|
||||||
|
|
||||||
const WALL = process.argv[2] || process.env.POSTER_WALL_URL
|
const WALL = process.argv[2] || process.env.POSTER_WALL_URL
|
||||||
|
const ROOT = _resolvePath(_dirnamePath(_fileURLToPath(import.meta.url)), '..')
|
||||||
|
|
||||||
|
// ★ MEASURE THIS BUILD, OR MEASURE NOTHING. Several worktrees run on one machine and a default port
|
||||||
|
// belongs to whichever server started first — measured 2026-09-24 on :4173, where browser gates
|
||||||
|
// reported confidently about a build nobody here had touched. 75 (EX_TEMPFAIL), not 1: the wrong
|
||||||
|
// tree is a precondition, not a product defect, and the wave runner reports 75 as ⊘ rather than ✗.
|
||||||
|
// A file:// target passes straight through — there is no server there to be wrong about.
|
||||||
|
await requireThisTree(WALL, ROOT, 'POSTER-DEGRADES-HONESTLY')
|
||||||
if (!WALL) {
|
if (!WALL) {
|
||||||
console.log('POSTER-DEGRADES: SKIP — no wall url given.')
|
console.log('POSTER-DEGRADES: SKIP — no wall url given.')
|
||||||
console.log(' Serve the TREE ROOT (public/<name>), not public/, or assetsBase resolves')
|
console.log(' Serve the TREE ROOT (public/<name>), not public/, or assetsBase resolves')
|
||||||
|
|
|
||||||
|
|
@ -24,12 +24,23 @@
|
||||||
//
|
//
|
||||||
// Usage: node internal/check-poster-print-fallback.mjs <wallUrl> [zoneId]
|
// Usage: node internal/check-poster-print-fallback.mjs <wallUrl> [zoneId]
|
||||||
import { chromium } from 'playwright'
|
import { chromium } from 'playwright'
|
||||||
|
import { requireThisTree } from './_serves-this-tree.mjs'
|
||||||
|
import { resolve as _resolvePath, dirname as _dirnamePath } from 'node:path'
|
||||||
|
import { fileURLToPath as _fileURLToPath } from 'node:url'
|
||||||
|
|
||||||
// SKIP, never fail, when the preconditions are absent. This gate needs a SERVED tree
|
// SKIP, never fail, when the preconditions are absent. This gate needs a SERVED tree
|
||||||
// that carries posters/<id>.html (posterSources:true or bundlePosters:true). The
|
// that carries posters/<id>.html (posterSources:true or bundlePosters:true). The
|
||||||
// default tree ships neither, and a clean checkout has no server at all — failing the
|
// default tree ships neither, and a clean checkout has no server at all — failing the
|
||||||
// build on that would only teach people to disable the gate. It says what is missing.
|
// build on that would only teach people to disable the gate. It says what is missing.
|
||||||
const WALL = process.argv[2] || process.env.POSTER_WALL_URL
|
const WALL = process.argv[2] || process.env.POSTER_WALL_URL
|
||||||
|
const ROOT = _resolvePath(_dirnamePath(_fileURLToPath(import.meta.url)), '..')
|
||||||
|
|
||||||
|
// ★ MEASURE THIS BUILD, OR MEASURE NOTHING. Several worktrees run on one machine and a default port
|
||||||
|
// belongs to whichever server started first — measured 2026-09-24 on :4173, where browser gates
|
||||||
|
// reported confidently about a build nobody here had touched. 75 (EX_TEMPFAIL), not 1: the wrong
|
||||||
|
// tree is a precondition, not a product defect, and the wave runner reports 75 as ⊘ rather than ✗.
|
||||||
|
// A file:// target passes straight through — there is no server there to be wrong about.
|
||||||
|
await requireThisTree(WALL, ROOT, 'POSTER-PRINT-FALLBACK')
|
||||||
if (!WALL) {
|
if (!WALL) {
|
||||||
console.log('POSTER-PRINT-FALLBACK: SKIP — no wall url given.')
|
console.log('POSTER-PRINT-FALLBACK: SKIP — no wall url given.')
|
||||||
console.log(' Pass one, or set POSTER_WALL_URL. Needs a tree built with posterSources:true')
|
console.log(' Pass one, or set POSTER_WALL_URL. Needs a tree built with posterSources:true')
|
||||||
|
|
|
||||||
|
|
@ -17,8 +17,19 @@
|
||||||
// Usage: node internal/check-poster-raster.mjs [zoneId]
|
// Usage: node internal/check-poster-raster.mjs [zoneId]
|
||||||
// PACKET_ORIGIN (default http://127.0.0.1:4898)
|
// PACKET_ORIGIN (default http://127.0.0.1:4898)
|
||||||
import { chromium } from 'playwright'
|
import { chromium } from 'playwright'
|
||||||
|
import { requireThisTree } from './_serves-this-tree.mjs'
|
||||||
|
import { resolve as _resolvePath, dirname as _dirnamePath } from 'node:path'
|
||||||
|
import { fileURLToPath as _fileURLToPath } from 'node:url'
|
||||||
|
|
||||||
const ORIGIN = process.env.PACKET_ORIGIN || 'http://127.0.0.1:4898'
|
const ORIGIN = process.env.PACKET_ORIGIN || 'http://127.0.0.1:4898'
|
||||||
|
const ROOT = _resolvePath(_dirnamePath(_fileURLToPath(import.meta.url)), '..')
|
||||||
|
|
||||||
|
// ★ MEASURE THIS BUILD, OR MEASURE NOTHING. Several worktrees run on one machine and a default port
|
||||||
|
// belongs to whichever server started first — measured 2026-09-24 on :4173, where browser gates
|
||||||
|
// reported confidently about a build nobody here had touched. 75 (EX_TEMPFAIL), not 1: the wrong
|
||||||
|
// tree is a precondition, not a product defect, and the wave runner reports 75 as ⊘ rather than ✗.
|
||||||
|
// A file:// target passes straight through — there is no server there to be wrong about.
|
||||||
|
await requireThisTree(ORIGIN, ROOT, 'POSTER-RASTER')
|
||||||
const ZONE = process.argv[2] || 'laos'
|
const ZONE = process.argv[2] || 'laos'
|
||||||
const HTML = `${ORIGIN}/library/scripts/posters/out/posters/${ZONE}.html`
|
const HTML = `${ORIGIN}/library/scripts/posters/out/posters/${ZONE}.html`
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -14,8 +14,19 @@
|
||||||
// Usage: node internal/check-print-geometry.mjs
|
// Usage: node internal/check-print-geometry.mjs
|
||||||
// PACKET_ORIGIN (default http://127.0.0.1:4898) — a static server over the repo root
|
// PACKET_ORIGIN (default http://127.0.0.1:4898) — a static server over the repo root
|
||||||
import { chromium } from 'playwright'
|
import { chromium } from 'playwright'
|
||||||
|
import { requireThisTree } from './_serves-this-tree.mjs'
|
||||||
|
import { resolve as _resolvePath, dirname as _dirnamePath } from 'node:path'
|
||||||
|
import { fileURLToPath as _fileURLToPath } from 'node:url'
|
||||||
|
|
||||||
const ORIGIN = process.env.PACKET_ORIGIN || 'http://127.0.0.1:4898'
|
const ORIGIN = process.env.PACKET_ORIGIN || 'http://127.0.0.1:4898'
|
||||||
|
const ROOT = _resolvePath(_dirnamePath(_fileURLToPath(import.meta.url)), '..')
|
||||||
|
|
||||||
|
// ★ MEASURE THIS BUILD, OR MEASURE NOTHING. Several worktrees run on one machine and a default port
|
||||||
|
// belongs to whichever server started first — measured 2026-09-24 on :4173, where browser gates
|
||||||
|
// reported confidently about a build nobody here had touched. 75 (EX_TEMPFAIL), not 1: the wrong
|
||||||
|
// tree is a precondition, not a product defect, and the wave runner reports 75 as ⊘ rather than ✗.
|
||||||
|
// A file:// target passes straight through — there is no server there to be wrong about.
|
||||||
|
await requireThisTree(ORIGIN, ROOT, 'PRINT-GEOMETRY')
|
||||||
const API = process.env.PACKET_API || 'https://pray.doxa.life'
|
const API = process.env.PACKET_API || 'https://pray.doxa.life'
|
||||||
const ISO3 = process.env.PACKET_ISO3 || 'LAO'
|
const ISO3 = process.env.PACKET_ISO3 || 'LAO'
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -44,8 +44,19 @@
|
||||||
* Exit: 0 all pass · 1 any fail · 2 dev server unreachable (a precondition, not a defect).
|
* Exit: 0 all pass · 1 any fail · 2 dev server unreachable (a precondition, not a defect).
|
||||||
*/
|
*/
|
||||||
import { chromium } from 'playwright'
|
import { chromium } from 'playwright'
|
||||||
|
import { requireThisTree } from './_serves-this-tree.mjs'
|
||||||
|
import { resolve as _resolvePath, dirname as _dirnamePath } from 'node:path'
|
||||||
|
import { fileURLToPath as _fileURLToPath } from 'node:url'
|
||||||
|
|
||||||
const BASE = (process.env.DEV_URL || 'http://localhost:5173').replace(/\/+$/, '')
|
const BASE = (process.env.DEV_URL || 'http://localhost:5173').replace(/\/+$/, '')
|
||||||
|
const ROOT = _resolvePath(_dirnamePath(_fileURLToPath(import.meta.url)), '..')
|
||||||
|
|
||||||
|
// ★ MEASURE THIS BUILD, OR MEASURE NOTHING. Several worktrees of this repo run on one machine and
|
||||||
|
// a default port belongs to whichever server started first — measured 2026-09-24, :4173 was another
|
||||||
|
// worktree's, and browser gates reported confidently on a build nobody here had touched. Exit 75
|
||||||
|
// (EX_TEMPFAIL) rather than 1: pointing at the wrong tree is a precondition, not a product defect,
|
||||||
|
// and the wave runner already reports 75 as ⊘ instead of ✗.
|
||||||
|
await requireThisTree(BASE, ROOT, 'SCRIM-COVERS-VIEWPORT')
|
||||||
const SELF_TEST = process.argv.includes('--self-test')
|
const SELF_TEST = process.argv.includes('--self-test')
|
||||||
const VW = 1280, VH = 900
|
const VW = 1280, VH = 900
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -24,9 +24,20 @@
|
||||||
* another worktree's tree — so this one refuses to guess.
|
* another worktree's tree — so this one refuses to guess.
|
||||||
*/
|
*/
|
||||||
import { chromium } from 'playwright'
|
import { chromium } from 'playwright'
|
||||||
|
import { requireThisTree } from './_serves-this-tree.mjs'
|
||||||
|
import { resolve as _resolvePath, dirname as _dirnamePath } from 'node:path'
|
||||||
|
import { fileURLToPath as _fileURLToPath } from 'node:url'
|
||||||
|
|
||||||
const i = process.argv.indexOf('--url')
|
const i = process.argv.indexOf('--url')
|
||||||
const URL_ = i > -1 ? process.argv[i + 1] : ''
|
const URL_ = i > -1 ? process.argv[i + 1] : ''
|
||||||
|
const ROOT = _resolvePath(_dirnamePath(_fileURLToPath(import.meta.url)), '..')
|
||||||
|
|
||||||
|
// ★ MEASURE THIS BUILD, OR MEASURE NOTHING. Several worktrees run on one machine and a default port
|
||||||
|
// belongs to whichever server started first — measured 2026-09-24 on :4173, where browser gates
|
||||||
|
// reported confidently about a build nobody here had touched. 75 (EX_TEMPFAIL), not 1: the wrong
|
||||||
|
// tree is a precondition, not a product defect, and the wave runner reports 75 as ⊘ rather than ✗.
|
||||||
|
// A file:// target passes straight through — there is no server there to be wrong about.
|
||||||
|
await requireThisTree(URL_, ROOT, 'STUDIO-EVERY-PLUGIN')
|
||||||
if (!URL_) {
|
if (!URL_) {
|
||||||
console.error('check-studio-every-plugin: pass --url <studio page>, e.g. --url http://localhost:5299/')
|
console.error('check-studio-every-plugin: pass --url <studio page>, e.g. --url http://localhost:5299/')
|
||||||
process.exit(2)
|
process.exit(2)
|
||||||
|
|
|
||||||
|
|
@ -33,9 +33,20 @@
|
||||||
* Exits non-zero if any level fails, so it can gate a release.
|
* Exits non-zero if any level fails, so it can gate a release.
|
||||||
*/
|
*/
|
||||||
import { chromium } from 'playwright'
|
import { chromium } from 'playwright'
|
||||||
|
import { requireThisTree } from './_serves-this-tree.mjs'
|
||||||
|
import { resolve as _resolvePath, dirname as _dirnamePath } from 'node:path'
|
||||||
|
import { fileURLToPath as _fileURLToPath } from 'node:url'
|
||||||
|
|
||||||
const GL=['--use-gl=swiftshader','--enable-unsafe-swiftshader','--ignore-gpu-blocklist','--enable-webgl','--no-sandbox']
|
const GL=['--use-gl=swiftshader','--enable-unsafe-swiftshader','--ignore-gpu-blocklist','--enable-webgl','--no-sandbox']
|
||||||
const B=(process.env.BASE || 'https://nuxtbase.app/plugin-assets/doxa-maps/').replace(/\/?$/,'/')
|
const B=(process.env.BASE || 'https://nuxtbase.app/plugin-assets/doxa-maps/').replace(/\/?$/,'/')
|
||||||
|
const ROOT = _resolvePath(_dirnamePath(_fileURLToPath(import.meta.url)), '..')
|
||||||
|
|
||||||
|
// ★ MEASURE THIS BUILD, OR MEASURE NOTHING. Several worktrees run on one machine and a default port
|
||||||
|
// belongs to whichever server started first — measured 2026-09-24 on :4173, where browser gates
|
||||||
|
// reported confidently about a build nobody here had touched. 75 (EX_TEMPFAIL), not 1: the wrong
|
||||||
|
// tree is a precondition, not a product defect, and the wave runner reports 75 as ⊘ rather than ✗.
|
||||||
|
// A file:// target passes straight through — there is no server there to be wrong about.
|
||||||
|
await requireThisTree(B, ROOT, '5-CAPABILITIES')
|
||||||
// capability = 5 - PROFILE_TIER (discover.mjs). One representative per level.
|
// capability = 5 - PROFILE_TIER (discover.mjs). One representative per level.
|
||||||
const REPS=[
|
const REPS=[
|
||||||
// ★ CORRECTED 2026-09-20 by the manifest reconciliation added below, on its FIRST RUN.
|
// ★ CORRECTED 2026-09-20 by the manifest reconciliation added below, on its FIRST RUN.
|
||||||
|
|
|
||||||
|
|
@ -30,6 +30,9 @@
|
||||||
* Exits non-zero if any leaf fails, so it can become a gate.
|
* Exits non-zero if any leaf fails, so it can become a gate.
|
||||||
*/
|
*/
|
||||||
import { chromium } from 'playwright'
|
import { chromium } from 'playwright'
|
||||||
|
import { requireThisTree } from './_serves-this-tree.mjs'
|
||||||
|
import { resolve as _resolvePath, dirname as _dirnamePath } from 'node:path'
|
||||||
|
import { fileURLToPath as _fileURLToPath } from 'node:url'
|
||||||
|
|
||||||
// The SwiftShader launch. Without these a headless Chromium here has NO GL context at all.
|
// The SwiftShader launch. Without these a headless Chromium here has NO GL context at all.
|
||||||
const GL_ARGS = [
|
const GL_ARGS = [
|
||||||
|
|
@ -41,6 +44,14 @@ const GL_ARGS = [
|
||||||
]
|
]
|
||||||
|
|
||||||
const BASE = process.env.BASE || 'https://nuxtbase.app/plugin-assets/doxa-maps'
|
const BASE = process.env.BASE || 'https://nuxtbase.app/plugin-assets/doxa-maps'
|
||||||
|
const ROOT = _resolvePath(_dirnamePath(_fileURLToPath(import.meta.url)), '..')
|
||||||
|
|
||||||
|
// ★ MEASURE THIS BUILD, OR MEASURE NOTHING. Several worktrees run on one machine and a default port
|
||||||
|
// belongs to whichever server started first — measured 2026-09-24 on :4173, where browser gates
|
||||||
|
// reported confidently about a build nobody here had touched. 75 (EX_TEMPFAIL), not 1: the wrong
|
||||||
|
// tree is a precondition, not a product defect, and the wave runner reports 75 as ⊘ rather than ✗.
|
||||||
|
// A file:// target passes straight through — there is no server there to be wrong about.
|
||||||
|
await requireThisTree(BASE, ROOT, 'MAP-PAINT')
|
||||||
// ★ WIDENED 2026-09-22 — 4 of 12 map profiles were covered, now 11.
|
// ★ WIDENED 2026-09-22 — 4 of 12 map profiles were covered, now 11.
|
||||||
// The four originals were the ones that happened to be under investigation when this file was
|
// The four originals were the ones that happened to be under investigation when this file was
|
||||||
// written. Measuring the manifest showed 12 profiles carry isMap=true, so EIGHT painted leaves
|
// written. Measuring the manifest showed 12 profiles carry isMap=true, so EIGHT painted leaves
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue