From 988c2b2f067b18931e9c9da60f63f147adb92d3e Mon Sep 17 00:00:00 2001 From: pac7 <47831526-pac7@users.noreply.replit.com> Date: Sun, 21 Sep 2025 16:31:10 +0000 Subject: [PATCH] Restored to '20442f595c8df2c8347249ade7f015b7ae566474' Replit-Restored-To: 20442f595c8df2c8347249ade7f015b7ae566474 --- .replit | 4 - backend/static/js/alpine-components.js | 40 --- .../templates/components/auth/auth-modal.html | 3 +- .../components/layout/enhanced_header.html | 26 +- mobile_auth_test_results.md | 126 ------- test_mobile_auth.html | 154 --------- test_mobile_auth_buttons.py | 317 ------------------ 7 files changed, 16 insertions(+), 654 deletions(-) delete mode 100644 mobile_auth_test_results.md delete mode 100644 test_mobile_auth.html delete mode 100644 test_mobile_auth_buttons.py diff --git a/.replit b/.replit index f7d564d0..d3cd2656 100644 --- a/.replit +++ b/.replit @@ -35,10 +35,6 @@ outputType = "webview" localPort = 5000 externalPort = 80 -[[ports]] -localPort = 32851 -externalPort = 3001 - [[ports]] localPort = 34277 externalPort = 3000 diff --git a/backend/static/js/alpine-components.js b/backend/static/js/alpine-components.js index 723a0764..0c238994 100644 --- a/backend/static/js/alpine-components.js +++ b/backend/static/js/alpine-components.js @@ -375,8 +375,6 @@ Alpine.data('authModal', (defaultMode = 'login') => ({ this.resetForms(); } }); - - // No need for event listeners since x-init handles global exposure }, async fetchSocialProviders() { @@ -620,44 +618,6 @@ Alpine.store('toast', { }); console.log('All Alpine.js components registered successfully'); - - // Ensure global authModal is available immediately - if (typeof window !== 'undefined') { - // Create a simple proxy that will find the authModal component when called - window.authModal = { - show: (mode = 'login') => { - console.log('Attempting to show auth modal:', mode); - - // Find the authModal component in the DOM - const modalEl = document.querySelector('[x-data*="authModal"]'); - if (modalEl && modalEl._x_dataStack && modalEl._x_dataStack[0]) { - const component = modalEl._x_dataStack[0]; - if (component.show && typeof component.show === 'function') { - component.show(mode); - console.log('Auth modal opened successfully'); - return; - } - } - - // Fallback: try to find any component with a show method - const elements = document.querySelectorAll('[x-data]'); - for (let el of elements) { - if (el._x_dataStack) { - for (let stack of el._x_dataStack) { - if (stack.show && stack.mode !== undefined) { - stack.show(mode); - console.log('Auth modal opened via fallback method'); - return; - } - } - } - } - - console.error('Could not find authModal component to open'); - } - }; - console.log('Global authModal proxy created'); - } } // Try multiple registration approaches diff --git a/backend/templates/components/auth/auth-modal.html b/backend/templates/components/auth/auth-modal.html index 98848845..b8c3137a 100644 --- a/backend/templates/components/auth/auth-modal.html +++ b/backend/templates/components/auth/auth-modal.html @@ -12,10 +12,9 @@ Matches React frontend AuthDialog functionality with modal-based auth x-data="authModal" x-show="open" x-cloak - x-init="window.authModal = $data; console.log('Auth modal initialized and exposed globally')" + x-init="window.authModal = $data" class="fixed inset-0 z-50 flex items-center justify-center" @keydown.escape.window="close()" - style="display: none;" >
{% else %} -
- - + {% include 'components/ui/button.html' with variant='default' size='sm' text='Join' %} +
{% endif %} diff --git a/mobile_auth_test_results.md b/mobile_auth_test_results.md deleted file mode 100644 index cb33cb81..00000000 --- a/mobile_auth_test_results.md +++ /dev/null @@ -1,126 +0,0 @@ -# ThrillWiki Mobile Authentication Testing Results - -## Test Overview -Testing the mobile Sign In and Join buttons functionality on ThrillWiki homepage. - -## Test Plan -1. āœ… Navigate to ThrillWiki homepage on mobile -2. āœ… Locate mobile Sign In and Join buttons in header -3. šŸ”„ Test Sign In button opens authentication modal with login form -4. šŸ”„ Test Join button opens authentication modal with registration form -5. šŸ”„ Test modal close functionality (escape key and close button) -6. šŸ”„ Verify button sizing and touch-friendliness on mobile devices -7. šŸ“ Report any issues found - -## Current Implementation Analysis - -### āœ… Mobile Button Implementation Found -**Location**: `backend/templates/components/layout/enhanced_header.html` (lines 310-325) - -**Sign In Button**: -```html - -``` - -**Join Button**: -```html - -``` - -### āœ… Authentication Modal Implementation Found -**Location**: `backend/templates/components/auth/auth-modal.html` - -**Key Features**: -- āœ… Alpine.js component with global `window.authModal` exposure -- āœ… Supports both 'login' and 'register' modes -- āœ… Escape key support: `@keydown.escape.window="close()"` -- āœ… Close button with proper click handler -- āœ… Responsive design with mobile-friendly styling - -### āœ… Alpine.js Integration Found -**Location**: `backend/static/js/alpine-components.js` - -**Features**: -- āœ… `Alpine.data('authModal')` component properly defined -- āœ… Global `window.authModal` proxy with fallback handling -- āœ… Supports `show(mode)` method for 'login' and 'register' -- āœ… Proper error handling and console logging - -## Button Sizing Analysis - -### Touch-Friendly Specifications -- āœ… **Height**: `h-10` = 40px (meets 44px minimum when including padding/border) -- āœ… **Padding**: `px-4` = 16px horizontal padding -- āœ… **Minimum Width**: `min-w-[70px]` ensures adequate touch target -- āœ… **Visual Feedback**: Hover states and transitions implemented - -## Test Results (Manual Verification Required) - -### Test Status -- **Environment**: āœ… ThrillWiki server running on localhost:5000 -- **Alpine.js**: āœ… Loaded and components registered successfully -- **Auth Modal**: āœ… Initialized and exposed globally -- **Mobile Viewport**: ā³ Requires manual testing - -### Console Log Evidence -From browser console: -``` -āœ… "Alpine components script is loading..." -āœ… "Alpine available? true" -āœ… "All Alpine.js components registered successfully" -āœ… "Auth modal initialized and exposed globally" -``` - -### Known Issues -āš ļø **Minor**: `/api/v1/auth/social-providers/` returns 404 - affects social login options but not core modal functionality - -## Manual Testing Required - -Since automated browser testing requires system dependencies, manual testing is needed: - -1. **Open ThrillWiki in mobile view**: - - Navigate to http://localhost:5000 - - Open browser developer tools - - Set device emulation to mobile (375px width or similar) - -2. **Test Sign In Button**: - - Locate Sign In button in mobile header (should be visible when screen width < 768px) - - Click button and verify modal opens with login form - - Check for username/email and password fields - -3. **Test Join Button**: - - Close any open modal - - Click Join button and verify modal opens with registration form - - Check for first name, last name, email, username, and password fields - -4. **Test Modal Close**: - - Verify close button (X) works - - Verify clicking outside modal closes it - - Verify escape key closes modal - -5. **Test Touch-Friendliness**: - - Verify buttons are easily tappable on mobile - - Check button spacing and visual feedback - -## Conclusion - -Based on code analysis, the mobile authentication implementation appears **COMPLETE and WELL-IMPLEMENTED**: - -āœ… Mobile buttons are properly implemented with correct click handlers -āœ… Authentication modal supports both login and register modes -āœ… Alpine.js integration is working correctly -āœ… Modal close functionality is implemented -āœ… Button sizing meets touch-friendly guidelines -āœ… Responsive design is properly implemented - -**No critical issues found in implementation**. Manual testing recommended to verify end-to-end functionality. \ No newline at end of file diff --git a/test_mobile_auth.html b/test_mobile_auth.html deleted file mode 100644 index abd0c945..00000000 --- a/test_mobile_auth.html +++ /dev/null @@ -1,154 +0,0 @@ - - - - - - Mobile Auth Test - - - -
-

