- Update test URLs from localhost:18188 to gandalf.local:8188 - Make check_interval test flexible (accept any valid 1-168 value) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
185 lines
5.5 KiB
Python
185 lines
5.5 KiB
Python
"""Full functionality test for ComfyUI-ModelSync."""
|
|
|
|
import pytest
|
|
from playwright.sync_api import Page, expect
|
|
|
|
|
|
COMFYUI_URL = "http://gandalf.local:8188"
|
|
|
|
|
|
def test_full_workflow(page: Page):
|
|
"""Test the complete ModelSync workflow."""
|
|
# Capture console for debugging
|
|
errors = []
|
|
page.on("console", lambda msg: errors.append(msg.text) if msg.type == "error" else None)
|
|
|
|
# 1. Load ComfyUI
|
|
page.goto(COMFYUI_URL)
|
|
page.wait_for_load_state("networkidle")
|
|
page.wait_for_timeout(3000)
|
|
|
|
# 2. Open Model Sync panel via JS (button may be in collapsed menu)
|
|
page.evaluate("() => { if (window.ModelSyncPanel) window.ModelSyncPanel.toggle(); }")
|
|
|
|
# 3. Verify panel opens
|
|
panel = page.locator(".modelsync-panel")
|
|
expect(panel).to_be_visible(timeout=5000)
|
|
|
|
# 4. Verify Models tab is active and shows models
|
|
models_tab = page.locator(".modelsync-tab:has-text('Models')")
|
|
assert "active" in models_tab.get_attribute("class")
|
|
|
|
# Should have models from previous scan
|
|
models_list = page.locator(".modelsync-models-list")
|
|
expect(models_list).to_be_visible()
|
|
|
|
# 5. Click Scan button
|
|
scan_btn = page.locator("button[data-action='scan']")
|
|
scan_btn.click()
|
|
page.wait_for_timeout(2000)
|
|
|
|
# Status should update
|
|
status = page.locator(".modelsync-status")
|
|
status_text = status.text_content()
|
|
assert "Scanned" in status_text, f"Expected 'Scanned' in status, got: {status_text}"
|
|
|
|
# 6. Switch to Sync Targets tab
|
|
targets_tab = page.locator(".modelsync-tab:has-text('Sync Targets')")
|
|
targets_tab.click()
|
|
page.wait_for_timeout(500)
|
|
|
|
# Verify tab content is visible
|
|
targets_content = page.locator("#modelsync-targets")
|
|
expect(targets_content).not_to_have_class("hidden")
|
|
|
|
# 7. Switch to Settings tab
|
|
settings_tab = page.locator(".modelsync-tab:has-text('Settings')")
|
|
settings_tab.click()
|
|
page.wait_for_timeout(500)
|
|
|
|
# Verify settings form
|
|
auto_update_checkbox = page.locator("#auto-update-enabled")
|
|
expect(auto_update_checkbox).to_be_visible()
|
|
|
|
check_interval = page.locator("#check-interval")
|
|
expect(check_interval).to_be_visible()
|
|
# Verify it has a valid numeric value (1-168 range)
|
|
value = check_interval.input_value()
|
|
assert value.isdigit() and 1 <= int(value) <= 168, f"check_interval should be 1-168, got {value}"
|
|
|
|
# 8. Test search functionality
|
|
models_tab.click()
|
|
page.wait_for_timeout(500)
|
|
|
|
search_input = page.locator(".modelsync-search")
|
|
search_input.fill("safetensor")
|
|
page.wait_for_timeout(500)
|
|
|
|
# Should filter results
|
|
rows = page.locator(".modelsync-table tbody tr")
|
|
row_count = rows.count()
|
|
print(f"Filtered rows with 'safetensor': {row_count}")
|
|
|
|
# Clear search
|
|
search_input.fill("")
|
|
page.wait_for_timeout(500)
|
|
|
|
# 9. Close panel
|
|
close_btn = page.locator(".modelsync-close")
|
|
close_btn.click()
|
|
|
|
# Panel should be gone
|
|
expect(panel).not_to_be_visible()
|
|
|
|
# 10. Re-open to verify state persists
|
|
page.evaluate("() => { if (window.ModelSyncPanel) window.ModelSyncPanel.toggle(); }")
|
|
page.wait_for_timeout(1000)
|
|
|
|
# Should still show models
|
|
models_list = page.locator(".modelsync-models-list")
|
|
expect(models_list).to_be_visible()
|
|
|
|
# Take final screenshot
|
|
page.screenshot(path="/tmp/comfyui-modelsync-final.png")
|
|
print("Final screenshot saved to /tmp/comfyui-modelsync-final.png")
|
|
|
|
# Report any JS errors
|
|
if errors:
|
|
print(f"\nJS Errors encountered: {len(errors)}")
|
|
for err in errors[:5]:
|
|
print(f" - {err}")
|
|
|
|
|
|
def test_api_endpoints(page: Page):
|
|
"""Test all API endpoints work correctly."""
|
|
# Status
|
|
response = page.request.get(f"{COMFYUI_URL}/modelsync/status")
|
|
assert response.ok
|
|
data = response.json()
|
|
assert "scheduler" in data
|
|
assert "models" in data
|
|
assert "sync" in data
|
|
|
|
# Models list
|
|
response = page.request.get(f"{COMFYUI_URL}/modelsync/models")
|
|
assert response.ok
|
|
data = response.json()
|
|
assert "models" in data
|
|
models = data["models"]
|
|
print(f"Total models tracked: {len(models)}")
|
|
|
|
# Config
|
|
response = page.request.get(f"{COMFYUI_URL}/modelsync/config")
|
|
assert response.ok
|
|
config = response.json()
|
|
assert "auto_update_enabled" in config
|
|
assert "check_interval_hours" in config
|
|
|
|
# Targets
|
|
response = page.request.get(f"{COMFYUI_URL}/modelsync/targets")
|
|
assert response.ok
|
|
data = response.json()
|
|
assert "targets" in data
|
|
|
|
# Scan
|
|
response = page.request.post(f"{COMFYUI_URL}/modelsync/models/scan")
|
|
assert response.ok
|
|
data = response.json()
|
|
assert "scanned" in data
|
|
print(f"Scan result: {data}")
|
|
|
|
|
|
def test_settings_save(page: Page):
|
|
"""Test saving settings."""
|
|
# Get current config
|
|
response = page.request.get(f"{COMFYUI_URL}/modelsync/config")
|
|
original_config = response.json()
|
|
|
|
# Update config
|
|
new_config = {
|
|
"check_interval_hours": "12",
|
|
"verify_downloads": "true",
|
|
}
|
|
response = page.request.post(
|
|
f"{COMFYUI_URL}/modelsync/config",
|
|
data=new_config,
|
|
headers={"Content-Type": "application/json"},
|
|
)
|
|
assert response.ok
|
|
|
|
# Verify change
|
|
response = page.request.get(f"{COMFYUI_URL}/modelsync/config")
|
|
updated = response.json()
|
|
assert updated["check_interval_hours"] == "12"
|
|
|
|
# Restore original
|
|
page.request.post(
|
|
f"{COMFYUI_URL}/modelsync/config",
|
|
data=original_config,
|
|
headers={"Content-Type": "application/json"},
|
|
)
|
|
|
|
|
|
if __name__ == "__main__":
|
|
pytest.main([__file__, "-v", "-s"])
|