lora-manager-e2e
Performs E2E validation of LoRa Manager, including server orchestration and frontend-to-backend integration testing.
Install
mkdir -p .claude/skills/lora-manager-e2e && curl -L -o skill.zip "https://agentskills.codes/api/skills/download/6933" && unzip -o skill.zip -d .claude/skills/lora-manager-e2e && rm skill.zipInstalls to .claude/skills/lora-manager-e2e
Activation
This is the description your AI agent reads to decide when to run this skill — the better it matches your request, the more reliably it fires.
End-to-end testing and validation for LoRa Manager features. Use when performing automated E2E validation of LoRa Manager standalone mode, including starting/restarting the server, using Chrome DevTools MCP to interact with the web UI at http://127.0.0.1:8188/loras, and verifying frontend-to-backend functionality. Covers workflow validation, UI interaction testing, and integration testing between the standalone Python backend and the browser frontend.Key capabilities
- →Start LoRa Manager standalone server
- →Automate UI form interactions
- →Verify frontend-to-backend API calls
- →Capture UI snapshots
- →Monitor console messages
How it works
It uses Chrome DevTools MCP to programmatically interact with the LoRa Manager web UI and verify backend responses.
Inputs & outputs
When to use lora-manager-e2e
- →Start LoRa Manager standalone server
- →Validate UI form interactions
- →Perform E2E test snapshots
- →Test integration between backend and browser
About this skill
LoRa Manager E2E Testing
This skill provides workflows and utilities for end-to-end testing of LoRa Manager using Chrome DevTools MCP.
Conventions Used in This Document
{PORT}: The server port. The default candidate is8188, but8188is commonly occupied by a live ComfyUI process and MUST NOT be assumed to be free. Always check availability first (see Port Selection) and use a free port (e.g.8199) for the E2E run. Substitute the actual port for every{PORT}in the commands below.<repo-root>: The repository/worktree root. Always run commands from the repo or worktree root; never assume a specific absolute path (paths such as/home/<user>/...differ per machine). The E2E scripts resolve the project root themselves, but fixture/settings paths are relative to<repo-root>.
SANDBOX (MANDATORY)
Read this section before running anything. Every E2E run MUST target a throwaway sandbox, never the real user data. A fresh subagent that skips this section WILL permanently mutate real user recipes.
- Portable settings: create
<repo-root>/settings.json(gitignored) with"use_portable_settings": trueplus sandboxedfolder_paths(lora/checkpoint roots) andrecipes_path. This keeps the configuration inside the repo instead of the real user config dir (~/.config/ComfyUI-LoRA-Manager/settings.json). - Sandboxed paths: point
folder_paths/recipes_path/example_images_pathat disposable dirs — e.g. under/tmp/opencode/<plan-name>-e2e/(or worktree-local dirs). NEVER point the E2E at the real library (~/models/...), real recipe dir, or real settings. - Never touch the real config: the real user config at
~/.config/ComfyUI-LoRA-Manager/settings.jsonand the real recipe dir must remain byte-identical before and after the run. - Record real-data protection proof before starting and after finishing:
Also confirm# BEFORE: snapshot real config + recipe library state sha256sum ~/.config/ComfyUI-LoRA-Manager/settings.json > /tmp/opencode/<plan>-e2e/settings.before.sha256 ls ~/models/recipes/*.recipe.json 2>/dev/null | wc -l > /tmp/opencode/<plan>-e2e/recipes-count.before.txt find ~/models/recipes -name '*.recipe.json' -newermt "$(date -Iseconds)" | head # expect empty after run # AFTER: record again, then diff the two snapshots. Any change = the run leaked into real data.<repo-root>/git statusstays clean forsettings.json/cache/(both are gitignored).
Portable Settings Example
{
"use_portable_settings": true,
"folder_paths": {
"loras": ["/tmp/opencode/<plan>-e2e/models/loras"],
"checkpoints": ["/tmp/opencode/<plan>-e2e/models/checkpoints"],
"unet": ["/tmp/opencode/<plan>-e2e/models/checkpoints"],
"diffusers": []
},
"recipes_path": "/tmp/opencode/<plan>-e2e/recipes",
"example_images_path": "/tmp/opencode/<plan>-e2e/example_images"
}
The scanner computes and persists model hashes during the library scan, so the sandbox model dirs just need the model files + .metadata.json sidecars (see Fixture + Fresh-State Guidance).
Time Budgets & Abort Guidance
A fresh subagent should complete a sandboxed standalone E2E in well under 30 minutes. Budget each phase:
| Phase | Expected duration | Abort if |
|---|---|---|
| Port check + sandbox setup | < 2 min | — |
| Server start (detached) + readiness | < 30 s | > 60 s (2x) → stop |
| Chrome DevTools MCP connect | < 1 min | > 2 min → stop |
| Per entry-point run (after fixtures ready) | < 5 min | > 10 min (2x) → stop |
| Fixture reset + cache clear between runs | < 1 min | > 2 min → stop |
Abort rule: if a phase exceeds ~2x its budget, OR any single tool call fails/retries 3+ times in a row, STOP. Do not loop or retry blindly. Report BLOCKED with: the phase, the last observed state (server PID + ss -tlnp output, page snapshot, last API response), and the suspected cause. Record the partial state as evidence; a clean BLOCKED report is more valuable than an hour of retries.
Prerequisites
- LoRa Manager project cloned and dependencies installed (
pip install -r requirements.txt) — run everything from<repo-root> - Chrome browser available for debugging
- Chrome DevTools MCP connected
ss(orlsof/netstat) available for port checks:ss -tlnp
Port Selection
8188 is only the default candidate. Verify it is actually free before every run:
# Is anything listening on 8188?
ss -tlnp | grep ':8188' || echo "8188 is free"
- If a process holds
8188(e.g. a live ComfyUI — pid 6575 on this machine), pick a different free port, e.g.8199:ss -tlnp | grep ':8199' || echo "8199 is free" - Never kill a process you did not start for this E2E. The live ComfyUI is off-limits. Pick a free port instead.
- Use your chosen port for all subsequent commands (server, Chrome launch, browser URLs).
Quick Start Workflow (sandboxed)
1. Prepare the sandbox
cd <repo-root> # ALWAYS run from the repo/worktree root
mkdir -p /tmp/opencode/<plan>-e2e/models/{loras,checkpoints}
mkdir -p /tmp/opencode/<plan>-e2e/{recipes,example_images,recipes-before}
# write <repo-root>/settings.json per the portable-settings example above
# record real-data protection proof (see SANDBOX section)
2. Check port availability
ss -tlnp | grep ':{PORT}' || echo "port {PORT} is free"
If {PORT} is occupied by an unrelated process, pick a free one and use it everywhere below. When in doubt use 8199.
3. Start LoRa Manager Standalone (detached)
The standalone server dies with the shell unless launched fully detached — a plain background & from the bash tool is killed when the tool call returns. Launch via the helper script:
python .agents/skills/lora-manager-e2e/scripts/start_server.py --port {PORT} --wait --timeout 30 --detach
Or manually (equivalent detached form):
setsid nohup python standalone.py --port {PORT} --host 127.0.0.1 < /dev/null \
>> /tmp/opencode/<plan>-e2e/server.log 2>&1 &
echo "started" # record the printed/pidfile PID for cleanup
Verify it is listening before proceeding (readiness poll is not a substitute for this):
ss -tlnp | grep ':{PORT}'
Record the server PID for cleanup: the helper script writes it to /tmp/lora-manager-e2e-server-{PORT}.pid; a manual setsid launch has no pidfile, so capture it explicitly (e.g. from ss -tlnp).
4. Open Chrome Debug Mode
# Chrome with remote debugging on port 9222 (note the {PORT} URL)
google-chrome --remote-debugging-port=9222 --user-data-dir=/tmp/chrome-lora-manager http://127.0.0.1:{PORT}/loras
5. Connect Chrome DevTools MCP
Ensure the MCP server is connected to Chrome at http://localhost:9222. Verify with list_pages — if it fails with "browser is already running", see Chrome DevTools MCP Troubleshooting.
6. Navigate and Interact
Use Chrome DevTools MCP tools to:
- Take snapshots:
take_snapshot - Click elements:
click - Fill forms:
fillorfill_form - Evaluate scripts:
evaluate_script - Wait for elements:
wait_for
Common E2E Test Patterns
Pattern: Full Page Load Verification
# Navigate to LoRA list page
navigate_page(type="url", url="http://127.0.0.1:{PORT}/loras")
# Wait for page to load
wait_for(text="LoRAs", timeout=10000)
# Take snapshot to verify UI state
snapshot = take_snapshot()
Pattern: Restart Server for Configuration Changes
# Stop current server (if running), start with new configuration.
# --restart only kills the E2E server this script started before (via its pidfile);
# it refuses to blindly kill unrelated processes on the port.
python .agents/skills/lora-manager-e2e/scripts/start_server.py --port {PORT} --restart --wait --detach
# Wait and refresh browser
navigate_page(type="reload", ignoreCache=True)
wait_for(text="LoRAs", timeout=15000)
Pattern: Verify Backend API via Frontend
# Execute script in browser to call backend API
result = evaluate_script(function="""
async () => {
const response = await fetch('/loras/api/list');
const data = await response.json();
return { count: data.length, firstItem: data[0]?.name };
}
""")
Pattern: Form Submission Flow
# Fill a form (e.g., search or filter)
fill_form(elements=[
{"uid": "search-input", "value": "character"},
])
# Click submit button
click(uid="search-button")
# Wait for results
wait_for(text="Results", timeout=5000)
# Verify results via snapshot
snapshot = take_snapshot()
Pattern: Modal Dialog Interaction
# Open modal (e.g., add LoRA)
click(uid="add-lora-button")
# Wait for modal to appear
wait_for(text="Add LoRA", timeout=3000)
# Fill modal form
fill_form(elements=[
{"uid": "lora-name", "value": "Test LoRA"},
{"uid": "lora-path", "value": "/path/to/lora.safetensors"},
])
# Submit
click(uid="modal-submit-button")
# Wait for success message or close
wait_for(text="Success", timeout=5000)
Fixture + Fresh-State Guidance
For rematch/repair E2E runs, seed the sandboxed recipes_path with hand-written fixture recipes. Rules (validated by the task-8 E2E):
- Filename constraint: each file MUST be named
f"{id}.recipe.json"and the in-JSONidfield MUST equal the filename. Discovery accepts any*.recipe.json, but persistence resolves the path viaget_recipe_json_pathand_save_recipe_persistentlyreturnsFalseon a mismatch → the fixture would be counted as an error.recipe-a.recipe.json→ in-JSON"id": "recipe-a"
- File format: mirror an existing recipe JSON — top-level
id,file_path,title,loras,fingerprint,gen_params; lora entries per the persistence conventions (hash,file_name,modelVersionId,isDeleted, ..
Content truncated.
When not to use it
- →Testing non-web interfaces
- →Validating production deployment environments
Prerequisites
Limitations
- →Requires Chrome remote debugging
- →Limited to LoRa Manager standalone mode
How it compares
It enables automated end-to-end testing of the UI and backend integration rather than manual browser-based verification.
Compared to similar skills
lora-manager-e2e side by side with the closest alternatives in the catalog.
| Skill | Installs | Updated | Safety | Difficulty |
|---|---|---|---|---|
| lora-manager-e2e (this skill) | 1 | 6mo | Review | Advanced |
| dev | 2 | 6mo | Review | Advanced |
| examples-auto-run | 2 | 3mo | Review | Intermediate |
| migrate | 1 | 5mo | Review | Intermediate |
Try saying
Example prompts that trigger this skill in your AI assistant.
You might also like
dev
atopile
LLM-focused workflow for working in this repo: compile Zig, run the orchestrated test runner, consume test-report.json/html artifacts, and discover/debug ConfigFlags.
examples-auto-run
openai
Run python examples in auto mode with logging, rerun helpers, and background control.
migrate
alirezarezvani
Migrate from Cypress or Selenium to Playwright. Use when user mentions "cypress", "selenium", "migrate tests", "convert tests", "switch to playwright", "move from cypress", or "replace selenium".
mobile-use-setup
minitap-ai
Interactive setup wizard for Minitap mobile-use SDK. USE WHEN user wants to set up mobile automation, configure mobile-use SDK, connect iOS or Android devices, or create a new mobile testing project.
create-environments
PrimeIntellect-ai
Create or migrate verifiers environments for the Prime Lab ecosystem. Use when asked to build a new environment from scratch, port an eval or benchmark from papers or other libraries, start from an environment on the Hub, or convert existing tasks into a package that exposes load_environment and installs cleanly with prime env install.
tdd-migrate
parcadei
TDD workflow for migrations - orchestrate agents, zero main context growth