ThrillWiki Mobile Authentication Testing

-

This page will test the mobile authentication buttons functionality.

- -
-
- ā³ Test 1: Loading ThrillWiki homepage in mobile view... -
-
- ā³ Test 2: Locating mobile Sign In and Join buttons... -
-
- ā³ Test 3: Testing Sign In button functionality... -
-
- ā³ Test 4: Testing Join button functionality... -
-
- ā³ Test 5: Testing modal close functionality... -
-
- ā³ Test 6: Verifying button touch-friendliness... -
-
- -
- - -
-
- - - - - - \ No newline at end of file diff --git a/test_mobile_auth_buttons.py b/test_mobile_auth_buttons.py deleted file mode 100644 index 1ef0110a..00000000 --- a/test_mobile_auth_buttons.py +++ /dev/null @@ -1,317 +0,0 @@ -#!/usr/bin/env python3 -""" -ThrillWiki Mobile Authentication Button Testing -Tests the mobile Sign In and Join buttons functionality -""" - -import asyncio -import sys -import os -from playwright.async_api import async_playwright, expect -import time - -class MobileAuthTester: - def __init__(self): - self.base_url = "http://localhost:5000" - self.test_results = [] - self.issues_found = [] - - def log_test_result(self, test_name, status, details=""): - """Log test result and print to console""" - result = { - "test": test_name, - "status": status, # "PASS", "FAIL", "SKIP" - "details": details - } - self.test_results.append(result) - - status_emoji = "āœ…" if status == "PASS" else "āŒ" if status == "FAIL" else "āš ļø" - print(f"{status_emoji} {test_name}: {status}") - if details: - print(f" Details: {details}") - - if status == "FAIL": - self.issues_found.append(f"{test_name}: {details}") - - async def test_mobile_auth_buttons(self): - """Main test function for mobile authentication buttons""" - print("šŸš€ Starting ThrillWiki Mobile Authentication Tests\n") - print("=" * 60) - - async with async_playwright() as p: - # Launch browser in mobile mode - browser = await p.chromium.launch(headless=False, slow_mo=500) - - # Create mobile context (iPhone 12 viewport) - context = await browser.new_context( - viewport={'width': 390, 'height': 844}, - user_agent='Mozilla/5.0 (iPhone; CPU iPhone OS 14_6 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/14.0 Mobile/15E148 Safari/604.1' - ) - - page = await context.new_page() - - try: - # Test 1: Navigate to homepage - await self.test_homepage_navigation(page) - - # Test 2: Locate mobile authentication buttons - await self.test_locate_mobile_buttons(page) - - # Test 3: Test Sign In button functionality - await self.test_sign_in_button(page) - - # Test 4: Test Join button functionality - await self.test_join_button(page) - - # Test 5: Test modal close functionality - await self.test_modal_close_functionality(page) - - # Test 6: Verify button sizing and touch-friendliness - await self.test_button_sizing_and_touch_friendliness(page) - - except Exception as e: - self.log_test_result("OVERALL_TEST", "FAIL", f"Unexpected error: {str(e)}") - - finally: - await browser.close() - - # Print final results - self.print_final_results() - - async def test_homepage_navigation(self, page): - """Test 1: Navigate to ThrillWiki homepage on mobile""" - try: - print("\n1ļøāƒ£ Testing homepage navigation...") - await page.goto(self.base_url, wait_until="networkidle") - - # Wait for page to fully load - await page.wait_for_selector('header', timeout=10000) - - # Check if we're on the homepage - title = await page.title() - if "ThrillWiki" in title: - self.log_test_result("Homepage Navigation", "PASS", f"Successfully loaded: {title}") - else: - self.log_test_result("Homepage Navigation", "FAIL", f"Unexpected title: {title}") - - except Exception as e: - self.log_test_result("Homepage Navigation", "FAIL", str(e)) - - async def test_locate_mobile_buttons(self, page): - """Test 2: Locate mobile Sign In and Join buttons in header""" - try: - print("\n2ļøāƒ£ Locating mobile authentication buttons...") - - # Check for mobile section (should be visible on mobile viewport) - mobile_section = page.locator('.md\\:hidden') - await expect(mobile_section).to_be_visible() - - # Look for Sign In button specifically in mobile section - sign_in_button = page.locator('.md\\:hidden button:has-text("Sign In")') - join_button = page.locator('.md\\:hidden button:has-text("Join")') - - # Check if buttons exist and are visible - sign_in_visible = await sign_in_button.is_visible() - join_visible = await join_button.is_visible() - - if sign_in_visible and join_visible: - self.log_test_result("Locate Mobile Buttons", "PASS", "Both Sign In and Join buttons found in mobile header") - else: - missing = [] - if not sign_in_visible: - missing.append("Sign In") - if not join_visible: - missing.append("Join") - self.log_test_result("Locate Mobile Buttons", "FAIL", f"Missing buttons: {', '.join(missing)}") - - except Exception as e: - self.log_test_result("Locate Mobile Buttons", "FAIL", str(e)) - - async def test_sign_in_button(self, page): - """Test 3: Test Sign In button functionality""" - try: - print("\n3ļøāƒ£ Testing Sign In button functionality...") - - # Find the Sign In button in mobile section - sign_in_button = page.locator('.md\\:hidden button:has-text("Sign In")') - await expect(sign_in_button).to_be_visible() - - # Click the Sign In button - await sign_in_button.click() - - # Wait for authentication modal to appear - auth_modal = page.locator('[x-data*="authModal"]') - await expect(auth_modal).to_be_visible(timeout=5000) - - # Check if login form is displayed (should show "Sign In" heading) - login_heading = page.locator('h2:has-text("Sign In")') - await expect(login_heading).to_be_visible() - - # Check for login form elements - username_field = page.locator('input[type="text"], input[type="email"]').first - password_field = page.locator('input[type="password"]').first - - username_visible = await username_field.is_visible() - password_visible = await password_field.is_visible() - - if username_visible and password_visible: - self.log_test_result("Sign In Button Functionality", "PASS", "Sign In button opens modal with login form") - else: - self.log_test_result("Sign In Button Functionality", "FAIL", "Login form elements not found in modal") - - except Exception as e: - self.log_test_result("Sign In Button Functionality", "FAIL", str(e)) - - async def test_join_button(self, page): - """Test 4: Test Join button functionality""" - try: - print("\n4ļøāƒ£ Testing Join button functionality...") - - # First, close any open modal by clicking overlay or escape - try: - overlay = page.locator('.fixed.inset-0.bg-background\\/80') - if await overlay.is_visible(): - await overlay.click() - await page.wait_for_timeout(500) - except: - pass - - # Find the Join button in mobile section - join_button = page.locator('.md\\:hidden button:has-text("Join")') - await expect(join_button).to_be_visible() - - # Click the Join button - await join_button.click() - - # Wait for authentication modal to appear - auth_modal = page.locator('[x-data*="authModal"]') - await expect(auth_modal).to_be_visible(timeout=5000) - - # Check if registration form is displayed (should show "Create Account" or "Sign Up" heading) - register_heading = page.locator('h2:has-text("Create Account"), h2:has-text("Sign Up")') - await expect(register_heading).to_be_visible() - - # Check for registration form elements - first_name_field = page.locator('input[id*="first"], input[placeholder*="first" i]') - email_field = page.locator('input[type="email"]') - - first_name_visible = await first_name_field.is_visible() - email_visible = await email_field.is_visible() - - if first_name_visible and email_visible: - self.log_test_result("Join Button Functionality", "PASS", "Join button opens modal with registration form") - else: - self.log_test_result("Join Button Functionality", "FAIL", "Registration form elements not found in modal") - - except Exception as e: - self.log_test_result("Join Button Functionality", "FAIL", str(e)) - - async def test_modal_close_functionality(self, page): - """Test 5: Test modal close functionality""" - try: - print("\n5ļøāƒ£ Testing modal close functionality...") - - # Ensure modal is open (click Join button if needed) - auth_modal = page.locator('[x-data*="authModal"]') - if not await auth_modal.is_visible(): - join_button = page.locator('.md\\:hidden button:has-text("Join")') - await join_button.click() - await expect(auth_modal).to_be_visible(timeout=5000) - - # Test close button - close_button = page.locator('button:has(i.fa-times), button[aria-label*="close" i]') - if await close_button.is_visible(): - await close_button.click() - await expect(auth_modal).to_be_hidden(timeout=3000) - self.log_test_result("Modal Close Button", "PASS", "Close button successfully closes modal") - else: - self.log_test_result("Modal Close Button", "FAIL", "Close button not found") - return - - # Test escape key functionality - join_button = page.locator('.md\\:hidden button:has-text("Join")') - await join_button.click() - await expect(auth_modal).to_be_visible(timeout=5000) - - await page.keyboard.press('Escape') - await expect(auth_modal).to_be_hidden(timeout=3000) - self.log_test_result("Modal Escape Key", "PASS", "Escape key successfully closes modal") - - except Exception as e: - self.log_test_result("Modal Close Functionality", "FAIL", str(e)) - - async def test_button_sizing_and_touch_friendliness(self, page): - """Test 6: Verify button sizing and touch-friendliness""" - try: - print("\n6ļøāƒ£ Testing button sizing and touch-friendliness...") - - # Get Sign In and Join buttons - sign_in_button = page.locator('.md\\:hidden button:has-text("Sign In")') - join_button = page.locator('.md\\:hidden button:has-text("Join")') - - # Check button dimensions (should be at least 44px for touch-friendliness) - sign_in_box = await sign_in_button.bounding_box() - join_box = await join_button.bounding_box() - - touch_friendly_issues = [] - - # Check Sign In button dimensions - if sign_in_box: - if sign_in_box['height'] < 44: - touch_friendly_issues.append(f"Sign In button height ({sign_in_box['height']}px) below 44px minimum") - if sign_in_box['width'] < 44: - touch_friendly_issues.append(f"Sign In button width ({sign_in_box['width']}px) below 44px minimum") - else: - touch_friendly_issues.append("Could not measure Sign In button dimensions") - - # Check Join button dimensions - if join_box: - if join_box['height'] < 44: - touch_friendly_issues.append(f"Join button height ({join_box['height']}px) below 44px minimum") - if join_box['width'] < 44: - touch_friendly_issues.append(f"Join button width ({join_box['width']}px) below 44px minimum") - else: - touch_friendly_issues.append("Could not measure Join button dimensions") - - if touch_friendly_issues: - self.log_test_result("Button Touch-Friendliness", "FAIL", "; ".join(touch_friendly_issues)) - else: - sign_in_size = f"{sign_in_box['width']:.0f}x{sign_in_box['height']:.0f}px" if sign_in_box else "N/A" - join_size = f"{join_box['width']:.0f}x{join_box['height']:.0f}px" if join_box else "N/A" - self.log_test_result("Button Touch-Friendliness", "PASS", - f"Buttons are touch-friendly - Sign In: {sign_in_size}, Join: {join_size}") - - except Exception as e: - self.log_test_result("Button Touch-Friendliness", "FAIL", str(e)) - - def print_final_results(self): - """Print comprehensive test results""" - print("\n" + "=" * 60) - print("šŸ“Š FINAL TEST RESULTS") - print("=" * 60) - - passed = sum(1 for result in self.test_results if result["status"] == "PASS") - failed = sum(1 for result in self.test_results if result["status"] == "FAIL") - total = len(self.test_results) - - print(f"\nTotal Tests: {total}") - print(f"āœ… Passed: {passed}") - print(f"āŒ Failed: {failed}") - print(f"Success Rate: {(passed/total)*100:.1f}%") - - if self.issues_found: - print(f"\nšŸ› ISSUES FOUND ({len(self.issues_found)}):") - for i, issue in enumerate(self.issues_found, 1): - print(f" {i}. {issue}") - else: - print("\nšŸŽ‰ No issues found! All mobile authentication functionality is working correctly.") - - print("\n" + "=" * 60) - -async def main(): - """Main entry point""" - tester = MobileAuthTester() - await tester.test_mobile_auth_buttons() - -if __name__ == "__main__": - asyncio.run(main()) \ No newline at end of file