File size: 3,695 Bytes
6182d7b
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
"""
Test: AudioGallery file serving and UI flow for video ID f-H9bbi0Vyw.
Server must already be running on http://localhost:7860.
"""
import sys
from pathlib import Path
from playwright.sync_api import sync_playwright, expect

VIDEO_ID = "f-H9bbi0Vyw"
BASE_URL = "http://localhost:7860"
STEMS = ["bass", "drums", "guitar", "music", "other", "piano", "vocals"]
SEPARATED = Path("D:/Projects/SeparateTracks/separated/htdemucs_6s") / VIDEO_ID


def test_file_endpoint(page):
    """Part 1: verify each /file= URL returns audio data (200 + audio MIME)."""
    print("\n=== Part 1: /file= endpoint ===")
    all_ok = True
    for stem in STEMS:
        path = (SEPARATED / f"{stem}.mp3").as_posix()
        url = f"{BASE_URL}/file={path}"
        resp = page.request.head(url)
        status = resp.status
        ct = resp.headers.get("content-type", "")
        ok = status == 200 and "audio" in ct
        symbol = "OK" if ok else "FAIL"
        print(f"  {symbol} {stem:8s}  HTTP {status}  {ct}")
        if not ok:
            all_ok = False
    return all_ok


def test_ui_flow(page):
    """Part 2: enter video ID, click button, wait for gallery, verify audio elements."""
    print("\n=== Part 2: UI flow ===")

    page.goto(BASE_URL)
    page.wait_for_load_state("networkidle")
    page.screenshot(path="specs/screenshots/01_initial.png", full_page=True)
    print("  Screenshot: 01_initial.png")

    # Fill in the video ID
    textbox = page.get_by_label("YouTube Video ID")
    textbox.fill(VIDEO_ID)
    page.screenshot(path="specs/screenshots/02_filled.png", full_page=True)
    print(f"  Entered video ID: {VIDEO_ID}")

    # Click Separate Tracks
    page.get_by_role("button", name="Separate Tracks").click()
    print("  Clicked 'Separate Tracks' — waiting for pipeline (CPU may take ~10 min)…")

    # Wait for the AudioGallery HTML to appear (long timeout for CPU demucs)
    try:
        page.wait_for_selector(".audio-gallery-container", timeout=720_000)
    except Exception:
        page.screenshot(path="specs/screenshots/03_timeout.png", full_page=True)
        print("  ❌ Timed out waiting for .audio-gallery-container")
        return False

    page.screenshot(path="specs/screenshots/03_gallery.png", full_page=True)
    print("  Screenshot: 03_gallery.png")

    # Count audio elements
    audio_els = page.locator("audio").all()
    print(f"  Found {len(audio_els)} <audio> element(s)")

    # Check each audio src
    all_ok = True
    for i, el in enumerate(audio_els):
        src = el.get_attribute("src") or ""
        # Verify src ends in .mp3 and contains the video ID or /file=
        ok = ".mp3" in src and ("/file=" in src or VIDEO_ID in src)
        symbol = "OK" if ok else "FAIL"
        print(f"  {symbol} audio[{i}] src={src[:80]}")
        if not ok:
            all_ok = False

    # Verify progress textbox shows "Done."
    progress = page.get_by_label("Progress").input_value()
    done_ok = "Done." in progress or "Separation complete" in progress
    print(f"  {'OK' if done_ok else 'FAIL'} Progress box: {progress[-60:].strip()!r}")

    return all_ok and len(audio_els) == 7


def main():
    Path("specs/screenshots").mkdir(parents=True, exist_ok=True)

    with sync_playwright() as p:
        browser = p.chromium.launch(headless=True)
        page = browser.new_page()

        endpoint_ok = test_file_endpoint(page)
        ui_ok = test_ui_flow(page)

        browser.close()

    print("\n=== Summary ===")
    print(f"  /file= endpoint: {'PASS' if endpoint_ok else 'FAIL'}")
    print(f"  UI flow:         {'PASS' if ui_ok else 'FAIL'}")
    sys.exit(0 if (endpoint_ok and ui_ok) else 1)


if __name__ == "__main__":
    main()