import { expect, test } from '../helpers/serve-dist'; test.use({ javaScriptEnabled: false }); const sectionIds = [ 'start', 'profile', 'experience', 'infrastructure', 'selected-builds', 'additional-work', 'toolkit', 'contact', ] as const; const sectionHeadings = [ 'START', 'PROFILE', 'EXPERIENCE', 'INFRASTRUCTURE', 'SELECTED BUILDS', 'ADDITIONAL WORK', 'TOOLKIT', 'CONTACT', ] as const; const visibleTextLeafSelector = 'h1,h2,h3,p,dt,dd,li,figcaption,a'; const visibleTextSelector = [ `.site-header :is(${visibleTextLeafSelector})`, `.portfolio-main :is(${visibleTextLeafSelector})`, ].join(','); const normalizedText = (value: string): string => value.replace(/\s+/gu, ' ').trim(); const rawVisibleTextSegments = async ( page: import('@playwright/test').Page, rawHtml: string, ): Promise => page.evaluate( ({ html, leafSelector, rootSelector }) => { const document = new DOMParser().parseFromString(html, 'text/html'); return [...document.querySelectorAll(rootSelector)] .filter( (element) => element.closest('[aria-hidden="true"]') === null && element.querySelector(leafSelector) === null, ) .map((element) => (element.textContent ?? '').replace(/\s+/gu, ' ').trim(), ) .filter((text) => text.length > 0); }, { html: rawHtml, leafSelector: visibleTextLeafSelector, rootSelector: visibleTextSelector, }, ); const browserVisibleTextSegments = async ( page: import('@playwright/test').Page, ): Promise => page.locator(visibleTextSelector).evaluateAll( (elements, leafSelector) => elements .filter((element) => { const htmlElement = element as HTMLElement; const style = getComputedStyle(htmlElement); return ( htmlElement.closest('[aria-hidden="true"]') === null && htmlElement.querySelector(leafSelector) === null && htmlElement.getClientRects().length > 0 && style.display !== 'none' && style.visibility !== 'hidden' && style.opacity !== '0' ); }) .map((element) => (element as HTMLElement).innerText.replace(/\s+/gu, ' ').trim(), ) .filter((text) => text.length > 0), visibleTextLeafSelector, ); const assertVisibleUnobscuredFocus = async ( page: import('@playwright/test').Page, ): Promise => { await expect .poll(() => page.evaluate(() => { const active = document.activeElement; if (!(active instanceof HTMLElement)) return false; const rect = active.getBoundingClientRect(); const left = Math.max(0, rect.left); const right = Math.min(window.innerWidth, rect.right); const top = Math.max(0, rect.top); const bottom = Math.min(window.innerHeight, rect.bottom); if (right <= left || bottom <= top) return false; const topElement = document.elementFromPoint( left + (right - left) / 2, top + Math.min(bottom - top, window.innerHeight) / 2, ); const style = getComputedStyle(active); return ( topElement !== null && (active === topElement || active.contains(topElement)) && style.outlineStyle !== 'none' && Number.parseFloat(style.outlineWidth) >= 2 ); }), ) .toBe(true); }; test('keeps every raw SSR reading-path segment visible without JavaScript', async ({ page, distUrl, request, }) => { const pageErrors: string[] = []; const consoleErrors: string[] = []; const failedRequests: string[] = []; page.on('pageerror', (error) => pageErrors.push(error.message)); page.on('console', (message) => { if (message.type() === 'error') consoleErrors.push(message.text()); }); page.on('requestfailed', (request) => { if (request.resourceType() !== 'script') { failedRequests.push( `${request.url()}: ${request.failure()?.errorText ?? 'failed'}`, ); } }); const rawResponse = await request.get(`${distUrl}/`); expect(rawResponse.status()).toBe(200); const rawHtml = await rawResponse.text(); const expectedVisibleText = await rawVisibleTextSegments(page, rawHtml); await page.goto(distUrl, { waitUntil: 'load' }); const actualVisibleText = await browserVisibleTextSegments(page); expect(expectedVisibleText.length).toBeGreaterThan(80); expect(actualVisibleText).toEqual(expectedVisibleText); expect(normalizedText(actualVisibleText.join(' '))).not.toContain( 'preview-semantic-v1', ); await expect(page.locator('h1:visible')).toHaveCount(1); await expect(page.locator('h1')).toHaveText('Luca Pîslaru'); await expect(page.locator('.site-header > p').first()).toHaveText( 'System Administrator & Full-Stack Developer', ); await expect(page.locator('main')).toBeVisible(); await expect( page.locator('nav[aria-label="Portfolio sections"]'), ).toBeVisible(); await expect(page.locator('footer')).toBeVisible(); expect( await page .locator('main > section') .evaluateAll((sections) => sections.map((section) => section.id)), ).toEqual(sectionIds); expect(await page.locator('main > section > h2').allTextContents()).toEqual( sectionHeadings, ); for (const evidence of [ 'Professional systems operations', 'Secure self-hosted platform and lifecycle', 'Private self-hosted medication tracker', 'Footy Tracker', 'Linux', 'Docker', 'Python', 'Vue.js', ]) { await expect( page.getByText(evidence, { exact: true }).first(), ).toBeVisible(); } const email = page.locator('a[href="mailto:luca.pislaru@gmail.com"]'); await expect(email).toBeVisible(); await expect(email).toHaveText('luca.pislaru@gmail.com'); await expect( page.getByText( 'For a current CV or role-specific information, contact me directly.', { exact: true }, ), ).toBeVisible(); for (const title of [ 'Private self-hosted medication tracker', 'Private healthcare platform', 'Private game prototype', ]) { await expect( page.locator('article').filter({ hasText: title }).locator('a'), ).toHaveCount(0); } await expect(page.locator('a[download]')).toHaveCount(0); expect(pageErrors).toEqual([]); expect(consoleErrors).toEqual([]); expect(failedRequests).toEqual([]); }); test('activating the skip link focuses visible portfolio content without JavaScript', async ({ page, distUrl, }) => { await page.goto(distUrl, { waitUntil: 'load' }); await page.keyboard.press('Tab'); await expect(page.locator('.skip-link')).toBeFocused(); await page.keyboard.press('Enter'); await expect(page).toHaveURL(`${distUrl}/#portfolio-content`); await expect(page.locator('#portfolio-content')).toBeFocused(); await expect(page.locator('#portfolio-content')).toHaveAttribute( 'tabindex', '-1', ); await assertVisibleUnobscuredFocus(page); }); test('retains native section navigation when scripts are disabled', async ({ page, distUrl, }) => { await page.goto(distUrl, { waitUntil: 'load' }); await page.locator('nav a[href="#contact"]').click(); await expect(page).toHaveURL(`${distUrl}/#contact`); await expect(page.locator('#contact')).toBeInViewport(); await expect(page.locator('#contact a[href^="mailto:"]')).toBeVisible(); });