Spaces:
Runtime error
Runtime error
| """End-to-end tests for the Video Analyzer application using Playwright.""" | |
| from __future__ import annotations | |
| import subprocess | |
| import time | |
| from typing import Generator | |
| import pytest | |
| from playwright.sync_api import Page, expect | |
| def app_url() -> Generator[str, None, None]: | |
| """Start the Gradio app and return its URL.""" | |
| # Start the app in background | |
| process = subprocess.Popen( | |
| ["python", "app.py"], | |
| stdout=subprocess.PIPE, | |
| stderr=subprocess.PIPE, | |
| ) | |
| # Wait for app to start | |
| time.sleep(10) | |
| yield "http://127.0.0.1:7860" | |
| # Cleanup | |
| process.terminate() | |
| process.wait() | |
| class TestUnifiedChatbotUI: | |
| """E2E tests for the unified chatbot Video Analyzer UI.""" | |
| def test_homepage_loads(self, page: Page, app_url: str): | |
| """Test that the homepage loads correctly.""" | |
| page.goto(app_url) | |
| # Check title is visible | |
| expect(page.locator("text=Video Analyzer")).to_be_visible() | |
| def test_app_subtitle_visible(self, page: Page, app_url: str): | |
| """Test that the app subtitle is visible.""" | |
| page.goto(app_url) | |
| # Check subtitle | |
| expect(page.locator("text=Analyze YouTube videos")).to_be_visible() | |
| def test_login_button_visible(self, page: Page, app_url: str): | |
| """Test that the login button is visible.""" | |
| page.goto(app_url) | |
| # Look for login button (HuggingFace sign in) | |
| login_button = page.locator("button:has-text('Sign in')") | |
| expect(login_button).to_be_visible() | |
| def test_chatbot_visible(self, page: Page, app_url: str): | |
| """Test that the chatbot component is visible.""" | |
| page.goto(app_url) | |
| # Check for chatbot container | |
| chatbot = page.locator("[data-testid='chatbot']") | |
| expect(chatbot).to_be_visible() | |
| def test_welcome_message_displayed(self, page: Page, app_url: str): | |
| """Test that welcome message is shown on load.""" | |
| page.goto(app_url) | |
| # Wait for page to load | |
| page.wait_for_timeout(2000) | |
| # Check for welcome message content | |
| expect(page.locator("text=Welcome to Video Analyzer")).to_be_visible() | |
| def test_message_input_exists(self, page: Page, app_url: str): | |
| """Test that the message input field exists.""" | |
| page.goto(app_url) | |
| # Check for text input with placeholder | |
| msg_input = page.locator("textarea[placeholder*='YouTube URL']") | |
| expect(msg_input).to_be_visible() | |
| def test_send_button_exists(self, page: Page, app_url: str): | |
| """Test that the Send button exists.""" | |
| page.goto(app_url) | |
| # Check for Send button | |
| send_btn = page.locator("button:has-text('Send')") | |
| expect(send_btn).to_be_visible() | |
| def test_clear_chat_button_exists(self, page: Page, app_url: str): | |
| """Test that the Clear Chat button exists.""" | |
| page.goto(app_url) | |
| # Check for Clear Chat button | |
| clear_btn = page.locator("button:has-text('Clear Chat')") | |
| expect(clear_btn).to_be_visible() | |
| def test_knowledge_base_status_visible(self, page: Page, app_url: str): | |
| """Test that knowledge base status is displayed.""" | |
| page.goto(app_url) | |
| # Wait for status to load | |
| page.wait_for_timeout(2000) | |
| # Check for knowledge base empty message | |
| expect(page.locator("text=Knowledge base is empty")).to_be_visible() | |
| def test_can_type_in_message_input(self, page: Page, app_url: str): | |
| """Test that user can type in the message input.""" | |
| page.goto(app_url) | |
| # Find and fill the message input | |
| msg_input = page.locator("textarea[placeholder*='YouTube URL']") | |
| msg_input.fill("https://youtube.com/watch?v=test123") | |
| # Verify the input has the text | |
| expect(msg_input).to_have_value("https://youtube.com/watch?v=test123") | |
| def test_send_button_is_primary(self, page: Page, app_url: str): | |
| """Test that Send button has primary styling.""" | |
| page.goto(app_url) | |
| # Check for primary variant button | |
| send_btn = page.locator("button:has-text('Send')").first | |
| expect(send_btn).to_be_visible() | |
| def test_login_prompt_for_unauthenticated_users(self, page: Page, app_url: str): | |
| """Test that unauthenticated users see login prompt in welcome.""" | |
| page.goto(app_url) | |
| # Wait for welcome message | |
| page.wait_for_timeout(2000) | |
| # Check for sign in prompt | |
| expect(page.locator("text=sign in with HuggingFace")).to_be_visible() | |
| def test_clear_chat_works(self, page: Page, app_url: str): | |
| """Test that Clear Chat button clears the chatbot.""" | |
| page.goto(app_url) | |
| # Wait for welcome message to appear | |
| page.wait_for_timeout(2000) | |
| expect(page.locator("text=Welcome to Video Analyzer")).to_be_visible() | |
| # Click clear chat | |
| clear_btn = page.locator("button:has-text('Clear Chat')") | |
| clear_btn.click() | |
| # Wait a moment for clear to process | |
| page.wait_for_timeout(500) | |
| # Welcome message should be gone (chat cleared) | |
| expect(page.locator("text=Welcome to Video Analyzer")).not_to_be_visible() | |
| def test_responsive_layout(self, page: Page, app_url: str): | |
| """Test that the layout is responsive.""" | |
| page.goto(app_url) | |
| # Set mobile viewport | |
| page.set_viewport_size({"width": 375, "height": 667}) | |
| # UI elements should still be visible | |
| expect(page.locator("text=Video Analyzer")).to_be_visible() | |
| expect(page.locator("button:has-text('Send')")).to_be_visible() | |
| def test_chatbot_has_height(self, page: Page, app_url: str): | |
| """Test that chatbot has appropriate height.""" | |
| page.goto(app_url) | |
| # Get chatbot element | |
| chatbot = page.locator("[data-testid='chatbot']") | |
| box = chatbot.bounding_box() | |
| # Should have significant height (500px configured) | |
| assert box is not None | |
| assert box["height"] >= 400 # Allow some flexibility | |
| def test_theme_applied(self, page: Page, app_url: str): | |
| """Test that Soft theme is applied (lighter colors).""" | |
| page.goto(app_url) | |
| # The Soft theme should be applied - check body has gradio styling | |
| body = page.locator("body") | |
| expect(body).to_be_visible() | |