Spaces:
Build error
Build error
| #!/usr/bin/env python3 | |
| """ | |
| Playwright test script to verify the chat widget at http://localhost:8000/chat-widget | |
| Tests: page loading, JavaScript errors, CSS formatting, UI elements, chat functionality | |
| """ | |
| import asyncio | |
| import sys | |
| from playwright.async_api import async_playwright | |
| import json | |
| from datetime import datetime | |
| async def test_chat_widget(): | |
| """Comprehensive test of the chat widget interface""" | |
| async with async_playwright() as p: | |
| # Launch browser in headed mode so we can see what's happening | |
| browser = await p.chromium.launch(headless=False, slow_mo=1000) | |
| context = await browser.new_context( | |
| viewport={'width': 1280, 'height': 720} | |
| ) | |
| # Enable console logging to capture JavaScript errors | |
| page = await context.new_page() | |
| console_messages = [] | |
| errors = [] | |
| def handle_console(msg): | |
| console_messages.append({ | |
| 'type': msg.type, | |
| 'text': msg.text, | |
| 'location': msg.location | |
| }) | |
| print(f"Console {msg.type}: {msg.text}") | |
| def handle_page_error(error): | |
| errors.append(str(error)) | |
| print(f"Page Error: {error}") | |
| def handle_response(response): | |
| if response.status >= 400: | |
| print(f"HTTP Error: {response.status} - {response.url}") | |
| page.on('console', handle_console) | |
| page.on('pageerror', handle_page_error) | |
| page.on('response', handle_response) | |
| try: | |
| print("π Starting chat widget test...") | |
| # Test 1: Page Loading | |
| print("\nπ Test 1: Loading page at http://localhost:8000/chat-widget") | |
| try: | |
| response = await page.goto('http://localhost:8000/chat-widget', wait_until='networkidle') | |
| print(f"β Page loaded with status: {response.status}") | |
| if response.status != 200: | |
| print(f"β Unexpected status code: {response.status}") | |
| return False | |
| except Exception as e: | |
| print(f"β Failed to load page: {e}") | |
| return False | |
| # Wait for page to fully load | |
| await page.wait_for_load_state('domcontentloaded') | |
| await asyncio.sleep(2) # Give time for any async loading | |
| # Test 2: JavaScript Errors | |
| print("\nπ Test 2: Checking for JavaScript errors") | |
| js_errors = [msg for msg in console_messages if msg['type'] == 'error'] | |
| # Filter out 404 errors that might be for optional resources | |
| critical_js_errors = [] | |
| resource_404_errors = [] | |
| for error in js_errors: | |
| if "Failed to load resource" in error['text'] and "404" in error['text']: | |
| resource_404_errors.append(error) | |
| else: | |
| critical_js_errors.append(error) | |
| if critical_js_errors: | |
| print(f"β Found {len(critical_js_errors)} critical JavaScript errors:") | |
| for error in critical_js_errors: | |
| print(f" - {error['text']}") | |
| return False | |
| else: | |
| print("β No critical JavaScript errors found") | |
| if resource_404_errors: | |
| print(f"β οΈ Found {len(resource_404_errors)} resource 404 errors (may be non-critical):") | |
| for error in resource_404_errors: | |
| print(f" - {error['text']}") | |
| if errors: | |
| print(f"β Found {len(errors)} page errors:") | |
| for error in errors: | |
| print(f" - {error}") | |
| return False | |
| else: | |
| print("β No page errors found") | |
| # Test 3: CSS and Layout Check | |
| print("\nπ¨ Test 3: Checking CSS formatting and layout") | |
| # Check if main container exists and is visible | |
| main_container = page.locator('#chat-widget, .chat-container, .chat-widget') | |
| if await main_container.count() > 0: | |
| print("β Main chat container found") | |
| # Check if container is visible | |
| if await main_container.first.is_visible(): | |
| print("β Main container is visible") | |
| else: | |
| print("β Main container is not visible") | |
| return False | |
| else: | |
| print("β Main chat container not found") | |
| return False | |
| # Test 4: UI Elements Visibility and Positioning | |
| print("\nπ Test 4: Checking UI elements visibility and positioning") | |
| # Check for common chat widget elements | |
| elements_to_check = [ | |
| {'selector': 'input[type="text"], textarea, .message-input', 'name': 'Message input field'}, | |
| {'selector': 'button[type="submit"], .send-button, .submit-button', 'name': 'Send button'}, | |
| {'selector': '.chat-messages, .messages-container, .conversation', 'name': 'Messages container'}, | |
| ] | |
| all_elements_found = True | |
| for element in elements_to_check: | |
| locator = page.locator(element['selector']) | |
| count = await locator.count() | |
| if count > 0: | |
| is_visible = await locator.first.is_visible() | |
| print(f"β {element['name']}: Found ({count}) and {'visible' if is_visible else 'hidden'}") | |
| if not is_visible: | |
| all_elements_found = False | |
| else: | |
| print(f"β {element['name']}: Not found") | |
| all_elements_found = False | |
| if not all_elements_found: | |
| print("β οΈ Some UI elements missing or hidden, but continuing with tests...") | |
| # Test 5: Chat Interface Functionality | |
| print("\n㪠Test 5: Testing chat interface functionality") | |
| # Try to find and interact with the input field | |
| input_field = page.locator('input[type="text"], textarea, .message-input').first | |
| send_button = page.locator('button[type="submit"], .send-button, .submit-button').first | |
| if await input_field.count() > 0 and await send_button.count() > 0: | |
| print("β Found input field and send button") | |
| try: | |
| # Test typing in the input field | |
| await input_field.fill("Hello, this is a test message") | |
| print("β Successfully typed in input field") | |
| # Test clicking send button | |
| await send_button.click() | |
| print("β Successfully clicked send button") | |
| # Wait a moment for any response | |
| await asyncio.sleep(3) | |
| except Exception as e: | |
| print(f"β οΈ Chat interaction failed: {e}") | |
| else: | |
| print("β οΈ Could not find input field or send button for interaction test") | |
| # Test 6: Take Screenshot | |
| print("\nπΈ Test 6: Taking screenshot for visual confirmation") | |
| timestamp = datetime.now().strftime("%Y%m%d_%H%M%S") | |
| screenshot_path = f"/Users/petergits/dev/voiceCal-ai-v1/chat_widget_test_{timestamp}.png" | |
| await page.screenshot(path=screenshot_path, full_page=True) | |
| print(f"β Screenshot saved to: {screenshot_path}") | |
| # Additional checks for common CSS issues | |
| print("\nπ§ Additional CSS and Layout Checks:") | |
| # Check page title | |
| title = await page.title() | |
| print(f"π Page title: {title}") | |
| # Check body background and basic styling | |
| body_styles = await page.evaluate(""" | |
| () => { | |
| const body = document.body; | |
| const computedStyles = window.getComputedStyle(body); | |
| return { | |
| backgroundColor: computedStyles.backgroundColor, | |
| fontFamily: computedStyles.fontFamily, | |
| margin: computedStyles.margin, | |
| padding: computedStyles.padding | |
| }; | |
| } | |
| """) | |
| print(f"π¨ Body styles: {json.dumps(body_styles, indent=2)}") | |
| # Check if any CSS files failed to load | |
| css_errors = [msg for msg in console_messages if 'css' in msg['text'].lower() or 'stylesheet' in msg['text'].lower()] | |
| if css_errors: | |
| print(f"β οΈ Found potential CSS loading issues:") | |
| for error in css_errors: | |
| print(f" - {error['text']}") | |
| else: | |
| print("β No CSS loading errors detected") | |
| print("\nπ Test completed successfully!") | |
| print(f"π Summary:") | |
| print(f" - Console messages: {len(console_messages)}") | |
| print(f" - JavaScript errors: {len(js_errors)}") | |
| print(f" - Page errors: {len(errors)}") | |
| print(f" - Screenshot saved: {screenshot_path}") | |
| return True | |
| except Exception as e: | |
| print(f"β Test failed with exception: {e}") | |
| return False | |
| finally: | |
| # Keep browser open for a moment to see the final state | |
| print("\nβ³ Keeping browser open for 5 seconds for manual inspection...") | |
| await asyncio.sleep(5) | |
| await browser.close() | |
| if __name__ == "__main__": | |
| print("π§ͺ Chat Widget Playwright Test") | |
| print("=" * 50) | |
| try: | |
| result = asyncio.run(test_chat_widget()) | |
| if result: | |
| print("\nβ All tests passed!") | |
| sys.exit(0) | |
| else: | |
| print("\nβ Some tests failed!") | |
| sys.exit(1) | |
| except KeyboardInterrupt: | |
| print("\nβΉοΈ Test interrupted by user") | |
| sys.exit(1) | |
| except Exception as e: | |
| print(f"\nπ₯ Test crashed: {e}") | |
| sys.exit(1) |