// @vitest-environment jsdom import { describe, it, expect, beforeAll, afterAll } from 'vitest'; import { SNAPSHOT_SCRIPT } from './browser.js'; /** * SNAPSHOT_SCRIPT はページ内で eval される文字列。jsdom の上で実際に * 走らせて、書き出しにパスワードが載らないことを見る(issue #1236)。 * * jsdom の getBoundingClientRect は常に 0×0 を返すので、そのままだと * isVisible() が全要素を落として何も走査されない。差し替えておく。 */ let originalRect: () => DOMRect; beforeAll(() => { originalRect = Element.prototype.getBoundingClientRect; Element.prototype.getBoundingClientRect = function (): DOMRect { return { width: 100, height: 20, top: 0, left: 0, right: 100, bottom: 20, x: 0, y: 0, toJSON() {} } as DOMRect; }; }); afterAll(() => { Element.prototype.getBoundingClientRect = originalRect; }); /** html を置いてから values を実際の .value に流し込み、書き出しを取る。 */ function snapshot(html: string, values: Record = {}): string { document.body.innerHTML = html; for (const [id, v] of Object.entries(values)) { (document.getElementById(id) as HTMLInputElement | HTMLTextAreaElement).value = v; } const result = (0, eval)(SNAPSHOT_SCRIPT) as { text: string }; return result.text; } describe('SNAPSHOT_SCRIPT — 入力欄の中身', () => { it('type=password の欄は中身を書き出さず、値があることだけ残す', () => { const text = snapshot('', { pw: 'hunter2-topsecret' }); expect(text).not.toContain('hunter2-topsecret'); expect(text).toContain('value=[masked]'); }); it('name からパスワードと分かる欄も伏せる(type=text でも)', () => { const text = snapshot('', { p: 'correct-horse-battery' }); expect(text).not.toContain('correct-horse-battery'); expect(text).toContain('value=[masked]'); }); it('autocomplete=one-time-code の欄も伏せる', () => { const text = snapshot('', { c: '482913' }); expect(text).not.toContain('482913'); expect(text).toContain('value=[masked]'); }); it('空のパスワード欄には印を出さない(値の有無だけが残る)', () => { const text = snapshot(''); expect(text).not.toContain('[masked]'); }); it('名札だけが手掛かりの欄も伏せる(「表示」で伏せ字を解いた欄)', () => { // type は text に変わり、id は枠組みの機械生成。残る手掛かりは名札だけ。 const text = snapshot('', { ':r3:': 'correct-horse-battery', }); expect(text).not.toContain('correct-horse-battery'); expect(text).toContain('value=[masked]'); }); it('`