File size: 6,401 Bytes
f7156b4
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
7da7ce7
 
f7156b4
 
 
 
 
 
 
 
7da7ce7
 
3410c2b
 
7da7ce7
 
3410c2b
f7156b4
 
 
 
7da7ce7
f7156b4
 
 
7da7ce7
 
f7156b4
 
7da7ce7
 
 
f7156b4
7da7ce7
 
f7156b4
 
7da7ce7
 
f7156b4
7da7ce7
 
 
 
 
 
 
 
 
 
 
 
 
f7156b4
 
7da7ce7
 
 
f7156b4
7da7ce7
 
f7156b4
 
7da7ce7
 
 
 
 
 
 
 
 
 
 
 
 
f7156b4
7da7ce7
 
f7156b4
 
7da7ce7
 
 
f7156b4
7da7ce7
 
 
 
 
f7156b4
 
7da7ce7
 
 
f7156b4
7da7ce7
 
3410c2b
 
7da7ce7
 
 
 
 
3410c2b
7da7ce7
 
f7156b4
 
7da7ce7
 
 
 
 
 
 
 
 
 
f7156b4
7da7ce7
 
f7156b4
7da7ce7
 
f7156b4
 
7da7ce7
 
f7156b4
7da7ce7
 
 
f7156b4
7da7ce7
 
f7156b4
 
7da7ce7
 
 
 
 
 
 
 
 
 
 
f7156b4
7da7ce7
 
 
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
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
"""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


@pytest.fixture(scope="module")
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()