feat: polish nightdrive road sun and signage

This commit is contained in:
2026-09-03 00:29:26 +03:00
parent bc18bc2043
commit a03d4d8dba
44 changed files with 1208 additions and 202 deletions

View File

@@ -1,4 +1,4 @@
import { expect, test } from '../helpers/serve-dist';
import { clickNavigationLink, expect, test } from '../helpers/serve-dist';
import {
installSceneInstrumentation,
readSceneInstrumentation,
@@ -104,6 +104,65 @@ test('draws only the independently eligible next roadside sign during passive fo
expect([...new Set(labels)]).toEqual([oracle.expectedLabel]);
});
test('keeps a readable sign immutable through reversal, resize, and a multi-section jump', async ({
page,
distUrl,
}) => {
await page.setViewportSize({ width: 1440, height: 900 });
await page.goto(distUrl, { waitUntil: 'domcontentloaded' });
await expect(page.locator('.journey-world')).toHaveAttribute('data-scene-state', 'running');
const oracle = await page.evaluate(() => {
const profile = document.getElementById('profile-heading');
if (!(profile instanceof HTMLElement)) throw new Error('Missing profile heading');
const viewportHeight = window.visualViewport?.height ?? window.innerHeight;
const headingTop = profile.getBoundingClientRect().top + window.scrollY;
return {
destination: Math.max(1, headingTop - viewportHeight * (0.35 + 0.8)),
viewportHeight,
};
});
await page.mouse.wheel(0, 1);
for (let y = 1; y < oracle.destination; y += oracle.viewportHeight * 0.5) {
await page.evaluate((nextY) => window.scrollTo(0, nextY), y);
await waitForOneAnimationFrame(page);
}
await page.evaluate((destination) => window.scrollTo(0, destination), oracle.destination);
await expect.poll(async () => (await readSceneInstrumentation(page)).routeLabelsDrawn)
.toContain('Profile');
await page.waitForTimeout(1_250);
await page.mouse.wheel(0, -120);
await page.setViewportSize({ width: 844, height: 390 });
await page.evaluate(() => {
const target = document.getElementById('selected-builds-heading');
if (!(target instanceof HTMLElement)) throw new Error('Missing selected builds heading');
window.scrollTo(0, target.getBoundingClientRect().top + window.scrollY);
});
await page.waitForTimeout(450);
const labels = (await readSceneInstrumentation(page)).routeLabelsDrawn;
expect([...new Set(labels)]).toEqual(['Profile']);
expect((await readSceneInstrumentation(page)).maximumCanvasCount).toBeLessThanOrEqual(1);
});
test('suppresses roadside signs for explicit navigation and history restoration', async ({
page,
distUrl,
}) => {
await page.goto(distUrl, { waitUntil: 'domcontentloaded' });
await expect(page.locator('.journey-world')).toHaveAttribute('data-scene-state', 'running');
await clickNavigationLink(page, '#selected-builds');
await expect(page.locator('#selected-builds-heading')).toBeFocused();
await page.waitForTimeout(400);
expect((await readSceneInstrumentation(page)).routeLabelsDrawn).toEqual([]);
await page.goBack({ waitUntil: 'domcontentloaded' });
await page.waitForTimeout(400);
expect((await readSceneInstrumentation(page)).routeLabelsDrawn).toEqual([]);
});
function colorEnergy(color: string): number {
const value = Number.parseInt(color.slice(1), 16);
return ((value >> 16) & 0xff) + ((value >> 8) & 0xff) + (value & 0xff);