* runner.js: shows a 30px fixed-top progress strip during runs (label "test x/total:", current suite/test name with ellipsis on the left, fixed 50%-wide progress fill on the right that turns danger-red on the first failure). The DOM node is created in loader.js so it appears immediately on shortcut press; runner.js only updates it. The fill width is fixed at flex:0 0 50% so it doesn't jiggle as the test name changes length. Suites now live on window._testSuites as a defensive fallback so two runner instances stay in sync. * Cache invalidation: every test file's `from './runner.js'` is now `from './runner.js?v=2'`, and loader.js imports the runner with the same RUNNER_V suffix. Same URL → one module instance → suite registration and runAll see the same array. Bumping RUNNER_V (in loader.js + every test file in lock-step) is the way to force a re-fetch when runner.js changes. * loader.js: ensureProgressBar() draws the strip via setProperty(..., 'important') with z-index 2147483647 attached to documentElement so nothing in user CSS, scanline overlay (z 9999) or modals can occlude it. Auto-run path (?test=1) also pre-renders the strip. chore: bump version to 0.9.1 Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
75 lines
2.6 KiB
JavaScript
75 lines
2.6 KiB
JavaScript
import { describe, it, afterEach, expect, $, click, sleep, closeAll } from './runner.js?v=2';
|
|
import { state } from '../../js/modules/state.js';
|
|
|
|
describe('Toolbar: Filter Toggles', () => {
|
|
afterEach(() => closeAll());
|
|
|
|
it('hide-done toggles state and active class', async () => {
|
|
const before = state.hideDone;
|
|
click('#hide-done');
|
|
await sleep(100);
|
|
expect(state.hideDone).toBe(!before);
|
|
expect($('#hide-done').classList.contains('active')).toBe(!before);
|
|
// Reset
|
|
click('#hide-done');
|
|
await sleep(50);
|
|
});
|
|
|
|
it('hide-termine toggles state and active class', async () => {
|
|
const before = state.hideTermine;
|
|
click('#hide-termine');
|
|
await sleep(100);
|
|
expect(state.hideTermine).toBe(!before);
|
|
expect($('#hide-termine').classList.contains('active')).toBe(!before);
|
|
click('#hide-termine');
|
|
await sleep(50);
|
|
});
|
|
|
|
it('hide-tagged toggles state and active class', async () => {
|
|
const before = state.hideTagged;
|
|
click('#hide-tagged');
|
|
await sleep(100);
|
|
expect(state.hideTagged).toBe(!before);
|
|
expect($('#hide-tagged').classList.contains('active')).toBe(!before);
|
|
click('#hide-tagged');
|
|
await sleep(50);
|
|
});
|
|
|
|
it('superview toggles state and active class', async () => {
|
|
const before = state.superView;
|
|
click('#superview-toggle');
|
|
await sleep(100);
|
|
expect(state.superView).toBe(!before);
|
|
expect($('#superview-toggle').classList.contains('active')).toBe(!before);
|
|
click('#superview-toggle');
|
|
await sleep(50);
|
|
});
|
|
|
|
it('sort cycles through modes', async () => {
|
|
const modes = ['manual', 'newest', 'oldest', 'alpha', 'tag'];
|
|
const before = state.sortMode;
|
|
click('#sort-toggle');
|
|
await sleep(100);
|
|
const after = state.sortMode;
|
|
const idx = modes.indexOf(before);
|
|
expect(after).toBe(modes[(idx + 1) % modes.length]);
|
|
// Reset back
|
|
while (state.sortMode !== before) { click('#sort-toggle'); await sleep(50); }
|
|
});
|
|
});
|
|
|
|
describe('Toolbar: Superview Rendering', () => {
|
|
afterEach(async () => {
|
|
if (state.superView) { click('#superview-toggle'); await sleep(100); }
|
|
await closeAll();
|
|
});
|
|
|
|
it('superview renders list items', async () => {
|
|
if (state.superView) { click('#superview-toggle'); await sleep(100); }
|
|
click('#superview-toggle');
|
|
await sleep(200);
|
|
const items = document.querySelectorAll('.superview-item');
|
|
expect(items.length).toBeGreaterThan(-1);
|
|
});
|
|
});
|