// Generated, do not edit. sha256:0196b96345c180a741780bad0241a094640e956c6972ad08f5b4f400181c36c5 import { describe, it, beforeEach } from 'node:test'; import assert from 'node:assert/strict'; import { installDom } from '../helpers/mini-dom.mjs'; const dom = installDom(); const { setPageHint, clearPageHint, configureHint, SAMPLES } = await import('../../client/ui/hint.js'); const mount = dom.document.createElement('div'); mount.id = 'page-hint'; dom.document.body.appendChild(mount); const page = dom.host(); const gone = dom.document.createElement('div'); describe('setPageHint', () => { beforeEach(() => { configureHint(); mount.innerHTML = ''; }); it('puts down one icon with its panel', () => { setPageHint(page, { title: 'What you see', rows: ['A row.'] }); assert.equal(mount.querySelectorAll('.hint-btn').length, 1); assert.equal(mount.querySelector('.hint-panel .hint-row').textContent, 'A row.'); }); it('ignores a page that is no longer on screen, and a call without a host', () => { setPageHint(gone, { title: 'Of the previous page', rows: ['Does not belong here.'] }); setPageHint(undefined, { title: 'No host', rows: [] }); assert.equal(mount.innerHTML, ''); }); it('escapes the title, in the attribute and in the heading', () => { setPageHint(page, { title: 'A "title" & ', rows: [] }); assert.equal(mount.querySelector('.hint-btn').getAttribute('aria-label'), 'A "title" & '); assert.equal(mount.querySelector('.hint-panel > .t-label').textContent, 'A "title" & '); assert.equal(mount.querySelector('more'), null); }); it('a row without a sample keeps the indent of a row with one', () => { setPageHint(page, { title: 'x', rows: ['Bare.', { sample: SAMPLES.dot, text: 'With a dot.' }] }); assert.equal(mount.querySelectorAll('.hint-row .hint-sample').length, 2); assert.ok(mount.querySelectorAll('.hint-row')[1].querySelector('.hint-dot')); }); it('a heading is a heading and not a row', () => { setPageHint(page, { title: 'x', rows: [{ heading: 'Box 3' }, 'A row.'] }); assert.equal(mount.querySelector('.hint-heading').textContent, 'Box 3'); assert.equal(mount.querySelectorAll('.hint-row').length, 1); }); it('without rows there is still a panel', () => { setPageHint(page, { title: 'x' }); assert.ok(mount.querySelector('.hint-panel')); }); }); describe('clearPageHint', () => { it('without configuration: empty', () => { configureHint(); setPageHint(page, { title: 'x', rows: ['A row.'] }); clearPageHint(); assert.equal(mount.innerHTML, ''); }); }); describe('configureHint', () => { beforeEach(() => { mount.innerHTML = ''; }); it('puts the lead on every legend, right under the title and before the rows', () => { configureHint({ lead: '
Lead
' }); setPageHint(page, { title: 'x', rows: ['A row.'] }); const panel = mount.querySelector('.hint-panel'); assert.deepEqual(panel.children.map(c => c.className), ['t-label', 'hint-row hint-warn', 'hint-row']); configureHint(); }); it('with an empty legend configured, clearing leaves that legend with only the lead', () => { configureHint({ lead: '
Lead
', empty: { title: 'Missing', className: 'is-fallback' } }); setPageHint(page, { title: 'x', rows: ['A row.'] }); clearPageHint(); assert.ok(mount.querySelector('.hint.is-fallback')); assert.equal(mount.querySelector('.hint-btn').getAttribute('aria-label'), 'Missing'); assert.ok(mount.querySelector('.hint-warn')); assert.equal(mount.querySelectorAll('.hint-row').length, 0); configureHint(); }); }); describe('a panel that would scroll gets wider on opening', () => { it('is-wide on opening when the content is taller than the panel, and off again when it fits', () => { configureHint(); setPageHint(page, { title: 'x', rows: ['A row.'] }); const panel = mount.querySelector('.hint-panel'); Object.defineProperty(panel, 'scrollHeight', { value: 500, configurable: true }); Object.defineProperty(panel, 'clientHeight', { value: 300, configurable: true }); dom.fire(mount, 'pointerenter'); assert.ok(panel.classList.contains('is-wide')); Object.defineProperty(panel, 'scrollHeight', { value: 300, configurable: true }); dom.fire(mount, 'focusin'); assert.equal(panel.classList.contains('is-wide'), false); }); it('a click on the icon pins the panel, and a click outside, Escape or the icon again closes it', () => { configureHint(); setPageHint(page, { title: 'x', rows: ['link'] }); const hint = () => mount.querySelector('.hint'); const btn = () => mount.querySelector('.hint-btn'); dom.click(btn()); assert.ok(hint().classList.contains('is-open')); assert.equal(btn().getAttribute('aria-expanded'), 'true'); dom.click(mount.querySelector('.hint-panel a')); assert.ok(hint().classList.contains('is-open'), 'a click inside the panel keeps it open'); dom.click(page); assert.equal(hint().classList.contains('is-open'), false); dom.click(btn()); dom.key(dom.document.body, 'Escape'); assert.equal(hint().classList.contains('is-open'), false); dom.click(btn()); dom.click(btn()); assert.equal(hint().classList.contains('is-open'), false); }); it('binds its listeners once per mount, however often a page announces', () => { const before = mount.listeners.length; setPageHint(page, { title: 'a', rows: [] }); setPageHint(page, { title: 'b', rows: [] }); assert.equal(mount.listeners.length, before); }); });