Spaces:
Running
Running
| import time | |
| import subprocess | |
| import os | |
| import signal | |
| import socket | |
| from playwright.sync_api import sync_playwright | |
| def wait_for_port(port, timeout=30): | |
| start_time = time.time() | |
| while time.time() - start_time < timeout: | |
| try: | |
| with socket.create_connection(("localhost", port), timeout=1): | |
| return True | |
| except: | |
| time.sleep(1) | |
| return False | |
| def test_advanced_features(): | |
| # 1. Start backend | |
| backend_env = os.environ.copy() | |
| backend_env["CI_MODE"] = "true" | |
| python_path = "./venv/bin/python3" if os.path.exists("./venv/bin/python3") else "python3" | |
| # Kill any existing processes on ports | |
| subprocess.run(["lsof -ti:8000 | xargs kill -9"], shell=True, stderr=subprocess.DEVNULL) | |
| subprocess.run(["lsof -ti:5173 | xargs kill -9"], shell=True, stderr=subprocess.DEVNULL) | |
| backend_proc = subprocess.Popen( | |
| [python_path, "backend/app.py"], | |
| stdout=open("backend_adv.log", "w"), | |
| stderr=subprocess.STDOUT, | |
| preexec_fn=os.setsid, | |
| env=backend_env | |
| ) | |
| # 2. Start frontend (Vite) | |
| frontend_proc = subprocess.Popen( | |
| ["npm", "run", "dev"], | |
| cwd="frontend", | |
| stdout=open("frontend_adv.log", "w"), | |
| stderr=subprocess.STDOUT, | |
| preexec_fn=os.setsid | |
| ) | |
| try: | |
| print("Waiting for servers to start...") | |
| if not wait_for_port(8000) or not wait_for_port(5173): | |
| print("Servers failed to start in time.") | |
| return | |
| with sync_playwright() as p: | |
| # Launch with microphone permissions mocked | |
| browser = p.chromium.launch( | |
| headless=True, | |
| args=[ | |
| "--use-fake-ui-for-media-stream", | |
| "--use-fake-device-for-media-stream", | |
| "--mute-audio" | |
| ] | |
| ) | |
| context = browser.new_context( | |
| permissions=["microphone"] | |
| ) | |
| page = context.new_page() | |
| # Navigate to frontend | |
| print("Navigating to frontend...") | |
| page.goto("http://localhost:5173", wait_until="networkidle") | |
| # Login | |
| print("Logging in...") | |
| page.fill("input[placeholder='admin or user']", "admin") | |
| page.fill("input[placeholder='••••••••']", "admin123") | |
| page.click("button:has-text('Login')") | |
| page.wait_for_selector("text=Dashboard", timeout=20000) | |
| # 1. Test Audio Recording & Dubbing | |
| print("Testing Audio Recording & Dubbing...") | |
| page.click("text=Audio Dub") | |
| page.wait_for_selector("text=Select Languages", timeout=20000) | |
| # Click Start Recording | |
| page.click("button:has-text('Start Recording')") | |
| print("Recording started...") | |
| time.sleep(3) # Record for 3 seconds | |
| # Click Stop Recording | |
| page.click("button:has-text('Stop')") | |
| print("Recording stopped.") | |
| # Click Dub button | |
| page.click("button:has-text('Transcribe & Dub Audio')") | |
| # Wait for result | |
| print("Waiting for audio results...") | |
| page.wait_for_selector("text=Dubbing Results", timeout=30000) | |
| page.wait_for_selector("text=Dubbed Voice Audio", timeout=30000) | |
| # Check for segments | |
| if page.locator("text=Translated Timeline").is_visible(): | |
| print("Audio segments rendered successfully!") | |
| # 2. Test Document Translation | |
| print("Testing Document Translation...") | |
| page.click("text=Documents") | |
| page.wait_for_selector("text=Click to upload documents", timeout=20000) | |
| # Upload mock doc | |
| with page.expect_file_chooser() as fc_info: | |
| page.click(".dropzone") | |
| file_chooser = fc_info.value | |
| file_chooser.set_files("testcase/e2e/assets/test_doc.docx") | |
| # Click Translate Document | |
| page.click("button:has-text('Translate Document')") | |
| # Wait for result link | |
| print("Waiting for document results...") | |
| try: | |
| page.wait_for_selector("text=Download Translated DOCX", timeout=60000) | |
| print("Document translation successful!") | |
| except Exception as e: | |
| print(f"Document translation failed or timed out: {e}") | |
| page.screenshot(path="doc_e2e_failure.png") | |
| print("Screenshot saved to doc_e2e_failure.png") | |
| # Log the output area specifically | |
| print("Page content around buttons:") | |
| print(page.content()[-2000:]) # Show some end part of content | |
| raise e | |
| # 3. Test Settings | |
| print("Testing Settings...") | |
| page.click("text=Settings") | |
| page.wait_for_selector("text=Whisper ASR Model Size", timeout=20000) | |
| # Change model size | |
| page.select_option("select.select-control", "tiny") | |
| print("Settings updated successfully!") | |
| browser.close() | |
| print("All advanced features tested successfully!") | |
| finally: | |
| # Cleanup | |
| try: | |
| os.killpg(os.getpgid(backend_proc.pid), signal.SIGTERM) | |
| except ProcessLookupError: | |
| pass | |
| try: | |
| os.killpg(os.getpgid(frontend_proc.pid), signal.SIGTERM) | |
| except ProcessLookupError: | |
| pass | |
| print("Servers stopped.") | |
| if __name__ == "__main__": | |
| test_advanced_features() | |