Files
Portfolio/tests/browser/scene-controls.spec.ts

90 lines
4.6 KiB
TypeScript

import { expect, test } from '../helpers/serve-dist';
test('keeps the decorative world separate from the semantic reading path', async ({ page, distUrl }) => {
await page.goto(distUrl, { waitUntil: 'domcontentloaded' });
await expect(page.locator('#journey-scene-description')).toContainText('night');
await expect(page.locator('.journey-world')).toHaveAttribute('aria-hidden', 'true');
await expect(page.locator('.journey-poster')).toHaveAttribute('alt', '');
await expect(page.locator('.journey-poster')).toHaveAttribute('width', '1600');
await expect(page.locator('main#portfolio-content')).toBeVisible();
});
test('keeps the desktop identity and navigation in a paint layer above the world', async ({ page, distUrl }) => {
await page.setViewportSize({ width: 1440, height: 900 });
await page.goto(distUrl, { waitUntil: 'domcontentloaded' });
const layers = await page.evaluate(() => {
const world = document.querySelector<HTMLElement>('.journey-world');
const header = document.querySelector<HTMLElement>('.site-header');
const heading = document.querySelector<HTMLElement>('.site-header h1');
const navigation = document.querySelector<HTMLElement>('.site-navigation');
if (!world || !header || !heading || !navigation) throw new Error('Missing top-screen structure');
const worldStyle = getComputedStyle(world);
const headerStyle = getComputedStyle(header);
return {
worldZ: Number(worldStyle.zIndex),
headerZ: Number(headerStyle.zIndex),
headerPosition: headerStyle.position,
headingVisible: heading.getBoundingClientRect().width > 0 && heading.getBoundingClientRect().height > 0,
navigationVisible: navigation.getBoundingClientRect().width > 0 && navigation.getBoundingClientRect().height > 0,
headerOpacity: Number.parseFloat(headerStyle.backgroundColor.match(/[\d.]+(?=\))/gu)?.at(-1) ?? '1'),
};
});
expect(layers).toMatchObject({
headerPosition: 'relative',
headingVisible: true,
navigationVisible: true,
});
expect(layers.headerZ).toBeGreaterThan(layers.worldZ);
expect(layers.headerOpacity).toBeGreaterThanOrEqual(0.94);
});
test('provides native motion and quality controls with visible state', async ({ page, distUrl }) => {
await page.goto(distUrl, { waitUntil: 'domcontentloaded' });
const quality = page.getByLabel('Quality control');
await expect(quality).toBeVisible();
await expect(page.getByRole('button', { name: 'Pause motion' })).toBeVisible();
await expect(page.getByRole('status')).toContainText('Motion:');
const canvas = page.locator('.journey-canvas');
const originalCanvas = await canvas.elementHandle();
const originalGeneration = await page.locator('.journey-world').getAttribute('data-scene-generation');
await page.getByRole('button', { name: 'Pause motion' }).click();
await expect(page.getByRole('button', { name: 'Resume motion' })).toBeVisible();
await expect(canvas).toHaveCount(1);
await expect(page.locator('.journey-world')).toHaveAttribute('data-scene-generation', originalGeneration ?? '');
expect(await originalCanvas?.evaluate((element) => element.isConnected)).toBe(true);
await page.getByRole('button', { name: 'Resume motion' }).click();
await expect(page.getByRole('button', { name: 'Pause motion' })).toBeVisible();
await expect(canvas).toHaveCount(1);
await expect(page.locator('.journey-world')).toHaveAttribute('data-scene-generation', originalGeneration ?? '');
expect(await originalCanvas?.evaluate((element) => element.isConnected)).toBe(true);
await quality.selectOption('static');
await expect(page.getByRole('button', { name: 'Enable motion' })).toBeVisible();
await expect(page.locator('.journey-canvas')).toHaveCount(0);
await expect(page.getByRole('status')).toContainText('Motion: static');
});
test('never creates a canvas when the system requests reduced motion', async ({ page, distUrl }) => {
await page.emulateMedia({ reducedMotion: 'reduce' });
await page.goto(distUrl, { waitUntil: 'domcontentloaded' });
await expect(page.locator('.journey-canvas')).toHaveCount(0);
await expect(page.getByRole('status')).toContainText('reduced motion requested');
await expect(page.getByLabel('Quality control')).toBeVisible();
});
test('shows ARRIVED from the authoritative section snapshot at Contact', async ({ page, distUrl }) => {
await page.goto(distUrl, { waitUntil: 'domcontentloaded' });
await page.locator('nav a[href="#contact"]').click();
await expect(page.locator('.journey-hud')).toContainText('Contact');
await expect(page.locator('.journey-hud')).toContainText('ARRIVED');
await expect(page.locator('.journey-hud')).toContainText('100%');
});