#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
模块名称：create_login_cases_full.py
模块描述：基于真实访问被测系统获取的页面元素，批量创建登录模块及可执行测试用例

被测系统：统一管理平台 https://192.168.5.44
登录页面元素（实测）：
  - 账号输入框: input[placeholder*="手机号"] (placeholder="手机号/用户名/邮箱")
  - 密码输入框: input[placeholder*="密码"] (type=password)
  - 图形验证码: input[placeholder*="图形验证"]
  - 登录按钮: button.login_btn (class="el-button login_input login_btn el-button--primary")
  - 同意协议弹窗: 点击"确定"按钮
  - 登录方式切换: 密码登录 / 短信登录 / 邮箱登录 (.login-tab)
  - 登录成功标志: URL 跳转到 #/Home，显示用户名 admin@xty12

作者：czj
创建日期：2026-07-13
"""

import asyncio
import httpx
import sys

BASE_URL = "http://localhost:8001"

# 被测系统真实信息
TARGET_URL = "https://192.168.5.44"
USERNAME = "admin@xty"
PASSWORD = "Ubains@13579"
CAPTCHA = "csba"


async def create_all():
    async with httpx.AsyncClient(timeout=30) as client:
        # ==================== 1. 创建登录模块 ====================
        print("=" * 60)
        print("【1】创建登录模块")
        print("=" * 60)
        r = await client.post(f"{BASE_URL}/api/modules", json={
            "name": "登录模块",
            "description": "统一管理平台登录功能测试：页面访问、正常登录、异常登录、登录方式切换",
            "icon": "lock",
        })
        if r.status_code == 201:
            login_module_id = r.json()["id"]
            print(f"  ✅ 登录模块创建成功: {login_module_id}")
        else:
            # 可能已存在，查询获取
            r2 = await client.get(f"{BASE_URL}/api/modules?skip=0&limit=100")
            for m in r2.json().get("items", []):
                if m["name"] == "登录模块":
                    login_module_id = m["id"]
                    print(f"  ℹ️ 登录模块已存在: {login_module_id}")
                    break

        # ==================== 2. 登录模块用例 ====================
        login_cases = build_login_cases(login_module_id)
        for case in login_cases:
            r = await client.post(f"{BASE_URL}/api/cases", json=case)
            if r.status_code == 201:
                print(f"  ✅ {case['name']}")
            else:
                print(f"  ❌ {case['name']}: {r.status_code} {r.text[:150]}")

        # ==================== 3. 创建会议管理模块 ====================
        print("\n" + "=" * 60)
        print("【3】创建会议管理模块")
        print("=" * 60)
        meeting_module_id = await create_module(client, "会议管理", "会议预约、模板、列表等会议相关功能", "calendar")

        meeting_cases = build_meeting_cases(meeting_module_id)
        for case in meeting_cases:
            r = await client.post(f"{BASE_URL}/api/cases", json=case)
            status = "✅" if r.status_code == 201 else "❌"
            print(f"  {status} {case['name']}")

        # ==================== 4. 创建数据分析模块 ====================
        print("\n" + "=" * 60)
        print("【4】创建数据分析模块")
        print("=" * 60)
        data_module_id = await create_module(client, "数据分析", "使用数据、故障数据、会议统计等数据看板", "data-line")

        data_cases = build_data_cases(data_module_id)
        for case in data_cases:
            r = await client.post(f"{BASE_URL}/api/cases", json=case)
            status = "✅" if r.status_code == 201 else "❌"
            print(f"  {status} {case['name']}")

        # ==================== 5. 创建运维管理模块 ====================
        print("\n" + "=" * 60)
        print("【5】创建运维管理模块")
        print("=" * 60)
        ops_module_id = await create_module(client, "运维管理", "运维数据、巡检报表、设备管理", "setting")

        ops_cases = build_ops_cases(ops_module_id)
        for case in ops_cases:
            r = await client.post(f"{BASE_URL}/api/cases", json=case)
            status = "✅" if r.status_code == 201 else "❌"
            print(f"  {status} {case['name']}")

        # ==================== 6. 创建管理看板模块 ====================
        print("\n" + "=" * 60)
        print("【6】创建管理看板模块")
        print("=" * 60)
        board_module_id = await create_module(client, "管理看板", "管理看板、会议室概览、通知统计", "data-board")

        board_cases = build_board_cases(board_module_id)
        for case in board_cases:
            r = await client.post(f"{BASE_URL}/api/cases", json=case)
            status = "✅" if r.status_code == 201 else "❌"
            print(f"  {status} {case['name']}")

        # ==================== 汇总 ====================
        print("\n" + "=" * 60)
        print("【汇总】")
        print("=" * 60)
        stats = await client.get(f"{BASE_URL}/api/stats/overview")
        s = stats.json()
        print(f"  模块总数: {s['modules']['total']}")
        print(f"  用例总数: {s['cases']['total']}")


async def create_module(client, name, description, icon):
    r = await client.post(f"{BASE_URL}/api/modules", json={
        "name": name, "description": description, "icon": icon
    })
    if r.status_code == 201:
        print(f"  ✅ {name}模块创建成功")
        return r.json()["id"]
    else:
        r2 = await client.get(f"{BASE_URL}/api/modules?skip=0&limit=100")
        for m in r2.json().get("items", []):
            if m["name"] == name:
                print(f"  ℹ️ {name}模块已存在")
                return m["id"]


def nav_step(order, name):
    """标准导航步骤：打开登录页 + 登录 + 同意协议 + 等待首页"""
    return {
        "order": order,
        "name": name,
        "action": "navigate",
        "params": {"url": TARGET_URL},
    }


def login_steps(start_order=1):
    """登录前置步骤序列，返回步骤列表"""
    return [
        {
            "order": start_order,
            "name": "打开登录页面",
            "action": "navigate",
            "params": {"url": TARGET_URL},
        },
        {
            "order": start_order + 1,
            "name": "等待登录表单加载",
            "action": "wait",
            "params": {"selector": 'input[placeholder*="手机号"]', "timeout": 15000},
        },
        {
            "order": start_order + 2,
            "name": "输入账号",
            "action": "fill",
            "params": {"selector": 'input[placeholder*="手机号"]', "value": USERNAME},
        },
        {
            "order": start_order + 3,
            "name": "输入密码",
            "action": "fill",
            "params": {"selector": 'input[placeholder*="密码"]', "value": PASSWORD},
        },
        {
            "order": start_order + 4,
            "name": "输入图形验证码",
            "action": "fill",
            "params": {"selector": 'input[placeholder*="图形验证"]', "value": CAPTCHA},
        },
        {
            "order": start_order + 5,
            "name": "点击登录按钮",
            "action": "click",
            "params": {"selector": "button.login_btn"},
        },
    ]


LOGIN_CONFIG = {
    "timeout": 120000,
    "screenshot": True,
    "auto_login": False,
    "step_retry_count": 2,
    "reset_login": True,
}

# 登录后需要同意协议弹窗的步骤
AGREE_STEP = {
    "name": "确认同意协议弹窗",
    "action": "click",
    "params": {
        "selectors": [
            ".el-dialog button.el-button--primary:has-text('确定')",
            ".el-dialog button:has-text('确定')",
            ".el-dialog button:has-text('同意')",
            ".el-dialog button:has-text('阅读并同意')",
            "button:has-text('确定')",
        ]
    },
}


def build_login_cases(module_id):
    """登录模块用例"""
    cases = []

    # 用例1：登录-页面访问验证
    cases.append({
        "module_id": module_id,
        "name": "登录-页面访问验证",
        "description": "验证登录页面可正常访问，标题、表单元素正确显示",
        "priority": "high",
        "tags": ["页面访问", "冒烟测试"],
        "steps": [
            nav_step(1, "打开登录页面"),
            {"order": 2, "name": "验证页面标题", "action": "assert",
             "params": {"type": "title", "expected": "统一管理平台"}},
            {"order": 3, "name": "等待账号输入框", "action": "wait",
             "params": {"selector": 'input[placeholder*="手机号"]', "timeout": 10000}},
            {"order": 4, "name": "验证密码输入框存在", "action": "assert",
             "params": {"selector": 'input[type="password"]', "type": "visible"}},
            {"order": 5, "name": "验证登录按钮存在", "action": "assert",
             "params": {"selector": "button.login_btn", "type": "visible"}},
        ],
        "config": {"timeout": 60000, "screenshot": True, "auto_login": False, "reset_login": True},
    })

    # 用例2：登录-完整登录流程
    steps = login_steps(1)
    steps.append({"order": 7, "name": "确认同意协议弹窗", "action": "click",
                  "params": {"selector": 'button:has-text("确定")'}})
    steps.append({"order": 8, "name": "等待登录成功跳转", "action": "wait",
                  "params": {"selector": "text=admin@xty", "timeout": 15000}})
    cases.append({
        "module_id": module_id,
        "name": "登录-完整登录流程",
        "description": "完整的密码登录流程：输入账号密码、图形验证码、点击登录、确认协议、验证登录成功",
        "priority": "high",
        "tags": ["核心流程", "登录", "P0"],
        "steps": steps,
        "config": LOGIN_CONFIG,
    })

    # 用例3：登录-空字段提交验证
    cases.append({
        "module_id": module_id,
        "name": "登录-空账号密码验证",
        "description": "验证账号密码为空时点击登录，系统应提示错误，不应跳转",
        "priority": "medium",
        "tags": ["异常场景"],
        "steps": [
            nav_step(1, "打开登录页面"),
            {"order": 2, "name": "等待表单加载", "action": "wait",
             "params": {"selector": 'input[placeholder*="手机号"]', "timeout": 10000}},
            {"order": 3, "name": "直接点击登录按钮（不填写）", "action": "click",
             "params": {"selector": "button.login_btn"}},
            {"order": 4, "name": "验证仍停留在登录页", "action": "assert",
             "params": {"selector": 'input[placeholder*="手机号"]', "type": "visible"}},
        ],
        "config": {"timeout": 60000, "screenshot": True, "auto_login": False, "reset_login": True},
    })

    # 用例4：登录-错误密码验证
    steps = login_steps(1)
    # 修正密码为错误密码（覆盖步骤4）
    steps[3]["params"]["value"] = "WrongPassword123"
    steps.append({"order": 7, "name": "等待错误提示出现", "action": "wait",
                  "params": {"selector": ".el-message, .el-message-box", "timeout": 10000}})
    cases.append({
        "module_id": module_id,
        "name": "登录-错误密码验证",
        "description": "验证使用错误密码登录时，系统应给出错误提示，不进入系统",
        "priority": "medium",
        "tags": ["异常场景", "安全验证"],
        "steps": steps,
        "config": {"timeout": 120000, "screenshot": True, "auto_login": False, "reset_login": True},
    })

    # 用例5：登录-登录方式切换验证
    cases.append({
        "module_id": module_id,
        "name": "登录-登录方式切换验证",
        "description": "验证密码登录/短信登录/邮箱登录三种方式可以正常切换",
        "priority": "low",
        "tags": ["UI验证"],
        "steps": [
            nav_step(1, "打开登录页面"),
            {"order": 2, "name": "等待表单加载", "action": "wait",
             "params": {"selector": 'input[placeholder*="手机号"]', "timeout": 10000}},
            {"order": 3, "name": "切换到短信登录", "action": "click",
             "params": {"selector": 'text=短信登录'}},
            {"order": 4, "name": "验证手机号输入框出现", "action": "wait",
             "params": {"selector": 'input[placeholder="手机号"]', "timeout": 5000}},
            {"order": 5, "name": "切换到邮箱登录", "action": "click",
             "params": {"selector": 'text=邮箱登录'}},
            {"order": 6, "name": "验证邮箱输入框出现", "action": "wait",
             "params": {"selector": 'input[placeholder="邮箱"]', "timeout": 5000}},
            {"order": 7, "name": "切换回密码登录", "action": "click",
             "params": {"selector": 'text=密码登录'}},
            {"order": 8, "name": "验证密码登录表单恢复", "action": "assert",
             "params": {"selector": 'input[placeholder*="手机号"]', "type": "visible"}},
        ],
        "config": {"timeout": 60000, "screenshot": True, "auto_login": False, "reset_login": True},
    })

    return cases


def build_meeting_cases(module_id):
    """会议管理模块用例（登录后访问各功能页）"""
    pages = [
        ("新建会议", "新建会议页面访问验证", "验证新建会议页面可正常打开"),
        ("会议模板", "会议模板页面访问验证", "验证会议模板页面可正常打开"),
        ("个人日程", "个人日程页面访问验证", "验证个人日程页面可正常打开"),
        ("会议室列表", "会议室列表页面访问验证", "验证会议室列表页面可正常打开"),
        ("会议列表", "会议列表页面访问验证", "验证会议列表页面可正常打开"),
        ("预定数据", "预定数据页面访问验证", "验证预定数据页面可正常打开"),
    ]
    cases = []
    for page_name, case_name, desc in pages:
        steps = login_steps(1)
        steps.append({"order": 7, "name": "确认同意协议弹窗", "action": "click",
                      "params": {"selector": 'button:has-text("确定")'}})
        steps.append({"order": 8, "name": "等待进入首页", "action": "wait",
                      "params": {"selector": "text=admin@xty", "timeout": 15000}})
        steps.append({"order": 9, "name": f"点击进入{page_name}", "action": "click",
                      "params": {"selector": f"text={page_name}"}})
        steps.append({"order": 10, "name": f"验证{page_name}页面加载", "action": "wait",
                      "params": {"selector": "body", "timeout": 10000}})
        cases.append({
            "module_id": module_id,
            "name": case_name,
            "description": desc,
            "priority": "high",
            "tags": ["页面访问", page_name],
            "steps": steps,
            "config": LOGIN_CONFIG,
        })
    return cases


def build_data_cases(module_id):
    """数据分析模块用例"""
    pages = [
        "使用数据", "故障数据", "会议统计", "通知统计",
        "会议服务统计", "会议室统计", "Welink会议统计", "SMC3.0会议统计",
    ]
    cases = []
    for page_name in pages:
        steps = login_steps(1)
        steps.append({"order": 7, "name": "确认同意协议弹窗", "action": "click",
                      "params": {"selector": 'button:has-text("确定")'}})
        steps.append({"order": 8, "name": "等待进入首页", "action": "wait",
                      "params": {"selector": "text=admin@xty", "timeout": 15000}})
        steps.append({"order": 9, "name": f"点击进入{page_name}", "action": "click",
                      "params": {"selector": f"text={page_name}"}})
        steps.append({"order": 10, "name": f"验证{page_name}页面加载", "action": "wait",
                      "params": {"selector": "body", "timeout": 10000}})
        cases.append({
            "module_id": module_id,
            "name": f"{page_name}-页面访问验证",
            "description": f"验证{page_name}数据页面可正常打开并显示",
            "priority": "medium",
            "tags": ["数据分析", page_name],
            "steps": steps,
            "config": LOGIN_CONFIG,
        })
    return cases


def build_ops_cases(module_id):
    """运维管理模块用例"""
    pages = ["运维数据", "运维统计", "巡检报表"]
    cases = []
    for page_name in pages:
        steps = login_steps(1)
        steps.append({"order": 7, "name": "确认同意协议弹窗", "action": "click",
                      "params": {"selector": 'button:has-text("确定")'}})
        steps.append({"order": 8, "name": "等待进入首页", "action": "wait",
                      "params": {"selector": "text=admin@xty", "timeout": 15000}})
        steps.append({"order": 9, "name": f"点击进入{page_name}", "action": "click",
                      "params": {"selector": f"text={page_name}"}})
        steps.append({"order": 10, "name": f"验证{page_name}页面加载", "action": "wait",
                      "params": {"selector": "body", "timeout": 10000}})
        cases.append({
            "module_id": module_id,
            "name": f"{page_name}-页面访问验证",
            "description": f"验证{page_name}页面可正常打开",
            "priority": "medium",
            "tags": ["运维管理", page_name],
            "steps": steps,
            "config": LOGIN_CONFIG,
        })
    return cases


def build_board_cases(module_id):
    """管理看板模块用例"""
    pages = ["管理看板", "会议概览", "会议室概览"]
    cases = []
    for page_name in pages:
        steps = login_steps(1)
        steps.append({"order": 7, "name": "确认同意协议弹窗", "action": "click",
                      "params": {"selector": 'button:has-text("确定")'}})
        steps.append({"order": 8, "name": "等待进入首页", "action": "wait",
                      "params": {"selector": "text=admin@xty", "timeout": 15000}})
        steps.append({"order": 9, "name": f"点击进入{page_name}", "action": "click",
                      "params": {"selector": f"text={page_name}"}})
        steps.append({"order": 10, "name": f"验证{page_name}页面加载", "action": "wait",
                      "params": {"selector": "body", "timeout": 10000}})
        cases.append({
            "module_id": module_id,
            "name": f"{page_name}-页面访问验证",
            "description": f"验证{page_name}页面可正常打开",
            "priority": "high",
            "tags": ["管理看板", page_name],
            "steps": steps,
            "config": LOGIN_CONFIG,
        })
    return cases


if __name__ == "__main__":
    asyncio.run(create_all())
    print("\n🎉 全部用例创建完成！")
