| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111 |
- """
- E2E test: Login → navigate all CRM pages via sidebar → screenshot each page.
- Verifies the Python backend serves all CRM data correctly through the Vue frontend.
- """
- import time
- import os
- from playwright.sync_api import sync_playwright
- BASE_URL = "http://localhost:80"
- SCREENSHOT_DIR = "/tmp/crm-e2e-screenshots"
- os.makedirs(SCREENSHOT_DIR, exist_ok=True)
- CRM_PAGES = [
- {"menu_text": "线索管理", "path": "/clue", "name": "clue"},
- {"menu_text": "客户管理", "path": "/customer", "name": "customer"},
- {"menu_text": "公海池", "path": "/pool", "name": "pool"},
- {"menu_text": "商机管理", "path": "/opportunity", "name": "opportunity"},
- {"menu_text": "报价单管理", "path": "/quote", "name": "quote"},
- {"menu_text": "合同列表", "path": "/contract", "name": "contract"},
- {"menu_text": "产品分类", "path": "/category", "name": "product-category"},
- {"menu_text": "产品列表", "path": "/product", "name": "product"},
- ]
- results = {"pass": [], "fail": []}
- def screenshot_name(page_name):
- return os.path.join(SCREENSHOT_DIR, f"{page_name}.png")
- with sync_playwright() as p:
- browser = p.chromium.launch(headless=True)
- page = browser.new_page(viewport={"width": 1440, "height": 900})
- # ─── LOGIN ───
- print("\n[LOGIN]")
- page.goto(f"{BASE_URL}/login", wait_until="networkidle", timeout=30000)
- page.wait_for_timeout(1000)
- page.locator('input[placeholder="用户名"]').fill("admin")
- page.locator('input[placeholder="密码"]').fill("admin123")
- page.locator('button:has-text("登")').click()
- page.wait_for_url("**/index**", timeout=20000)
- page.wait_for_load_state("networkidle", timeout=20000)
- page.wait_for_timeout(2000)
- print(f" ✅ Login successful - URL: {page.url}")
- page.screenshot(path=screenshot_name("home"), full_page=False)
- print(f" ✅ Home page screenshot saved")
- # ─── NAVIGATE CRM PAGES ───
- print("\n[CRM PAGES]")
- for page_info in CRM_PAGES:
- menu_text = page_info["menu_text"]
- page_name = page_info["name"]
- try:
- # Try clicking sidebar menu item
- sidebar_item = page.locator(f'.el-menu-item:has-text("{menu_text}"), .el-sub-menu__title:has-text("{menu_text}")').first
- if sidebar_item.count() > 0:
- sidebar_item.click()
- page.wait_for_load_state("networkidle", timeout=10000)
- page.wait_for_timeout(1500)
- else:
- # Fallback: navigate directly via URL
- page.goto(f"{BASE_URL}/{page_info['path']}", wait_until="networkidle", timeout=10000)
- page.wait_for_timeout(1500)
- # Check for table or content
- has_table = page.locator(".el-table").count() > 0
- has_content = page.locator(".app-main, .app-container, .page-container").count() > 0
- has_error = page.locator(".el-message-box, .el-notification--error").count() > 0
- status = "✅"
- if has_error:
- status = "❌"
- results["fail"].append((page_name, "Error notification visible"))
- elif has_table or has_content:
- results["pass"].append(page_name)
- else:
- status = "⚠️"
- results["fail"].append((page_name, "No table/content found"))
- page.screenshot(path=screenshot_name(page_name), full_page=False)
- print(f" {status} {menu_text} ({page_name}) - table:{has_table} content:{has_content}")
- except Exception as e:
- print(f" ❌ {menu_text} ({page_name}) - {e}")
- results["fail"].append((page_name, str(e)[:100]))
- try:
- page.screenshot(path=screenshot_name(f"{page_name}-error"), full_page=False)
- except:
- pass
- # ─── SUMMARY ───
- print(f"\n{'='*60}")
- total = len(results["pass"]) + len(results["fail"])
- print(f"RESULTS: {len(results['pass'])}/{total} PASSED")
- if results["fail"]:
- print(f"\n❌ FAILURES ({len(results['fail'])}):")
- for name, reason in results["fail"]:
- print(f" - {name}: {reason}")
- else:
- print("🎉 ALL CRM PAGES LOADED SUCCESSFULLY!")
- print(f"{'='*60}")
- print(f"\nScreenshots saved to: {SCREENSHOT_DIR}/")
- browser.close()
|