test: align navigation and sign label checks with the gantry
This commit is contained in:
@@ -18,6 +18,16 @@ const sections = [
|
|||||||
|
|
||||||
test.beforeEach(async ({ page }) => installSceneInstrumentation(page));
|
test.beforeEach(async ({ page }) => installSceneInstrumentation(page));
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The gantry window pre-draws its hover twin for the exit it rests on, which
|
||||||
|
* is Start at load. That is a window texture, not a roadside sign, so it is
|
||||||
|
* left out of the roadside label checks; Start never has a roadside sign.
|
||||||
|
*/
|
||||||
|
function roadsideLabels(labels: readonly string[]): string[] {
|
||||||
|
return labels.filter((label) => label !== 'Start');
|
||||||
|
}
|
||||||
|
|
||||||
test('keeps navigation, HUD, progress, chapter, and arrival on the same next-frame section snapshot', async ({
|
test('keeps navigation, HUD, progress, chapter, and arrival on the same next-frame section snapshot', async ({
|
||||||
page,
|
page,
|
||||||
distUrl,
|
distUrl,
|
||||||
@@ -105,7 +115,7 @@ test('draws only the independently eligible next roadside sign during passive fo
|
|||||||
await waitForOneAnimationFrame(page);
|
await waitForOneAnimationFrame(page);
|
||||||
|
|
||||||
await expect.poll(async () => (await readSceneInstrumentation(page)).routeLabelsDrawn).toContain(oracle.expectedLabel);
|
await expect.poll(async () => (await readSceneInstrumentation(page)).routeLabelsDrawn).toContain(oracle.expectedLabel);
|
||||||
const labels = (await readSceneInstrumentation(page)).routeLabelsDrawn;
|
const labels = roadsideLabels((await readSceneInstrumentation(page)).routeLabelsDrawn);
|
||||||
expect([...new Set(labels)]).toEqual([oracle.expectedLabel]);
|
expect([...new Set(labels)]).toEqual([oracle.expectedLabel]);
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -235,12 +245,12 @@ test('shows exactly one destination sign for a navigator click and suppresses hi
|
|||||||
await expect(page.locator('#selected-builds-heading')).toBeFocused();
|
await expect(page.locator('#selected-builds-heading')).toBeFocused();
|
||||||
await page.waitForTimeout(2_400);
|
await page.waitForTimeout(2_400);
|
||||||
const afterRepeat = await readSceneInstrumentation(page);
|
const afterRepeat = await readSceneInstrumentation(page);
|
||||||
expect(afterRepeat.routeLabelsDrawn).toEqual(['Selected builds']);
|
expect(roadsideLabels(afterRepeat.routeLabelsDrawn)).toEqual(['Selected builds']);
|
||||||
expect(countSignPresentations(afterRepeat.signFrames, 'selected-builds')).toBe(1);
|
expect(countSignPresentations(afterRepeat.signFrames, 'selected-builds')).toBe(1);
|
||||||
|
|
||||||
await page.goBack({ waitUntil: 'domcontentloaded' });
|
await page.goBack({ waitUntil: 'domcontentloaded' });
|
||||||
await page.waitForTimeout(400);
|
await page.waitForTimeout(400);
|
||||||
expect((await readSceneInstrumentation(page)).routeLabelsDrawn).toEqual(['Selected builds']);
|
expect(roadsideLabels((await readSceneInstrumentation(page)).routeLabelsDrawn)).toEqual(['Selected builds']);
|
||||||
});
|
});
|
||||||
|
|
||||||
test('keeps the non-navigator Explore work section jump sign-suppressed', async ({
|
test('keeps the non-navigator Explore work section jump sign-suppressed', async ({
|
||||||
@@ -430,7 +440,7 @@ test('moves an already-readable portrait sign into navigator-safe placement with
|
|||||||
|
|
||||||
const instrumentation = await readSceneInstrumentation(page);
|
const instrumentation = await readSceneInstrumentation(page);
|
||||||
expect(countSignPresentations(instrumentation.signFrames, 'profile')).toBe(1);
|
expect(countSignPresentations(instrumentation.signFrames, 'profile')).toBe(1);
|
||||||
expect(instrumentation.routeLabelsDrawn).toEqual(['Profile']);
|
expect(roadsideLabels(instrumentation.routeLabelsDrawn)).toEqual(['Profile']);
|
||||||
});
|
});
|
||||||
|
|
||||||
test('re-arms passive signage after a navigator round trip to Start', async ({
|
test('re-arms passive signage after a navigator round trip to Start', async ({
|
||||||
@@ -495,7 +505,7 @@ test('reconciles an idle rapid jump to the latest active route without flashing
|
|||||||
frame.targetId === 'selected-builds'
|
frame.targetId === 'selected-builds'
|
||||||
))?.phase, { intervals: [16], timeout: 5_000 }).toBe('dwell');
|
))?.phase, { intervals: [16], timeout: 5_000 }).toBe('dwell');
|
||||||
const instrumentation = await readSceneInstrumentation(page);
|
const instrumentation = await readSceneInstrumentation(page);
|
||||||
expect([...new Set(instrumentation.routeLabelsDrawn)])
|
expect([...new Set(roadsideLabels(instrumentation.routeLabelsDrawn))])
|
||||||
.toEqual(['Selected builds']);
|
.toEqual(['Selected builds']);
|
||||||
const dwell = instrumentation.signFrames.findLast((frame) => (
|
const dwell = instrumentation.signFrames.findLast((frame) => (
|
||||||
frame.targetId === 'selected-builds' && frame.phase === 'dwell'
|
frame.targetId === 'selected-builds' && frame.phase === 'dwell'
|
||||||
|
|||||||
@@ -8,8 +8,11 @@ test('desktop navigation docks without stretching labels or shifting the documen
|
|||||||
await page.evaluate(() => document.fonts.ready);
|
await page.evaluate(() => document.fonts.ready);
|
||||||
const nav = page.locator('.site-navigation');
|
const nav = page.locator('.site-navigation');
|
||||||
await expect(nav).toHaveAttribute('data-enhanced', 'true');
|
await expect(nav).toHaveAttribute('data-enhanced', 'true');
|
||||||
|
// Since round 5 the bar is a full-bleed overhead gantry: it is docked at
|
||||||
|
// the top and unscaled from the first frame instead of growing into place.
|
||||||
const surfaceScale = () => nav.evaluate(el => new DOMMatrixReadOnly(getComputedStyle(el, '::before').transform).a);
|
const surfaceScale = () => nav.evaluate(el => new DOMMatrixReadOnly(getComputedStyle(el, '::before').transform).a);
|
||||||
expect(await surfaceScale()).toBeLessThan(1);
|
expect(await surfaceScale()).toBe(1);
|
||||||
|
expect((await nav.boundingBox())!.y).toBeLessThan(1);
|
||||||
const label = nav.locator('a').first();
|
const label = nav.locator('a').first();
|
||||||
const initialFont = await label.evaluate(el => getComputedStyle(el).fontSize);
|
const initialFont = await label.evaluate(el => getComputedStyle(el).fontSize);
|
||||||
// Measure the content beside this fixed header, not unrelated lazy media
|
// Measure the content beside this fixed header, not unrelated lazy media
|
||||||
@@ -26,7 +29,7 @@ test('desktop navigation docks without stretching labels or shifting the documen
|
|||||||
expect(await label.evaluate(el => getComputedStyle(el).fontSize)).toBe(initialFont);
|
expect(await label.evaluate(el => getComputedStyle(el).fontSize)).toBe(initialFont);
|
||||||
expect(await heroGeometry()).toEqual(initialHero);
|
expect(await heroGeometry()).toEqual(initialHero);
|
||||||
await page.evaluate(() => scrollTo(0, 0));
|
await page.evaluate(() => scrollTo(0, 0));
|
||||||
await expect.poll(async () => (await nav.boundingBox())!.y).toBeGreaterThan(10);
|
await expect.poll(async () => (await nav.boundingBox())!.y).toBeLessThan(1);
|
||||||
});
|
});
|
||||||
|
|
||||||
test('selected navigation has rounded inset highlights', async ({ page, distUrl }) => {
|
test('selected navigation has rounded inset highlights', async ({ page, distUrl }) => {
|
||||||
@@ -34,7 +37,16 @@ test('selected navigation has rounded inset highlights', async ({ page, distUrl
|
|||||||
const disclosure = page.locator('.site-navigation summary');
|
const disclosure = page.locator('.site-navigation summary');
|
||||||
if (await disclosure.isVisible()) await disclosure.click();
|
if (await disclosure.isVisible()) await disclosure.click();
|
||||||
const selected = page.locator('.site-navigation a[aria-current="page"]');
|
const selected = page.locator('.site-navigation a[aria-current="page"]');
|
||||||
expect(await selected.evaluate(el => parseFloat(getComputedStyle(el).borderTopLeftRadius))).toBeGreaterThanOrEqual(5);
|
// On the desktop gantry the current exit is marked by its amber lane lamp
|
||||||
|
// (the li::after rule) rather than a rounded inset; the menu keeps the inset.
|
||||||
|
const marker = await selected.evaluate(el => {
|
||||||
|
const lamp = getComputedStyle(el.parentElement!, '::after');
|
||||||
|
return {
|
||||||
|
radius: parseFloat(getComputedStyle(el).borderTopLeftRadius),
|
||||||
|
lamp: lamp.content !== 'none' && parseFloat(lamp.blockSize) >= 2,
|
||||||
|
};
|
||||||
|
});
|
||||||
|
expect(marker.radius >= 5 || marker.lamp).toBe(true);
|
||||||
await selected.focus();
|
await selected.focus();
|
||||||
await page.keyboard.press('Shift');
|
await page.keyboard.press('Shift');
|
||||||
expect(await selected.evaluate(el => getComputedStyle(el).outlineStyle)).not.toBe('none');
|
expect(await selected.evaluate(el => getComputedStyle(el).outlineStyle)).not.toBe('none');
|
||||||
|
|||||||
Reference in New Issue
Block a user