import { chromium } from '@playwright/test'; import fs from 'node:fs';import path from 'node:path';import {pathToFileURL} from 'node:url';import assert from 'node:assert/strict';import crypto from 'node:crypto'; const root=path.resolve(import.meta.dirname,'..');const file=process.env.DECK_PATH||path.join(root,'dist/presentation-html-demo-0.1.0.html'); const executablePath=process.env.CHROMIUM_EXECUTABLE; const browser=await chromium.launch({headless:true,...(executablePath?{executablePath}:{})}); const report={file,sha256:crypto.createHash('sha256').update(fs.readFileSync(file)).digest('hex'),runs:[]}; fs.mkdirSync(path.join(root,'evidence'),{recursive:true}); try { for(const reducedMotion of ['no-preference','reduce']){ const context=await browser.newContext({viewport:{width:1440,height:900},reducedMotion,offline:true});const page=await context.newPage();const errors=[],requests=[]; page.on('pageerror',e=>errors.push(String(e)));page.on('console',m=>{if(m.type()==='error')errors.push(m.text());});page.on('request',r=>{if(/^https?:/.test(r.url()))requests.push(r.url());}); await page.goto(pathToFileURL(file).href);await page.waitForFunction(()=>window.deckReady);await page.evaluate(()=>document.fonts.ready); assert.equal(await page.evaluate(()=>document.fonts.check('28px "Work Sans"')),true); assert.equal(await page.evaluate(()=>getComputedStyle(document.body).backgroundColor),'rgb(16, 30, 37)'); assert.equal(await page.evaluate(()=>getComputedStyle(document.querySelector('.reveal')).color),'rgb(244, 243, 237)'); const slides=await page.locator('.slides>section').count();assert.equal(slides,6); let testedNodes=0; for(let i=0;iReveal.slide(i),i);await page.waitForTimeout(900); const clipped=await page.evaluate(()=>{const s=Reveal.getCurrentSlide(),r=s.getBoundingClientRect();return [...s.querySelectorAll('h1,h2,p,strong,svg text,button')].filter(e=>{const b=e.getBoundingClientRect();return b.leftr.right+2||b.topr.bottom+2;}).map(e=>e.textContent);});assert.deepEqual(clipped,[],'Clipping slide '+i); const nodes=page.locator('.present [data-node]'); for(let j=0;jReveal.slide(0));await page.keyboard.press('ArrowRight');assert.equal(await page.evaluate(()=>Reveal.getIndices().h),1);await page.keyboard.press('ArrowLeft');assert.equal(await page.evaluate(()=>Reveal.getIndices().h),0); await page.keyboard.press('Escape');assert.equal(await page.evaluate(()=>Reveal.isOverview()),true);await page.keyboard.press('Escape'); await page.locator('#fullscreen').click();await page.waitForFunction(()=>!!document.fullscreenElement);assert.equal(await page.locator('#fullscreen').getAttribute('aria-pressed'),'true');await page.keyboard.press('f');await page.waitForFunction(()=>!document.fullscreenElement); await page.keyboard.press('f');await page.waitForFunction(()=>!!document.fullscreenElement);await page.locator('#fullscreen').click();await page.waitForFunction(()=>!document.fullscreenElement); await page.evaluate(()=>Reveal.slide(3));await page.waitForFunction(()=>location.hash.includes('sequence'));await page.reload();await page.waitForFunction(()=>window.deckReady);assert.equal(await page.evaluate(()=>Reveal.getIndices().h),3); if(reducedMotion==='reduce'){assert.equal(await page.evaluate(()=>presentationQA.active()),0);assert.equal(await page.locator('#motion').getAttribute('aria-pressed'),'false');} await page.emulateMedia({media:'print'});await page.evaluate(()=>dispatchEvent(new Event('beforeprint')));assert.equal(await page.evaluate(()=>getComputedStyle(document.querySelector('.toolbar')).display),'none'); assert.deepEqual(errors,[]);assert.deepEqual(requests,[]);report.runs.push({reducedMotion,slides,testedNodes,errors,networkRequests:requests,clipping:0,keyboard:true,fullscreen:true,overview:true,reload:true,print:true});await context.close(); } fs.writeFileSync(path.join(root,'evidence/test-report.json'),JSON.stringify(report,null,2)+'\n');console.log(JSON.stringify(report,null,2)); } finally {await browser.close();}