Files
presentation-html/scripts/test.mjs
T

38 lines
4.7 KiB
JavaScript

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;i<slides;i++){
await page.evaluate(i=>Reveal.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.left<r.left-2||b.right>r.right+2||b.top<r.top-2||b.bottom>r.bottom+2;}).map(e=>e.textContent);});assert.deepEqual(clipped,[],'Clipping slide '+i);
const nodes=page.locator('.present [data-node]');
for(let j=0;j<await nodes.count();j++){
const n=nodes.nth(j);await n.focus();await page.keyboard.press('Enter');assert.equal(await n.getAttribute('aria-pressed'),'true');assert.equal(await page.locator('#detail').textContent(),await n.getAttribute('data-detail'));await page.keyboard.press('Space');assert.equal(await n.getAttribute('aria-pressed'),'false');await n.click();assert.equal(await n.getAttribute('aria-pressed'),'true');await n.click();testedNodes++;
}
if(reducedMotion==='no-preference')await page.screenshot({path:path.join(root,`evidence/slide-${String(i+1).padStart(2,'0')}.png`)});
}
assert.equal(testedNodes,6);await page.evaluate(()=>Reveal.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 && document.querySelector('#fullscreen').getAttribute('aria-pressed')==='true');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();}