feedback1 final: the loadout screen's background layer draws again (pointed out in PR #14)
css/screens/loadout.css: `.lo > * { position: relative }` (one class, a later rule) overrode `.lo__bg { position:
absolute }`, so the mint glow / grid layer was a 0-px flex item and never rendered. `.lo > :where(:not(.lo__bg))`
keeps the one-class specificity for every other layer and never matches the background.
Checked in headless Chrome at 1920x1080 and 844x390 (touch): the layer now covers the overlay (0 px tall before),
every other box of the screen is unchanged, no console errors. Tests: test/ui/loadout.test.js (the cascade; fails on
the old rule), opt-in test/ui/loadout.e2e.test.js (the layer's box and stacking at both sizes). DESIGN §21.25 credits
PR #14 and PR #10 (crossOrigin on the two new Image() loads); CHANGELOG 0.1.1 lines for both.
This commit is contained in:
1 parent
2dba6da598
commit
e7d957b27c
5 files changed
+42
-2
No files matched your search
@@ -68,6 +68,24 @@ describe('干员调配 overlay (real server, headless Chrome)', { skip: !ENABLED
|
||||
while (Date.now() - t0 < timeout) { last = await st(page); if (pred(last)) return last; await sleep(150); }
|
||||
throw new Error(`timed out waiting for ${what}: ${JSON.stringify(last)}`);
|
||||
}
|
||||
/** The overlay's background layer (css/screens/loadout.css .lo__bg — the mint glow and the grid): out of the flex flow
|
||||
* and as large as the overlay, every other layer stacked above it. It used to be a 0-px flex item: `.lo > *` (same
|
||||
* specificity, a later rule) overrode its position: absolute (PR #14). */
|
||||
const bgLayer = (page) => page.evaluate(() => {
|
||||
const lo = document.querySelector('.lo');
|
||||
const el = lo.querySelector(':scope > .lo__bg');
|
||||
const a = lo.getBoundingClientRect(), b = el.getBoundingClientRect();
|
||||
return {
|
||||
position: getComputedStyle(el).position, first: lo.firstElementChild === el, rect: [b.x, b.y, b.width, b.height], lo: [a.x, a.y, a.width, a.height],
|
||||
others: [...lo.children].filter((c) => c !== el).map((c) => getComputedStyle(c).position),
|
||||
};
|
||||
});
|
||||
const assertBgLayer = async (page) => {
|
||||
const bg = await bgLayer(page);
|
||||
assert.equal(bg.position, 'absolute', `the background layer is out of the flex flow ${JSON.stringify(bg)}`);
|
||||
assert.ok(bg.first && bg.rect[3] > 0 && JSON.stringify(bg.rect) === JSON.stringify(bg.lo), `it covers the whole overlay ${JSON.stringify(bg)}`);
|
||||
assert.ok(bg.others.length >= 3 && bg.others.every((p) => p === 'relative'), `every other layer stacks above it ${JSON.stringify(bg)}`);
|
||||
};
|
||||
const clickSel = async (page, sel) => {
|
||||
await page.waitForSelector(sel, { visible: true, timeout: 10000 });
|
||||
await page.click(sel);
|
||||
@@ -78,6 +96,7 @@ describe('干员调配 overlay (real server, headless Chrome)', { skip: !ENABLED
|
||||
await clickSel(page, '.lobby-screen [data-testid="loadout-open"]');
|
||||
await page.waitForSelector('.lo .lo-card', { visible: true, timeout: 15000 });
|
||||
assert.equal(await page.$$eval('.lo-card', (els) => els.length), 112, 'every visible chess');
|
||||
await assertBgLayer(page);
|
||||
await page.screenshot({ path: path.join(OUT, 'loadout-desktop.png') });
|
||||
// search → one card
|
||||
await page.type('.lo-search input', '隐现');
|
||||
@@ -210,6 +229,7 @@ describe('干员调配 overlay (real server, headless Chrome)', { skip: !ENABLED
|
||||
const { ctx, page, problems } = await open({ w: 844, h: 390, touch: true });
|
||||
await page.tap('.lobby-screen [data-testid="loadout-open"]');
|
||||
await page.waitForSelector('.lo .lo-card', { visible: true, timeout: 15000 });
|
||||
await assertBgLayer(page);
|
||||
await page.screenshot({ path: path.join(OUT, 'loadout-phone.png') });
|
||||
// review fix: the shared Button / TextField shrink to 6–7 px text on phones — the overlay's own controls stay readable
|
||||
// and tappable (返回, 全部恢复默认, the detail's 恢复默认, the search input)
|
||||
|
||||
@@ -300,6 +300,19 @@ test('untimed phases show no countdown: the "无倒计时" placeholder of Countd
|
||||
assert.ok(/'无倒计时'/.test(fn) || /return null/.test(fn), 'Countdown marks (or skips) the untimed state');
|
||||
});
|
||||
|
||||
test('the background layer (.lo__bg: mint glow + grid) keeps position: absolute — no later rule of the same specificity overrides it (PR #14)', () => {
|
||||
const css = readFileSync(path.join(ROOT, 'public/css/screens/loadout.css'), 'utf8').replace(/\/\*[\s\S]*?\*\//g, '');
|
||||
assert.match(css, /\.lo__bg\s*\{[^}]*position:\s*absolute;/);
|
||||
// `.lo > *` (one class, after .lo__bg) used to set position: relative on it, a 0-px flex item that never drew
|
||||
assert.ok(!/\.lo\s*>\s*\*\s*\{[^}]*position/.test(css), 'no universal child rule setting position');
|
||||
assert.match(css, /\.lo > :where\(:not\(\.lo__bg\)\) \{ position: relative; \}/, 'the other layers still stack above it, at one class of specificity');
|
||||
const after = css.slice(css.indexOf('.lo__bg'));
|
||||
for (const m of after.matchAll(/([^{}]+)\{([^}]*)\}/g)) {
|
||||
if (!/\.lo__bg\b/.test(m[1]) || /:not\(\.lo__bg\)/.test(m[1])) continue;
|
||||
for (const v of m[2].matchAll(/position:\s*([a-z-]+)/g)) assert.equal(v[1], 'absolute', `${m[1].trim()} changes the layer's position`);
|
||||
}
|
||||
});
|
||||
|
||||
// ---- review fixes (adversarial review of the loadout workstream) -------------------------------------------------------
|
||||
|
||||
/** A net whose replies are released by hand (the socket is ordered: replies come back in request order). */
|
||||
|
||||
Reference in new issue
Block a user