From 0e9ec9693b424fded6bea412d7899585cf04acfb Mon Sep 17 00:00:00 2001 From: Bryce Date: Thu, 7 Aug 2025 07:28:41 -0700 Subject: [PATCH] playwright tests. --- app/routes/imap.py | 4 +- playwright.config.py | 35 +++++++++++ tests/test_full_user_flow.py | 115 +++++++++++++++++++++++++++++++++++ 3 files changed, 153 insertions(+), 1 deletion(-) create mode 100644 playwright.config.py create mode 100644 tests/test_full_user_flow.py diff --git a/app/routes/imap.py b/app/routes/imap.py index 60d58ef..2d53608 100644 --- a/app/routes/imap.py +++ b/app/routes/imap.py @@ -197,7 +197,9 @@ def sync_imap_folders(): else: # Just return the updated folders list folders = Folder.query.filter_by(user_id=current_user.id).all() - return render_template('partials/folders_list.html', folders=folders) + response=make_response(render_template('partials/folders_list.html', folders=folders)) + response.headers['HX-Trigger'] = 'close-modal' + return response except Exception as e: logging.exception("Error syncing IMAP folders: %s", e) diff --git a/playwright.config.py b/playwright.config.py new file mode 100644 index 0000000..276c187 --- /dev/null +++ b/playwright.config.py @@ -0,0 +1,35 @@ +import os +from playwright.sync_api import sync_playwright + +config = { + "use": [ + { + "browserName": "chromium", + "headless": True, + "slowMo": 0, + } + ], + "projects": [ + { + "name": "chromium", + "use": { + "browserName": "chromium", + "headless": os.getenv("PLAYWRIGHT_HEADLESS", "false").lower() == "true", + "slowMo": 0, + }, + } + ], + "webServer": { + "command": "python manage.py runserver --host=0.0.0.0 --port=5002", + "url": "http://localhost:5002", + "reuseExistingServer": True, + "timeout": 120, + "stdout": "pipe", + "stderr": "pipe", + }, + "testDir": "./tests", + "fullyParallel": False, + "retries": 0, + "reporter": "list", + "timeout": 30000, +} \ No newline at end of file diff --git a/tests/test_full_user_flow.py b/tests/test_full_user_flow.py new file mode 100644 index 0000000..222217c --- /dev/null +++ b/tests/test_full_user_flow.py @@ -0,0 +1,115 @@ +import pytest +import playwright.sync_api +from playwright.sync_api import expect +import uuid +import time + + +def test_full_user_flow(playwright: playwright.sync_api.Playwright): + """ + Test the complete user flow: + 1. Navigate to localhost:5001 + 2. Go to signup page from login + 3. Create a new user + 4. Configure IMAP with specified details + 5. Sync folders + 6. Verify at least 3 folder cards are displayed + """ + + # Launch browser + browser = playwright.chromium.launch(headless=False) + context = browser.new_context() + page = context.new_page() + + try: + # Generate unique data for this test run + import random + random_number = random.randint(1000, 9999) + test_email = f"testuser{random_number}@example.com" + test_username = f"user{random_number}" + + # Step 1: Navigate to localhost:5000 (login page) + page.goto("http://localhost:5001") + + # Wait for page to load + page.wait_for_load_state("networkidle") + + # Step 2: Navigate to signup page + # Click the "Sign up" link + page.click("a:has-text('Sign up')") + + # Wait for navigation to complete + page.wait_for_load_state("networkidle") + + # Step 3: Create a new user + # Fill out signup form + page.fill("input[name='first_name']", "Test") + page.fill("input[name='last_name']", "User") + page.fill("input[name='email']", test_email) + page.fill("input[name='password']", "TestPassword123") + page.fill("input[name='confirm_password']", "TestPassword123") + page.check("input[name='terms']") + + # Submit signup form + page.click("button:has-text('Create Account')") + + # Wait for navigation to complete + page.wait_for_load_state("networkidle") + + # Step 3: Configure IMAP + # Wait for and click the "Configure IMAP" button + configure_button = page.locator("button:has-text('Configure IMAP')") + configure_button.click() + + # Wait for modal to appear + page.wait_for_selector("#imap-modal") + + # Fill out IMAP configuration form + page.fill("input[name='server']", "localhost") + page.fill("input[name='port']", "5143") + page.fill("input[name='username']", "user1@example.com") + page.fill("input[name='password']", "password1") + + # Uncheck SSL checkbox + page.uncheck("input[name='use_ssl']") + + # Submit IMAP configuration form + page.click("button[type='submit']") + + # Wait for connection test to complete + page.wait_for_selector("button:has-text('Configure Folder Types')") + + # Step 4: Sync folders + # Click the "Configure Folder Types" button + page.click("button:has-text('Configure Folder Types')") + + # Step 5: Click "Save and Continue" on the final modal + page.click("button:has-text('Save and Continue')") + + # Wait for modal to close and navigation to complete + page.wait_for_load_state("networkidle") + + # Wait for modal to appear and folders to sync + page.wait_for_selector("#folders-list", timeout=10000) + + # Step 6: Verify at least 3 folder cards are displayed + folder_cards = page.locator(".card.bg-base-100.shadow-xl") + + # Wait for at least 3 folder cards to be visible + page.wait_for_function("document.querySelectorAll('.card.bg-base-100.shadow-xl').length >= 3", timeout=15000) + + # Get the count of folder cards + count = folder_cards.count() + print(f"Found {count} folder cards") + + # Verify we have at least 3 folder cards + assert count >= 3, f"Expected at least 3 folder cards, but found {count}" + + # Verify each folder card has the expected structure + for i in range(min(3, count)): + card = folder_cards.nth(i) + expect(card).to_be_visible() + + finally: + # Close browser + browser.close() \ No newline at end of file