import { describe, it } from './runner.mjs'; import { JSDOM } from 'jsdom'; const POPUP_HTML = ` VidPlex

VidPlex

Quick start

How to use VidPlex

  1. Scan videos Click Find Videos to search the current browser window for videos.
  2. Review the list Check the popup list; each found video URL is clickable.
  3. Open the viewer Click Open Viewer to open the 2x2 grid player in a new window.
  4. Reset and rescan Click Clear to erase results and scan again.

Warning: Browser pages, extension pages, and restricted frames can hide videos, so results may be incomplete.

Learn more tooltip: Read the VidPlex README and audit notes.

`; function installPopupDom() { const dom = new JSDOM(POPUP_HTML, { url: 'chrome-extension://test/src/viewer/index.html' }); const previous = { window: globalThis.window, document: globalThis.document, navigator: globalThis.navigator, chrome: globalThis.chrome, HTMLElement: globalThis.HTMLElement, Node: globalThis.Node, }; globalThis.window = dom.window; globalThis.document = dom.window.document; Object.defineProperty(globalThis, 'navigator', { value: dom.window.navigator, configurable: true, writable: true, }); Object.defineProperty(globalThis, 'HTMLElement', { value: dom.window.HTMLElement, configurable: true, writable: true, }); Object.defineProperty(globalThis, 'Node', { value: dom.window.Node, configurable: true, writable: true, }); globalThis.chrome = { storage: { local: { get: async () => ({}), set: async () => undefined, remove: async () => undefined, }, }, tabs: { query: async () => [] }, scripting: { executeScript: async () => [] }, runtime: { getURL: (path) => `chrome-extension://test/${path}` }, windows: { create: async () => ({ id: 1 }) }, }; return { dom, cleanup() { dom.window.close(); globalThis.window = previous.window; globalThis.document = previous.document; Object.defineProperty(globalThis, 'navigator', { value: previous.navigator, configurable: true, writable: true, }); globalThis.chrome = previous.chrome; Object.defineProperty(globalThis, 'HTMLElement', { value: previous.HTMLElement, configurable: true, writable: true, }); Object.defineProperty(globalThis, 'Node', { value: previous.Node, configurable: true, writable: true, }); }, }; } async function mountPopup() { const { dom, cleanup } = installPopupDom(); const moduleUrl = new URL('../src/viewer/index.js?test=' + Date.now(), import.meta.url); await import(moduleUrl.href); return { dom, cleanup }; } describe('Viewer popup instructions', () => { it('renders the drafted instructions copy on mount with accessible labeling', async () => { const { dom, cleanup } = await mountPopup(); try { const doc = dom.window.document; const region = doc.querySelector('.instructions-panel'); const title = doc.getElementById('instructions-title'); const toggle = doc.getElementById('instructions-toggle'); const body = doc.getElementById('instructions-body'); if (!region) throw new Error('Instructions region missing'); if (region.getAttribute('role') !== 'region') throw new Error('Instructions region missing role="region"'); if (region.getAttribute('aria-labelledby') !== 'instructions-title') throw new Error('Instructions region missing aria-labelledby'); if (!title || title.textContent !== 'How to use VidPlex') throw new Error('Instructions title not rendered'); if (!toggle) throw new Error('Instructions toggle missing'); if (toggle.getAttribute('aria-controls') !== 'instructions-body') throw new Error('Toggle missing aria-controls'); if (toggle.getAttribute('aria-expanded') !== 'true') throw new Error('Toggle should start expanded'); if (!body || body.hidden) throw new Error('Instructions body should be visible on mount'); const expectedTexts = [ 'Scan videos', 'Click Find Videos to search the current browser window for videos.', 'Review the list', 'Check the popup list; each found video URL is clickable.', 'Open the viewer', 'Click Open Viewer to open the 2x2 grid player in a new window.', 'Reset and rescan', 'Click Clear to erase results and scan again.', 'Warning: Browser pages, extension pages, and restricted frames can hide videos, so results may be incomplete.', 'Learn more tooltip: Read the VidPlex README and audit notes.', ]; for (const text of expectedTexts) { if (!doc.body.textContent.includes(text)) { throw new Error(`Missing instructions copy: ${text}`); } } } finally { cleanup(); } }); it('toggles the instructions panel open and closed', async () => { const { dom, cleanup } = await mountPopup(); try { const doc = dom.window.document; const toggle = doc.getElementById('instructions-toggle'); const body = doc.getElementById('instructions-body'); if (!toggle || !body) throw new Error('Instructions controls missing'); toggle.click(); if (toggle.getAttribute('aria-expanded') !== 'false') throw new Error('Toggle should collapse the instructions'); if (!body.hidden) throw new Error('Instructions body should be hidden after collapse'); if (toggle.textContent !== 'Show instructions') throw new Error('Collapsed label should switch to Show instructions'); toggle.click(); if (toggle.getAttribute('aria-expanded') !== 'true') throw new Error('Toggle should expand the instructions'); if (body.hidden) throw new Error('Instructions body should be visible after expanding'); if (toggle.textContent !== 'Hide instructions') throw new Error('Expanded label should switch back to Hide instructions'); } finally { cleanup(); } }); });