#!/usr/bin/env python3 """WEVIA Playwright Visual Test Runner โ€” Screenshot all capabilities""" import asyncio, json, time, os, sys from playwright.async_api import async_playwright SSDIR = "/var/www/html/test-report/screenshots" RESULTS_FILE = "/var/www/html/test-report/playwright-results.json" BASE = "https://weval-consulting.com" os.makedirs(SSDIR, exist_ok=True) # Test definitions: (id, label, message, wait_seconds) TESTS = [ ("greeting", "๐Ÿ‘‹ Greeting", "Bonjour, presente WEVAL Consulting en 3 phrases", 12), ("pdf-audit", "๐Ÿ“„ PDF Audit Cyber", "Genere un PDF audit cybersecurite pour une PME marocaine", 45), ("pdf-cdc", "๐Ÿ“‹ PDF Cahier des Charges", "Genere un cahier des charges pour un projet ERP SAP migration", 45), ("swot", "๐Ÿ“Š SWOT", "Analyse SWOT de la transformation digitale bancaire au Maroc", 45), ("ishikawa", "๐Ÿ”ฌ Ishikawa", "Diagramme Ishikawa causes-effets probleme de stock en entreprise", 45), ("porter", "๐Ÿ“ˆ Porter", "5 forces de Porter pour le marche du cloud computing au Maghreb", 45), ("mermaid", "๐Ÿ“ Mermaid Schema", "Schema mermaid du processus achats en 5 etapes", 45), ("python", "๐Ÿ Python ETL", "Ecris un pipeline ETL Python complet avec pandas pour traiter un CSV", 40), ("react", "โš›๏ธ React Dashboard", "Cree un composant React dashboard KPI avec 4 cartes et graphique", 40), ("image", "๐ŸŽจ Image Art", "Genere une image artistique futuriste de smart city au Maroc", 12), ("logo", "โœ๏ธ Logo SVG", "Genere 4 variantes logo pour DataVision startup IA au Maroc", 40), ("websearch", "๐ŸŒ Web Search", "Quelles sont les dernieres actualites au Maroc cette semaine ?", 20), ("consulting", "๐Ÿข SAP vs Oracle", "Compare SAP S/4HANA vs Oracle Fusion Cloud ERP en 5 criteres", 45), ("skills", "๐Ÿง  Skills", "Quelles sont tes 20 competences completes ?", 15), ("long-content", "๐Ÿ“ Long Content", "Ecris un article complet de 1500 mots sur la transformation digitale des banques au Maroc avec introduction, 5 parties et conclusion", 60), ] async def run_tests(test_ids=None): results = [] async with async_playwright() as pw: browser = await pw.chromium.launch(headless=True, args=["--no-sandbox", "--disable-dev-shm-usage"]) ctx = await browser.new_context(viewport={"width": 1400, "height": 900}) page = await ctx.new_page() # Login print("๐Ÿ” Login...") await page.goto(f"{BASE}/login.html", wait_until="networkidle", timeout=15000) await page.fill('#user', "yacine") await page.fill('#pass', "YacineWeval2026") await page.click("button") await page.wait_for_timeout(3000) # Go to WEVIA print("๐Ÿ  WEVIA...") await page.goto(f"{BASE}/wevia-ia/wevia.html", wait_until="networkidle", timeout=15000) await page.wait_for_timeout(2000) await page.screenshot(path=f"{SSDIR}/pw-home.png") for tid, label, msg, wait in TESTS: if test_ids and tid not in test_ids: continue print(f"๐Ÿงช {label}...") t0 = time.time() try: # Click "Nouvelle discussion" to start fresh try: new_btn = page.locator("text=Nouvelle discussion").first if await new_btn.is_visible(timeout=2000): await new_btn.click() await page.wait_for_timeout(1500) except: pass # Find and fill input inp = page.locator("textarea, input[placeholder*='question'], input[placeholder*='message'], #messageInput, .chat-input").first await page.wait_for_timeout(3000) await inp.fill(msg, force=True) await page.wait_for_timeout(300) # Send try: send = page.locator("button.send-btn, #sendBtn, button[type='submit'], .send-message, button:has(svg[viewBox])").first await send.click(timeout=3000) except: await inp.press("Enter") # Wait for response await page.wait_for_timeout(wait * 1000) # Scroll to bottom of chat await page.evaluate("window.scrollTo(0, document.body.scrollHeight)") await page.wait_for_timeout(500) # Screenshot ss_path = f"{SSDIR}/pw-{tid}.png" await page.screenshot(path=ss_path, full_page=False) elapsed = round(time.time() - t0, 1) results.append({ "id": tid, "label": label, "status": "pass", "time": elapsed, "screenshot": f"pw-{tid}.png", "message": msg }) print(f" โœ… {label} ({elapsed}s)") except Exception as e: elapsed = round(time.time() - t0, 1) results.append({ "id": tid, "label": label, "status": "error", "time": elapsed, "error": str(e)[:200], "screenshot": None, "message": msg }) print(f" โŒ {label}: {e}") await browser.close() # Save results output = { "timestamp": time.strftime("%Y-%m-%dT%H:%M:%SZ", time.gmtime()), "total": len(results), "pass": sum(1 for r in results if r["status"] == "pass"), "fail": sum(1 for r in results if r["status"] != "pass"), "tests": results } with open(RESULTS_FILE, "w") as f: json.dump(output, f, ensure_ascii=False) print(f"\n{'โœ…' if output['fail']==0 else 'โš ๏ธ'} {output['pass']}/{output['total']} โ€” Results: {RESULTS_FILE}") return output if __name__ == "__main__": # Accept test IDs as args: python3 pw-tests.py greeting pdf-audit swot test_ids = sys.argv[1:] if len(sys.argv) > 1 else None asyncio.run(run_tests(test_ids))