mirror of
https://github.com/willmiao/ComfyUI-Lora-Manager.git
synced 2026-03-21 21:22:11 -03:00
feat(tests): add frontend automated testing setup with Vitest and jsdom
This commit is contained in:
2
.gitignore
vendored
2
.gitignore
vendored
@@ -6,3 +6,5 @@ py/run_test.py
|
||||
.vscode/
|
||||
cache/
|
||||
civitai/
|
||||
node_modules/
|
||||
coverage/
|
||||
|
||||
23
docs/frontend-testing-roadmap.md
Normal file
23
docs/frontend-testing-roadmap.md
Normal file
@@ -0,0 +1,23 @@
|
||||
# Frontend Automation Testing Roadmap
|
||||
|
||||
This roadmap tracks the planned rollout of automated testing for the ComfyUI LoRA Manager frontend. Each phase builds on the infrastructure introduced in this change set and records progress so future contributors can quickly identify the next tasks.
|
||||
|
||||
## Phase Overview
|
||||
|
||||
| Phase | Goal | Primary Focus | Status | Notes |
|
||||
| --- | --- | --- | --- | --- |
|
||||
| Phase 0 | Establish baseline tooling | Add Node test runner, jsdom environment, and seed smoke tests | ✅ Complete | Vitest + jsdom configured, example state tests committed |
|
||||
| Phase 1 | Cover state management logic | Unit test selectors, derived data helpers, and storage utilities under `static/js/state` and `static/js/utils` | 🟡 In Progress | Prioritize deterministic scenarios for `storageHelpers`, `AppState` derivatives, and regression cases for migrations |
|
||||
| Phase 2 | Test AppCore orchestration | Simulate page bootstrapping, infinite scroll hooks, and manager registration using JSDOM DOM fixtures | ⚪ Not Started | Requires DOM fixtures from `templates/*.html` and stubbing of manager modules |
|
||||
| Phase 3 | Validate page-specific managers | Add focused suites for `loras`, `checkpoints`, `embeddings`, and `recipes` managers covering filtering, sorting, and bulk actions | ⚪ Not Started | Consider shared helpers for mocking API modules and storage |
|
||||
| Phase 4 | Interaction-level regression tests | Exercise template fragments, modals, and menus to ensure UI wiring remains intact | ⚪ Not Started | Evaluate Playwright component testing or happy-path DOM snapshots |
|
||||
| Phase 5 | Continuous integration & coverage | Integrate frontend tests into CI workflow and track coverage metrics | ⚪ Not Started | Align reporting directories with backend coverage for unified reporting |
|
||||
|
||||
## Next Steps Checklist
|
||||
|
||||
- [ ] Expand unit tests for `storageHelpers` covering migrations and namespace behavior.
|
||||
- [ ] Document DOM fixture strategy for reproducing template structures in tests.
|
||||
- [ ] Prototype AppCore initialization test that verifies manager bootstrapping with stubbed dependencies.
|
||||
- [ ] Evaluate integrating coverage reporting once test surface grows (> 20 specs).
|
||||
|
||||
Maintaining this roadmap alongside code changes will make it easier to append new automated test tasks and update their progress.
|
||||
2572
package-lock.json
generated
Normal file
2572
package-lock.json
generated
Normal file
File diff suppressed because it is too large
Load Diff
14
package.json
Normal file
14
package.json
Normal file
@@ -0,0 +1,14 @@
|
||||
{
|
||||
"name": "comfyui-lora-manager-frontend",
|
||||
"version": "0.1.0",
|
||||
"private": true,
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"test": "vitest run",
|
||||
"test:watch": "vitest"
|
||||
},
|
||||
"devDependencies": {
|
||||
"jsdom": "^24.0.0",
|
||||
"vitest": "^1.6.0"
|
||||
}
|
||||
}
|
||||
53
static/js/state/index.test.js
Normal file
53
static/js/state/index.test.js
Normal file
@@ -0,0 +1,53 @@
|
||||
import { describe, it, expect, beforeEach } from 'vitest';
|
||||
import { createDefaultSettings, getCurrentPageState, initPageState, setCurrentPageType, state } from './index.js';
|
||||
import { MODEL_TYPES } from '../api/apiConfig.js';
|
||||
import { DEFAULT_PATH_TEMPLATES } from '../utils/constants.js';
|
||||
|
||||
describe('state module', () => {
|
||||
beforeEach(() => {
|
||||
// Reset to default page before each assertion
|
||||
state.currentPageType = MODEL_TYPES.LORA;
|
||||
});
|
||||
|
||||
it('creates default settings with immutable template copies', () => {
|
||||
const defaultSettings = createDefaultSettings();
|
||||
|
||||
expect(defaultSettings).toMatchObject({
|
||||
civitai_api_key: '',
|
||||
language: 'en',
|
||||
blur_mature_content: true
|
||||
});
|
||||
|
||||
expect(defaultSettings.download_path_templates).toEqual(DEFAULT_PATH_TEMPLATES);
|
||||
|
||||
// ensure nested objects are new references so tests can safely mutate
|
||||
expect(defaultSettings.download_path_templates).not.toBe(DEFAULT_PATH_TEMPLATES);
|
||||
expect(defaultSettings.base_model_path_mappings).toEqual({});
|
||||
expect(Object.isFrozen(defaultSettings)).toBe(false);
|
||||
});
|
||||
|
||||
it('switches current page type when valid', () => {
|
||||
const didSwitch = setCurrentPageType(MODEL_TYPES.CHECKPOINT);
|
||||
|
||||
expect(didSwitch).toBe(true);
|
||||
expect(state.currentPageType).toBe(MODEL_TYPES.CHECKPOINT);
|
||||
expect(getCurrentPageState()).toBe(state.pages[MODEL_TYPES.CHECKPOINT]);
|
||||
});
|
||||
|
||||
it('rejects switching to an unknown page type', () => {
|
||||
state.currentPageType = MODEL_TYPES.LORA;
|
||||
|
||||
const didSwitch = setCurrentPageType('invalid-page');
|
||||
|
||||
expect(didSwitch).toBe(false);
|
||||
expect(state.currentPageType).toBe(MODEL_TYPES.LORA);
|
||||
});
|
||||
|
||||
it('initializes and returns state for a known page', () => {
|
||||
const pageState = initPageState(MODEL_TYPES.EMBEDDING);
|
||||
|
||||
expect(pageState).toBeDefined();
|
||||
expect(pageState).toBe(state.pages[MODEL_TYPES.EMBEDDING]);
|
||||
expect(state.currentPageType).toBe(MODEL_TYPES.EMBEDDING);
|
||||
});
|
||||
});
|
||||
16
tests/frontend/setup.js
Normal file
16
tests/frontend/setup.js
Normal file
@@ -0,0 +1,16 @@
|
||||
import { afterEach, beforeEach } from 'vitest';
|
||||
|
||||
beforeEach(() => {
|
||||
// Ensure storage is clean before each test to avoid cross-test pollution
|
||||
localStorage.clear();
|
||||
sessionStorage.clear();
|
||||
|
||||
// Reset DOM state for modules that rely on body attributes
|
||||
document.body.innerHTML = '';
|
||||
document.body.dataset.page = '';
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
// Clean any dynamically attached globals by tests
|
||||
delete document.body.dataset.page;
|
||||
});
|
||||
17
vitest.config.js
Normal file
17
vitest.config.js
Normal file
@@ -0,0 +1,17 @@
|
||||
import { defineConfig } from 'vitest/config';
|
||||
|
||||
export default defineConfig({
|
||||
test: {
|
||||
environment: 'jsdom',
|
||||
globals: true,
|
||||
setupFiles: ['tests/frontend/setup.js'],
|
||||
include: [
|
||||
'static/js/**/*.test.js',
|
||||
'tests/frontend/**/*.test.js'
|
||||
],
|
||||
coverage: {
|
||||
enabled: false,
|
||||
reportsDirectory: 'coverage/frontend'
|
||||
}
|
||||
}
|
||||
});
|
||||
Reference in New Issue
Block a user