'use strict'; const assert = require('node:assert/strict'); const fs = require('node:fs'); const path = require('node:path'); const root = path.resolve(__dirname, '../..'); const read = (file) => fs.readFileSync(path.join(root, file), 'utf8'); const js = read('assets/widgets/frontend.js'); const css = read('assets/widgets/frontend.css'); const content = read('src/WidgetSystem/Renderers/ContentRenderer.php'); const knowledge = read('src/WidgetSystem/Renderers/KnowledgeProductRenderer.php'); const general = read('src/WidgetSystem/Renderers/GeneralRenderer.php'); for (const key of ['ArrowRight', 'ArrowLeft', 'Home', 'End']) assert.match(js, new RegExp(key)); assert.match(js, /setAttribute\('tabindex', tab === button \? '0' : '-1'\)/); assert.match(js, /setAttribute\('aria-labelledby', button\.id\)/); assert.match(content, /role="tab"[^;]+aria-controls=/); assert.match(content, /role="tabpanel"[^;]+aria-labelledby=/); assert.match(knowledge, /role="tab"[^;]+aria-controls=/); assert.match(knowledge, /role="tabpanel"[^;]+aria-labelledby=/); assert.match(css, /:focus-visible/); assert.match(css, /forced-colors: active/); assert.match(content, /aria-live="polite" aria-busy="true"/); assert.match(content, /role="status"/); assert.match(js, /setAttribute\('aria-busy', 'true'\)/); assert.match(js, /setAttribute\('aria-busy', 'false'\)/); assert.match(general, /role="alert" aria-live="assertive"/); assert.match(css, /prefers-reduced-motion: reduce/); assert.match(js, /prefers-reduced-motion: reduce/); console.log('Widget accessibility contract tests passed: keyboard tabs, focus, live states and reduced motion.');