feat: add manual confirmation toggle for incomplete exams
This commit is contained in:
+35
-1
@@ -58,7 +58,7 @@ async function main() {
|
||||
const host = page.locator('#yian-question-assistant');
|
||||
const tab = id => host.getByTestId('tab-' + id);
|
||||
const pane = id => host.getByTestId('pane-' + id);
|
||||
async function screenshot(name) { await page.screenshot({ path: path.join(qaDir, name), fullPage: false }); }
|
||||
async function screenshot(name) { await page.screenshot({ path: path.join(qaDir, name), fullPage: false, animations: 'disabled' }); }
|
||||
async function visible() {
|
||||
await page.waitForFunction(() => {
|
||||
const box = qaPanel.host.getBoundingClientRect();
|
||||
@@ -118,6 +118,26 @@ async function main() {
|
||||
assert.equal(await host.getByTestId('setting-answerInterval').inputValue(), '4');
|
||||
assert.equal(await host.getByTestId('setting-minSubmitMinutes').inputValue(), '6');
|
||||
assert(await pane('exam').textContent().then(text => text.includes('80 分(题库估计)')));
|
||||
const incompleteSwitch = host.getByTestId('setting-manualConfirmIncomplete');
|
||||
assert.equal(await incompleteSwitch.getAttribute('role'), 'switch');
|
||||
assert.equal(await incompleteSwitch.getAttribute('aria-label'), '题目不全时手动确认');
|
||||
assert(await incompleteSwitch.isChecked(), '缺题手动确认默认开启');
|
||||
assert(await host.getByTestId('exam-threshold').textContent().then(text => text.includes('题目不全时由用户在原网页手动确认')));
|
||||
assert(await host.getByTestId('incomplete-confirmation-hint').textContent().then(text => text.includes('试卷未完整加载均禁止自动交卷')));
|
||||
await incompleteSwitch.uncheck();
|
||||
assert.deepEqual(await page.evaluate(() => qaCalls.settings.at(-1)), ['manualConfirmIncomplete', false]);
|
||||
assert(await host.getByTestId('exam-threshold').textContent().then(text => text.includes('允许题库部分缺题时自动交卷') && text.includes('严格大于 80 分') && text.includes('所有可匹配题均已核验')));
|
||||
await screenshot('02a-desktop-incomplete-switch-off.png');
|
||||
const callsAfterIncompleteOff = await page.evaluate(() => JSON.stringify(qaCalls));
|
||||
await tab('overview').click(); await page.evaluate(() => qaPanel.setState({ learning: { etaSeconds: 360 } })); await tab('exam').click();
|
||||
assert(!await incompleteSwitch.isChecked(), '切栏及部分状态更新保留关闭状态');
|
||||
assert.equal(await page.evaluate(() => JSON.stringify(qaCalls)), callsAfterIncompleteOff, '切栏不能修改缺题开关、自动答题或交卷');
|
||||
await incompleteSwitch.check();
|
||||
assert.deepEqual(await page.evaluate(() => qaCalls.settings.at(-1)), ['manualConfirmIncomplete', true]);
|
||||
assert.deepEqual(await page.evaluate(() => qaCalls.settings.filter(([key]) => key === 'manualConfirmIncomplete')), [['manualConfirmIncomplete', false], ['manualConfirmIncomplete', true]]);
|
||||
assert.deepEqual(await page.evaluate(() => qaCalls.auto), [], '缺题开关与自动选择答案独立');
|
||||
assert.deepEqual(await page.evaluate(() => qaCalls.actions), [], '缺题开关不启动或提交考试');
|
||||
console.log('PASS incomplete-question switch defaults on, boolean setting callbacks, persistent tab state and independent answer controls');
|
||||
await host.getByTestId('setting-answerInterval').fill('5'); await host.getByTestId('setting-answerInterval').press('Tab');
|
||||
assert.deepEqual(await page.evaluate(() => qaCalls.settings.at(-1)), ['answerInterval', 5]);
|
||||
await host.getByRole('switch', { name: '自动选择答案', exact: true }).check();
|
||||
@@ -130,6 +150,17 @@ async function main() {
|
||||
assert.equal(await host.getByTestId('setting-answerInterval').inputValue(), '5');
|
||||
await host.getByTestId('task-examResume').click();
|
||||
assert.equal(await page.evaluate(() => qaCalls.actions.at(-1)), 'examResume');
|
||||
await page.evaluate(() => qaPanel.setState({ learning: { exam: { title: '安全考试', status: 'waiting', total: 25,
|
||||
verifiedCount: 21, unverifiedCount: 4, predictedScore: 84, requiresManualSubmission: true,
|
||||
elapsedSeconds: 360, remainingSeconds: 1000, message: '题目未全部核验,请在网页手动确认交卷' } } }));
|
||||
assert(await pane('exam').textContent().then(text => text.includes('84 分(题库估计)') && text.includes('21 / 25 题') && text.includes('原网页手动确认')));
|
||||
await page.evaluate(() => qaPanel.setState({ learning: { manualConfirmIncomplete: false } }));
|
||||
assert(!await incompleteSwitch.isChecked());
|
||||
assert(await pane('exam').textContent().then(text => text.includes('题目未全部核验或网站提示未答完,请在原网页手动确认')), '控制器要求人工时优先显示其提示');
|
||||
await page.evaluate(() => qaPanel.setState({ learning: { manualConfirmIncomplete: true } }));
|
||||
assert(await incompleteSwitch.isChecked(), '面板反映外部恢复的开关配置');
|
||||
assert.equal(await pane('exam').getByRole('button', { name: '确认交卷', exact: true }).count(), 0, '面板不能提供跳过缺题的交卷确认入口');
|
||||
await host.locator('.panes').evaluate(node => { node.scrollTop = 0; });
|
||||
await screenshot('02-desktop-exam.png');
|
||||
console.log('PASS exam defaults/score/full answer evidence, partial learning updates and persistent switch/details state');
|
||||
|
||||
@@ -182,6 +213,9 @@ async function main() {
|
||||
const moved = await host.boundingBox(); assert(Math.abs(moved.x - box.x - 35) <= 2);
|
||||
await page.setViewportSize({ width: 390, height: 844 }); await visible();
|
||||
assert.equal(await host.locator('.navigation').evaluate(element => getComputedStyle(element).flexDirection), 'row');
|
||||
await tab('exam').click(); await incompleteSwitch.scrollIntoViewIfNeeded();
|
||||
assert(await incompleteSwitch.isVisible()); assert(await incompleteSwitch.isChecked());
|
||||
await screenshot('03a-mobile-incomplete-switch-on.png');
|
||||
await tab('bank').click(); await screenshot('03-mobile-bank.png');
|
||||
await page.setViewportSize({ width: 320, height: 480 }); await visible();
|
||||
await tab('overview').click(); await screenshot('04-small-overview.png');
|
||||
|
||||
Reference in New Issue
Block a user