Files
DemonGatanjieu-Anomalous_Mo…/tests/ai_drafts.html
T

47 lines
2.7 KiB
HTML

<!doctype html>
<meta charset="utf-8">
<title>AI answer draft regression</title>
<script type="importmap">{"imports":{"/scripts/app.js":"data:text/javascript,export const app = {};","/scripts/api.js":"data:text/javascript,export const api = new EventTarget();"}}</script>
<pre id="results">Running…</pre>
<div id="stage"></div><div id="now"></div>
<script type="module">
import { renderPanel } from '../web/modules/ui_ai_panel.js';
import { nowStrip } from '../web/modules/ui_ai_now.js';
// No real task writes: only this fixture's fake typing/answer boundary is replaced.
window.fetch = async () => ({ ok: true, json: async () => ({}) });
const results = document.querySelector('#results');
const stage = document.querySelector('#stage');
const strip = nowStrip();
document.querySelector('#now').append(strip);
const task = { id: 'draft-test', steps: [{ id: 'q1', kind: 'panel', panel: {
id: 'panel1', title: 'Question', blocks: [{ type: 'input', id: 'answer', question: 'Your answer?' }]
}, answers: {} }] };
const ctx = { taskId: task.id, changed() {}, refresh() {}, openStage() {}, showStep() {} };
const redraw = () => stage.replaceChildren(renderPanel(task.steps[0], ctx));
const settle = () => new Promise(resolve => requestAnimationFrame(() => requestAnimationFrame(resolve)));
let failures = 0;
const check = (condition, text) => { results.textContent += `${condition ? 'PASS' : 'FAIL'} ${text}\n`; if (!condition) failures++; };
try {
results.textContent = '';
redraw(); strip.update(task, ctx);
let field = stage.querySelector('input');
field.value = 'abcdef';
field.dispatchEvent(new Event('input'));
check(strip.querySelector('input').value === 'abcdef', 'same question shares its draft between stage and bottom strip');
field.focus(); field.setSelectionRange(1, 4, 'backward');
redraw(); await settle();
field = stage.querySelector('input');
check(field.value === 'abcdef', 'redraw preserves answer text');
check(document.activeElement === field, 'redraw restores focus');
check(field.selectionStart === 1 && field.selectionEnd === 4 && field.selectionDirection === 'backward', 'redraw preserves selection instead of jumping to the end');
const bottom = strip.querySelector('input');
bottom.focus();
redraw();
task.steps.push({ id: 'q2', kind: 'panel', panel: { id: 'panel2', blocks: [{type: 'input', id: 'answer'}] }, answers: {} });
strip.update(task, ctx);
await settle();
check(document.activeElement === strip.querySelector('input'), 'simultaneous refresh keeps focus on the surface the user was editing');
results.textContent += failures ? `${failures} FAILED` : 'ALL PASSED';
} catch (error) { results.textContent += `FAIL ${error.stack}`; }
</script>