fix: restore signs after navigation

This commit is contained in:
2026-09-03 02:59:10 +03:00
parent cce018d3cb
commit 4404c07f93
5 changed files with 71 additions and 8 deletions

View File

@@ -163,6 +163,36 @@ test('suppresses roadside signs for explicit navigation and history restoration'
expect((await readSceneInstrumentation(page)).routeLabelsDrawn).toEqual([]);
});
test('restores the next sign after a navigator round trip', async ({
page,
distUrl,
}) => {
await page.goto(distUrl, { waitUntil: 'domcontentloaded' });
await expect(page.locator('.journey-world')).toHaveAttribute('data-scene-state', 'running');
await clickNavigationLink(page, '#profile');
await expect(page.locator('#profile-heading')).toBeFocused();
await clickNavigationLink(page, '#start');
await expect(page.locator('#start-heading')).toBeFocused();
const destination = 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;
return Math.max(
1,
profile.getBoundingClientRect().top + window.scrollY
- viewportHeight * (0.35 + 0.45),
);
});
await page.mouse.wheel(0, 1);
await page.evaluate((scrollY) => window.scrollTo(0, scrollY), destination);
await expect.poll(async () => (
await readSceneInstrumentation(page)
).signFrames.some((frame) => frame.targetId === 'profile')).toBe(true);
});
test('reconciles an idle rapid jump to the latest active route without flashing intermediates', async ({
page,
distUrl,

View File

@@ -458,4 +458,30 @@ describe('clock-driven sign lifecycle', () => {
candidateId: 'experience',
}))).toBeNull();
});
it('starts a fresh passive sign traversal after explicit navigation', () => {
const controller = createSignController();
controller.sample(sample());
controller.sample(sample({ now: 1_200, direction: 0, deltaY: 0 }));
controller.sample(sample({ now: 2_600, direction: 0, deltaY: 0 }));
controller.sample(sample({ now: 3_300, direction: 0, deltaY: 0 }));
expect(controller.sample(sample({
now: 3_400,
source: 'explicit-navigation',
activeSectionId: 'contact',
candidateId: null,
candidateDistanceVh: null,
}))).toBeNull();
expect(controller.sample(sample({
now: 3_500,
source: 'explicit-navigation',
activeSectionId: 'start',
}))).toBeNull();
expect(controller.sample(sample({ now: 3_600 }))).toMatchObject({
targetId: 'profile',
phase: 'anticipate',
});
});
});