#!/usr/bin/env python3
"""
Novalon管理系统全面业务流程测试 - 最终版
确保在同一个浏览器上下文中保持登录状态
"""

import time
import json
from datetime import datetime
from playwright.sync_api import sync_playwright, Page

class TestResult:
    def __init__(self):
        self.total = 0
        self.passed = 0
        self.failed = 0
        self.errors = []
        self.start_time = datetime.now()
    
    def add_pass(self, test_name):
        self.total += 1
        self.passed += 1
        print(f"✅ {test_name} - 通过")
    
    def add_fail(self, test_name, error):
        self.total += 1
        self.failed += 1
        self.errors.append({"test": test_name, "error": str(error)})
        print(f"❌ {test_name} - 失败: {error}")
    
    def print_summary(self):
        duration = (datetime.now() - self.start_time).total_seconds()
        print("\n" + "="*80)
        print("测试总结")
        print("="*80)
        print(f"总测试数: {self.total}")
        print(f"通过: {self.passed} ✅")
        print(f"失败: {self.failed} ❌")
        print(f"成功率: {(self.passed/self.total*100):.2f}%")
        print(f"耗时: {duration:.2f}秒")
        
        if self.errors:
            print("\n失败详情:")
            for error in self.errors:
                print(f"  - {error['test']}: {error['error']}")
        print("="*80)

result = TestResult()

def login_and_keep_session(page: Page):
    """登录并保持会话"""
    try:
        page.goto("http://localhost:3002/login")
        page.wait_for_load_state("networkidle")
        
        page.fill('input[placeholder="请输入用户名"]', 'admin')
        page.fill('input[placeholder="请输入密码"]', 'admin123')
        page.click('button:has-text("登录")')
        
        # 等待Token保存到localStorage
        for i in range(10):
            time.sleep(1)
            token = page.evaluate("localStorage.getItem('token')")
            if token:
                print(f"✅ 登录成功，Token: {token[:50]}...")
                return True
        
        return False
    except Exception as e:
        print(f"登录失败: {e}")
        return False

def test_page_load(page: Page, name: str, url: str):
    """测试页面加载"""
    print(f"\n📋 测试{name}...")
    
    try:
        # 使用点击导航而不是goto，保持会话
        # 先回到首页
        if page.url != 'http://localhost:3002/dashboard':
            page.goto("http://localhost:3002/dashboard")
            page.wait_for_load_state("networkidle")
            time.sleep(1)
        
        # 通过侧边栏导航
        try:
            # 尝试点击侧边栏菜单
            menu_item = page.locator(f'text="{name}"').first
            if menu_item.is_visible():
                menu_item.click()
                page.wait_for_load_state("networkidle")
                time.sleep(2)
            else:
                # 如果菜单不可见，直接导航
                page.goto(url)
                page.wait_for_load_state("networkidle")
                time.sleep(2)
        except:
            # 如果点击失败，直接导航
            page.goto(url)
            page.wait_for_load_state("networkidle")
            time.sleep(2)
        
        # 检查是否被重定向到登录页
        if '/login' in page.url:
            result.add_fail(f"{name}-页面加载", "被重定向到登录页，会话丢失")
            return
        
        # 验证页面加载
        page.wait_for_selector('table, [class*="card"], [class*="stats"], [class*="tree"]', timeout=5000)
        
        result.add_pass(f"{name}-页面加载")
        
    except Exception as e:
        result.add_fail(f"{name}-页面加载", e)

def main():
    print("="*80)
    print("Novalon管理系统全面业务流程测试")
    print("="*80)
    print(f"测试时间: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}")
    print("="*80)
    
    with sync_playwright() as p:
        # 启动浏览器
        browser = p.chromium.launch(headless=True)
        context = browser.new_context()
        page = context.new_page()
        
        try:
            # 登录并保持会话
            print("\n🔐 测试登录...")
            if login_and_keep_session(page):
                result.add_pass("登录功能")
            else:
                result.add_fail("登录功能", "登录失败")
                return
            
            # 测试仪表板
            test_page_load(page, "仪表板", "http://localhost:3002/dashboard")
            
            # 测试用户管理
            test_page_load(page, "用户管理", "http://localhost:3002/users")
            
            # 测试角色管理
            test_page_load(page, "角色管理", "http://localhost:3002/roles")
            
            # 测试菜单管理
            test_page_load(page, "菜单管理", "http://localhost:3002/menus")
            
            # 测试字典管理
            test_page_load(page, "字典管理", "http://localhost:3002/dict")
            
            # 测试系统配置
            test_page_load(page, "系统配置", "http://localhost:3002/sys/config")
            
            # 测试文件管理
            test_page_load(page, "文件管理", "http://localhost:3002/files")
            
            # 测试通知管理
            test_page_load(page, "通知管理", "http://localhost:3002/notice")
            
            # 测试操作日志
            test_page_load(page, "操作日志", "http://localhost:3002/oplog")
            
            # 测试登录日志
            test_page_load(page, "登录日志", "http://localhost:3002/loginlog")
            
        except Exception as e:
            print(f"\n❌ 测试执行出错: {e}")
            import traceback
            traceback.print_exc()
        
        finally:
            browser.close()
    
    # 打印测试总结
    result.print_summary()
    
    # 返回退出码
    return 0 if result.failed == 0 else 1

if __name__ == "__main__":
    exit(main())
