Firefox app-unit web-compat experiments #
Standalone scripts probing whether Firefox's layout-geometry outlier behavior
(docs/firefox-app-units.md) has an observable web-compatibility consequence, rather than
being a sub-pixel difference no user or script would ever see. Separate from the oracle
service: these launch Playwright directly so each script can pick its own
deviceScaleFactor per run, which oracle/oracle.mjs's fixed-DPR-1 contexts do not
expose, and they leave the oracle's request/response wire contract (docs/dump-format.md)
untouched.
Setup #
npm --prefix experiments/firefox-compat install
npx playwright install chromium firefox webkit # already cached on a dev host that has run the oracle
Scripts #
engines.mjs-- shared engine-launch and paged-measurement helpers.wrap-sweep.mjs-- sweeps container widths for fractional-percentage siblings (thirds, sevenths, sixths, and a 12-column 8.33333% grid) laid out as floats, inline-blocks andflex-wrapitems, checking whether the three engines agree on which row each item lands in.known-bugs.mjs-- direct reproductions of two confirmed Bugzilla/webcompat.com reports that name app-unit rounding as the cause (bug 1923245, bug 1959132).scrollbar-sweep.mjs-- the same twelve-level nested-percentage shape ascrates/harness/src/cases.rs'srecipe_nesting_depth, insideoverflow: auto, swept across widths, checking for a scrollbar appearing in only one engine.integer-rounding.mjs-- the same nested chain, reading backoffsetWidth/clientWidth(integers, per CSSOM View) rather than the sub-pixelgetBoundingClientRectthe base harness compares, across all four device pixel ratios.line-breaking.mjs-- the same nested chain wrapping a line of text, checking whether the wrap boundary (one line vs two) ever differs across engines. Caveat: text introduces font shaping, a confound the base harness avoids entirely.deep-nesting-direct.mjs-- reproduces the base harness's own worst-case shape (twelve levels ofwidth: 83.333%) directly and reads the raw sub-pixel width at DPR 1, 1.5, 2 and 3, to check whether the mechanism's magnitude is DPR-dependent (it should not be -- app units and LayoutUnit both quantize CSS pixels, not device pixels).pixel-seam.mjs-- screenshots (decoded withpngjs) a row of touching, alternating-color boxes at each DPR, checking for a stripe of the container's own background color where two boxes should abut exactly.
Each script writes its raw results to results/*.json (gitignored) and prints a summary,
including every divergent case found, to stdout.
Running #
node wrap-sweep.mjs
node known-bugs.mjs
node scrollbar-sweep.mjs
node integer-rounding.mjs
node line-breaking.mjs
node deep-nesting-direct.mjs
node pixel-seam.mjs
Each launches its own Chromium/Firefox/WebKit instances and can take several minutes for the wider sweeps; run one at a time to avoid resource contention on a dev host.