Files
DemonGatanjieu-Anomalous_Mo…/tests/update_guide.mjs
T

93 lines
5.2 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import assert from 'node:assert/strict';
import { fixture, Element } from './ui_fixture.mjs';
const storage = new Map();
const f = fixture({ storage });
const data = await f.module('update_guide_data.js');
const { i18n } = await f.module('locales.js');
assert.equal(data.validateUpdateGuide(data.CURRENT_UPDATE_GUIDE, i18n), true);
assert.equal(data.validateUpdateGuide({ ...data.CURRENT_UPDATE_GUIDE, steps: [] }, i18n), false);
assert.equal(data.validateUpdateGuide({ ...data.CURRENT_UPDATE_GUIDE, steps: [data.CURRENT_UPDATE_GUIDE.steps[0], data.CURRENT_UPDATE_GUIDE.steps[0]] }, i18n), false);
assert.equal(data.validateUpdateGuide(data.CURRENT_UPDATE_GUIDE, { zh: i18n.zh, en: {} }), false);
const guide = await f.module('ui_update_guide.js');
const owner = { modal: new Element('div') };
assert.equal(guide.showUpdateGuide(owner), false, 'never show over a closed browser');
owner.modal.classList.add('visible');
assert.equal(guide.showUpdateGuide(owner), true);
assert.equal(guide.showUpdateGuide(owner), false, 'no duplicate dialog');
let dialog = f.document.querySelector('dialog');
assert.equal(f.button(dialog, 'Back').disabled, true);
await f.button(dialog, 'Next').click();
assert.match(dialog.textContent, /Material Library/);
await f.button(dialog, 'Back').click();
assert.match(dialog.textContent, /Workflow Recipe Studio/);
await f.button(dialog, 'Next').click();
await f.button(dialog, 'Next').click();
await f.button(dialog, 'Next').click();
await f.button(dialog, 'Got it').click();
assert.equal(dialog.isConnected, false);
assert.equal(dialog.listenerCount(), 0);
assert.equal(guide.showUpdateGuide(owner), false);
assert.equal(guide.hasAcknowledged(data.CURRENT_UPDATE_GUIDE.id), true);
const fresh = fixture({ storage });
assert.equal((await fresh.module('ui_update_guide.js')).showUpdateGuide(owner), false, 'dismissal persists across page sessions');
assert.equal(guide.showUpdateGuide(owner, { force: true }), true);
dialog = f.document.querySelector('dialog');
let stopped = false, prevented = false;
dialog.dispatch('keydown', { key: 'Escape', stopPropagation() { stopped = true; }, preventDefault() { prevented = true; } });
assert.ok(stopped && prevented);
assert.equal(dialog.listenerCount(), 0);
assert.ok(owner.modal.classList.contains('visible'), 'Escape belongs only to the guide');
const nextGuide = { ...data.CURRENT_UPDATE_GUIDE, id: 'next-release' };
assert.equal(guide.showUpdateGuide(owner, { guide: nextGuide }), true);
guide.closeUpdateGuide(owner);
guide.closeUpdateGuide(owner);
assert.equal(guide.showUpdateGuide(owner, { guide: nextGuide }), true, 'parent close must not acknowledge unread content');
await f.button(f.document.querySelector('dialog'), 'Skip').click();
assert.equal(guide.showUpdateGuide(owner, { guide: nextGuide }), false);
assert.equal(guide.showUpdateGuide(owner, { guide: { ...nextGuide, steps: [] } }), false);
const unavailable = fixture({ storageOverride: { getItem() { throw new Error('Storage blocked'); }, setItem() { throw new Error('Storage blocked'); } } });
const unavailableGuide = await unavailable.module('ui_update_guide.js');
assert.equal(unavailableGuide.showUpdateGuide(owner), true);
unavailable.document.querySelector('dialog').dispatch('cancel', { preventDefault() {} });
assert.equal(unavailableGuide.showUpdateGuide(owner), false, 'blocked storage still prevents repeated prompts in this session');
console.log('Update guide: configuration, steps, persistence, replay, Escape, parent close and blocked storage passed.');
const actions = await f.module('sidebar_actions.js');
const root = new Element('div');
const scan = new Element('button'); scan.id = 'anomalous-scan-btn';
let clicks = 0; scan.onclick = () => clicks++;
root.append(scan);
actions.configureSidebarActions(root);
actions.configureSidebarActions(root);
assert.equal(scan.querySelectorAll('.anomalous-action-label').length, 1);
assert.equal(scan.querySelector('.anomalous-action-label').textContent, 'Scan');
await scan.click(); assert.equal(clicks, 1);
scan.innerHTML = '<svg></svg>'; // Scanner status refresh replaces its icon.
scan.classList.add('anomalous-radar-spinning');
actions.configureSidebarAction(scan);
assert.ok(scan.querySelector('.anomalous-action-label'));
assert.ok(scan.classList.contains('anomalous-radar-spinning'));
assert.match(scan.getAttribute('data-tooltip'), /metadata and previews/);
console.log('Sidebar labels: repeated setup, scanner icon replacement and click behavior passed.');
const tour = await f.module('ui_spotlight_tour.js');
const modelsBtn = new Element('button'); modelsBtn.id = 'anomalous-models-btn';
const scanBtn = new Element('button'); scanBtn.id = 'anomalous-scan-btn';
f.document.body.append(modelsBtn, scanBtn);
assert.equal(tour.isSpotlightTourActive(), false);
assert.equal(tour.startSpotlightTour(owner), true);
assert.equal(tour.isSpotlightTourActive(), true);
const overlay = f.document.querySelector('.anomalous-spotlight-overlay');
assert.ok(overlay);
assert.match(overlay.textContent, /Workspace Navigation/);
await f.button(overlay, 'Next ›').click();
assert.match(overlay.textContent, /Model Scanning/);
tour.closeSpotlightTour();
assert.equal(tour.isSpotlightTourActive(), false);
console.log('Spotlight tour: lifecycle, step advancement, and clean exit passed.');