The sweep renders every served page in a headless Chromium at 390, 768, 1024, 1280 and 1600 in light and dark (the hero at rest and at each step), reads every visible run of text and flags text covered by another element, clipped by overflow hidden, or past the viewport; a fixture with one deliberate overlap of each kind is flagged before any sweep is trusted. It runs on a build box when this machine has no browser (infra/build-server/overlap-browser.sh installs Chromium there without root). Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
57 lines
4 KiB
Bash
57 lines
4 KiB
Bash
#!/usr/bin/env bash
|
|
# A headless Chromium for the text-overlap sweep (tools/ci/overlap-check.mjs) on a build box, without root. The build user
|
|
# has no sudo, so Playwright's `install --with-deps` cannot add the X and GTK libraries Chromium links; this script downloads
|
|
# the same Ubuntu packages with apt-get download (no root needed), unpacks them into a sysroot and points LD_LIBRARY_PATH
|
|
# at it, plus two font packages behind a private fontconfig file (the box ships no fonts at all: fc-list is empty, and
|
|
# text with no font has no width). Idempotent; re-run after a box re-provision.
|
|
#
|
|
# infra/build-server/overlap-browser.sh on the box (run-from-mac.sh copies and runs it; or ssh and run by hand)
|
|
# . /srv/builds/_bin/overlap/env.sh what a caller sources before `node tools/ci/overlap-check.mjs`
|
|
#
|
|
# Installed 7 October 2026 on igneum-build-2 (Ubuntu 24.04.5, node 22): playwright 1.56 with chromium 1194 (headless shell
|
|
# and full), 36 packages in the sysroot, Liberation and DejaVu fonts. A page with 20 px sans-serif text measured 23 px high
|
|
# through it, so glyphs have real metrics there.
|
|
set -euo pipefail
|
|
ROOT="${OVERLAP_ROOT:-/srv/builds/_bin/overlap}"
|
|
PW_VERSION="${PW_VERSION:-1.56}"
|
|
mkdir -p "$ROOT/debs" "$ROOT/sysroot" "$ROOT/fonts" "$ROOT/fc-cache"
|
|
cd "$ROOT"
|
|
[ -f package.json ] || npm init -y >/dev/null
|
|
if ! node -e "require('playwright')" 2>/dev/null; then npm i --no-audit --no-fund "playwright@$PW_VERSION" | tail -1; fi
|
|
# the browser download (Playwright keeps it under ~/.cache/ms-playwright; a second run finds it and does nothing)
|
|
PLAYWRIGHT_SKIP_VALIDATE_HOST_REQUIREMENTS=1 npx playwright install chromium 2>&1 | tail -1 || true
|
|
PKGS="libatk1.0-0t64 libatk-bridge2.0-0t64 libatspi2.0-0t64 libx11-6 libxcomposite1 libxdamage1 libxext6 libxfixes3 libxrandr2 libgbm1 libxcb1
|
|
libasound2t64 libxrender1 libxau6 libxdmcp6 libwayland-server0 libwayland-client0 libcups2t64 libcairo2 libpango-1.0-0 libpangocairo-1.0-0
|
|
libpangoft2-1.0-0 libharfbuzz0b libfribidi0 libthai0 libdatrie1 libpixman-1-0 libxcb-render0 libxcb-shm0 libavahi-client3 libavahi-common3
|
|
libxi6 libfontconfig1 libgraphite2-3 fonts-liberation fonts-dejavu-core"
|
|
cd "$ROOT/debs"
|
|
# shellcheck disable=SC2086
|
|
apt-get download $PKGS 2>&1 | grep -v '^Get:' | tail -1 || true
|
|
for d in ./*.deb; do dpkg -x "$d" "$ROOT/sysroot"; done
|
|
find "$ROOT/sysroot" -name '*.ttf' -exec cp -n {} "$ROOT/fonts/" \;
|
|
cat >"$ROOT/fonts.conf" <<EOF
|
|
<?xml version="1.0"?><!DOCTYPE fontconfig SYSTEM "fonts.dtd">
|
|
<fontconfig><dir>$ROOT/fonts</dir><cachedir>$ROOT/fc-cache</cachedir>
|
|
<alias><family>sans-serif</family><prefer><family>Liberation Sans</family></prefer></alias>
|
|
<alias><family>serif</family><prefer><family>Liberation Serif</family></prefer></alias>
|
|
<alias><family>monospace</family><prefer><family>Liberation Mono</family></prefer></alias></fontconfig>
|
|
EOF
|
|
cat >"$ROOT/env.sh" <<EOF
|
|
export LD_LIBRARY_PATH=$ROOT/sysroot/usr/lib/x86_64-linux-gnu\${LD_LIBRARY_PATH:+:\$LD_LIBRARY_PATH}
|
|
export FONTCONFIG_FILE=$ROOT/fonts.conf
|
|
export NODE_PATH=$ROOT/node_modules\${NODE_PATH:+:\$NODE_PATH}
|
|
export IGNEUM_PLAYWRIGHT_DIR=$ROOT
|
|
EOF
|
|
# shellcheck disable=SC1091
|
|
. "$ROOT/env.sh"
|
|
SHELL_BIN="$(ls -d "$HOME"/.cache/ms-playwright/chromium_headless_shell-*/chrome-linux/headless_shell | tail -1)"
|
|
if ldd "$SHELL_BIN" | grep -q 'not found'; then echo "overlap-browser: libraries still missing:"; ldd "$SHELL_BIN" | grep 'not found'; exit 1; fi
|
|
cat >"$ROOT/smoke.cjs" <<'EOF2'
|
|
const { chromium } = require("playwright");
|
|
(async () => { const b = await chromium.launch({ args: ["--no-sandbox"] }); const p = await b.newPage();
|
|
await p.setContent('<p id=a style="font:20px sans-serif">Hello overlap world</p>');
|
|
const h = await p.evaluate(() => document.getElementById("a").getBoundingClientRect().height); await b.close();
|
|
if (!(h > 15 && h < 40)) { console.error("overlap-browser: text has no metrics (height " + h + ")"); process.exit(1); }
|
|
console.log("overlap-browser: ready at " + __dirname + " (20 px text measures " + h + " px; source " + __dirname + "/env.sh)"); })();
|
|
EOF2
|
|
cd "$ROOT" && node smoke.cjs
|