import { readFileSync } from 'node:fs'; import { resolve } from 'node:path'; import { describe, expect, it } from 'vitest'; import { validateProductionInputs } from '@/content/schemas'; import { render } from '@/entry-server'; const fixture = (name: string): unknown => JSON.parse(readFileSync(resolve(process.cwd(), 'tests/fixtures', name), 'utf8')); const validInputs = validateProductionInputs( fixture('portfolio-content.valid.json'), fixture('asset-manifest.valid.json'), fixture('site-config.preview.json'), new URL('file:///prepared-assets/'), ); const renderedDocument = async (): Promise => { const document = globalThis.document.implementation.createHTMLDocument('Portfolio'); document.body.innerHTML = await render('/', validInputs); return document; }; describe('semantic portfolio document', () => { it('renders the complete landmark and heading reading structure on the server', async () => { const document = await renderedDocument(); expect(document.querySelectorAll('header')).toHaveLength(1); expect(document.querySelector('nav[aria-label="Portfolio sections"]')).not.toBeNull(); expect(document.querySelectorAll('main')).toHaveLength(1); expect(document.querySelectorAll('footer')).toHaveLength(1); expect(document.querySelectorAll('h1')).toHaveLength(1); expect(document.querySelector('h1')?.textContent).toBe('Luca Pîslaru'); expect([...document.querySelectorAll('main > section')].map((section) => section.id)).toEqual([ 'start', 'profile', 'experience', 'infrastructure', 'selected-builds', 'additional-work', 'toolkit', 'contact', ]); expect([...document.querySelectorAll('main > section')].every((section) => section.hasAttribute('aria-labelledby'))).toBe(true); expect([...document.querySelectorAll('main > section > h2')].map((heading) => heading.textContent)).toEqual([ 'START', 'PROFILE', 'EXPERIENCE', 'INFRASTRUCTURE', 'SELECTED BUILDS', 'ADDITIONAL WORK', 'TOOLKIT', 'CONTACT', ]); expect(document.querySelector('h2 + h4')).toBeNull(); }); it('keeps native section links and visible contact available without JavaScript', async () => { const document = await renderedDocument(); const navigation = document.querySelector('nav[aria-label="Portfolio sections"]')!; expect([...navigation.querySelectorAll('a')].map((link) => link.getAttribute('href'))).toEqual([ '#start', '#profile', '#experience', '#infrastructure', '#selected-builds', '#additional-work', '#toolkit', '#contact', ]); const email = document.querySelector('a[href="mailto:hello@example.test"]'); expect(email?.textContent).toBe('hello@example.test'); expect(document.body.textContent).toContain('For a current CV or role-specific information, contact me directly.'); }); it('includes systems and software evidence in server-rendered content', async () => { const document = await renderedDocument(); expect(document.body.textContent).toContain('Professional systems operations'); expect(document.body.textContent).toContain('Secure self-hosted platform and lifecycle'); expect(document.body.textContent).toContain('Private self-hosted medication tracker'); expect(document.body.textContent).toContain('Footy Tracker'); }); });