fix: reduce userscript page blocking and stale option clicks

This commit is contained in:
suanyuit-cyber
2026-10-30 01:47:03 +08:00
parent 26e0a920b6
commit 4bf2de1bad
12 changed files with 1128 additions and 170 deletions
+49
View File
@@ -256,3 +256,52 @@ test('a question changing during the first click stops the rest of a multiple se
assert.equal(page.inputs[1].checked, false);
engine.destroy();
});
test('reusing the same input nodes with different option values stops the remaining clicks', async () => {
let page;
page = checkboxPage({ duringClick: index => {
if (index === 0) [page.inputs[1].value, page.inputs[2].value] = [page.inputs[2].value, page.inputs[1].value];
} });
const engine = create({ window: page.win, document: page.doc, core, getRecords: () => [page.record] });
await engine.answerCurrent();
assert.deepEqual(page.clicks, [0], 'an old positional plan must not click a reused node now carrying another option ID');
engine.destroy();
});
test('a nested framework microtask that changes the question is observed before another click', async () => {
let page;
page = checkboxPage({ duringClick: index => {
if (index === 0) queueMicrotask(() => queueMicrotask(() => { page.title.textContent = '框架异步渲染的新题目。'; }));
} });
const engine = create({ window: page.win, document: page.doc, core, getRecords: () => [page.record] });
await engine.answerCurrent();
assert.deepEqual(page.clicks, [0], 'a single awaited Promise is too early to safely click the next option');
engine.destroy();
});
test('an 1884-record bank only normalizes exact-stem candidates, not every unrelated question per poll', () => {
const records = Array.from({ length: 1884 }, (_, index) => single({ questionId: `question-${index}`, stem: `无关的题库练习 ${index}。` }));
records[1000] = single();
let normalizedCount = 0;
const observed = { ...core, normalizeRecord(value) { normalizedCount++; return core.normalizeRecord(value); } };
assert.equal(planAnswer(records, current(), observed).status, 'ready');
const initial = normalizedCount;
for (let attempt = 0; attempt < 20; attempt++) assert.equal(planAnswer(records, current(), observed).status, 'ready');
assert.ok(initial <= 3, `first lookup should not normalize all 1884 records (observed ${initial})`);
assert.ok(normalizedCount - initial <= 20, 'repeat lookups only need to validate the current question again');
});
test('the answer index detects in-place option/answer mutations and changed raw records', () => {
const records = [single()];
assert.equal(planAnswer(records, current(), core).status, 'ready');
records[0].correctOptionIds = ['a']; records[0].answerTexts = ['降低温度'];
assert.deepEqual(planAnswer(records, current(), core).labels, ['B']);
records[0].answerStatus = 'conflict';
assert.equal(planAnswer(records, current(), core).status, 'ambiguous');
records[0] = single();
assert.deepEqual(planAnswer(records, current(), core).labels, ['C']);
records.push(single({ questionId: 'changed-stem', stem: '此前与目标无关。', correctOptionIds: ['a'], answerTexts: ['降低温度'] }));
assert.equal(planAnswer(records, current(), core).status, 'ready');
records[1].stem = single().stem;
assert.equal(planAnswer(records, current(), core).status, 'ambiguous', 'a record changing into an exact match must invalidate the question index');
});