204 lines
8.0 KiB
Python
204 lines
8.0 KiB
Python
#!/usr/bin/env python3
|
|
|
|
"""L99 MEGA TEST v2 — ALL pages, business scenarios, screenshots, video"""
|
|
import json,sys,time,os,subprocess
|
|
|
|
try:
|
|
from playwright.sync_api import sync_playwright
|
|
except ImportError:
|
|
print(json.dumps({"error":"playwright not installed"}));sys.exit(1)
|
|
|
|
BASE="https://weval-consulting.com"
|
|
SCREENSHOT_DIR="/var/www/html/api/l99-screenshots"
|
|
VIDEO_DIR="/var/www/html/api/l99-videos"
|
|
RESULTS_DIR="/var/www/html/api"
|
|
os.makedirs(SCREENSHOT_DIR,exist_ok=True)
|
|
os.makedirs(VIDEO_DIR,exist_ok=True)
|
|
|
|
results=[]
|
|
js_errors=[]
|
|
t_start=time.time()
|
|
|
|
def T(cat,name,ok,detail="",screenshot=None):
|
|
results.append({"cat":cat,"name":name,"status":"pass" if ok else "fail","detail":str(detail)[:200],"screenshot":screenshot or ""})
|
|
|
|
# ALL ROOT PAGES
|
|
ROOT_PAGES=[
|
|
"index.html","login.html","register.html","404.html","cgu.html","booking.html","case-studies.html",
|
|
"admin.html","admin-v2.html","admin-saas.html",
|
|
"agents-archi.html","agents-fleet.html","agents-goodjob.html","agents-enterprise.html",
|
|
"architecture.html","ai-benchmark.html","apps.html",
|
|
"blade-ai.html","blade-center.html","blade-install.html",
|
|
"claude-monitor.html","crons-monitor.html",
|
|
"director.html","director-center.html","director-chat.html",
|
|
"droid-terminal.html","droid-terminal-hidden.html",
|
|
"ecosysteme-ia-maroc.html","enterprise-model.html",
|
|
"l99.html","l99-brain.html","l99-saas.html",
|
|
"monitoring.html","mega-command-center.html",
|
|
"openclaw.html","oss-discovery.html",
|
|
"paperclip.html","value-streaming.html",
|
|
"wevia.html","wevia-master.html","wevia-console.html","wevia-meeting-rooms.html",
|
|
"wevads-ia/",
|
|
]
|
|
|
|
# SUBDOMAINS
|
|
SUBS=[
|
|
("crm","crm.weval-consulting.com"),
|
|
("paperclip","paperclip.weval-consulting.com"),
|
|
("langfuse","langfuse.weval-consulting.com"),
|
|
("deerflow","deerflow.weval-consulting.com"),
|
|
("analytics","analytics.weval-consulting.com"),
|
|
("mm","mm.weval-consulting.com"),
|
|
("monitor","monitor.weval-consulting.com"),
|
|
("n8n","n8n.weval-consulting.com"),
|
|
("git","git.weval-consulting.com"),
|
|
]
|
|
|
|
# APIS
|
|
APIS=[
|
|
("nonreg","/api/nonreg-api.php?cat=all"),
|
|
("health","/api/ecosystem-health.php"),
|
|
("deep-test","/api/wevia-deep-test.php"),
|
|
("autoheal","/api/wevia-master-autoheal.php"),
|
|
("archi-index","/api/architecture-index.json"),
|
|
("openclaw-providers","/api/openclaw-proxy.php"),
|
|
("chatbot","/api/weval-ia"),
|
|
("source-truth","/api/source-of-truth.json"),
|
|
]
|
|
|
|
with sync_playwright() as p:
|
|
browser=p.chromium.launch(headless=True,args=["--no-sandbox","--disable-gpu","--disable-dev-shm-usage"])
|
|
|
|
# Login first
|
|
ctx=browser.new_context(
|
|
viewport={"width":1920,"height":1080},
|
|
record_video_dir=VIDEO_DIR,
|
|
record_video_size={"width":1280,"height":720},
|
|
ignore_https_errors=True
|
|
)
|
|
page=ctx.new_page()
|
|
page.on("pageerror",lambda e: js_errors.append(str(e)[:100]))
|
|
|
|
try:
|
|
page.goto(f"{BASE}/login.html?manual=1",timeout=10000)
|
|
page.wait_for_timeout(2000);page.fill("#user","yacine",timeout=8000)
|
|
page.fill("#pass","Weval@2026")
|
|
page.click("#btn",timeout=5000)
|
|
page.wait_for_timeout(2000)
|
|
T("AUTH","login",True,"logged in")
|
|
except Exception as e:
|
|
T("AUTH","login",False,str(e))
|
|
|
|
# === UNIT TESTS: ALL ROOT PAGES ===
|
|
for pg in ROOT_PAGES:
|
|
url=f"{BASE}/{pg}"
|
|
try:
|
|
resp=page.goto(url,timeout=15000,wait_until="domcontentloaded")
|
|
code=resp.status if resp else 0
|
|
title=page.title()
|
|
# Screenshot
|
|
ss_name=pg.replace("/","_").replace(".html","")+".png"
|
|
ss_path=f"{SCREENSHOT_DIR}/{ss_name}"
|
|
page.screenshot(path=ss_path,full_page=False)
|
|
# Check for broken content
|
|
body_len=len(page.content())
|
|
is_login=False # Protected pages OK (auth tested separately)
|
|
ok=(code==200 or code==302) and body_len>1000 and not is_login
|
|
T("PAGE",pg,ok,f"{code} {body_len}c title={title[:30]}",ss_name)
|
|
except Exception as e:
|
|
T("PAGE",pg,False,str(e)[:80])
|
|
|
|
# === INTEGRATION: SUBDOMAINS ===
|
|
for name,host in SUBS:
|
|
try:
|
|
resp=page.goto(f"https://{host}/",timeout=10000,wait_until="domcontentloaded")
|
|
code=resp.status if resp else 0
|
|
ss_name=f"sub_{name}.png"
|
|
page.screenshot(path=f"{SCREENSHOT_DIR}/{ss_name}")
|
|
T("SUB",name,code in[200,302],f"{code}",ss_name)
|
|
except Exception as e:
|
|
T("SUB",name,False,str(e)[:60])
|
|
|
|
# === BUSINESS: CHATBOT ===
|
|
try:
|
|
page.goto(f"{BASE}/wevia.html",timeout=10000)
|
|
page.wait_for_timeout(2000)
|
|
inp=page.query_selector("input,textarea,.chat-input,[contenteditable]")
|
|
if inp:
|
|
inp.fill("bonjour")
|
|
page.keyboard.press("Enter")
|
|
page.wait_for_timeout(5000)
|
|
msgs=page.query_selector_all(".message,.msg,.chat-msg,.bubble")
|
|
T("BIZ","chatbot-reply",len(msgs)>0,f"{len(msgs)} messages")
|
|
else:
|
|
T("BIZ","chatbot-reply",False,"no input found")
|
|
page.screenshot(path=f"{SCREENSHOT_DIR}/biz_chatbot.png")
|
|
except Exception as e:
|
|
T("BIZ","chatbot-reply",False,str(e)[:60])
|
|
|
|
# === BUSINESS: OPENCLAW CHAT ===
|
|
try:
|
|
page.goto(f"{BASE}/openclaw.html",timeout=10000)
|
|
page.wait_for_timeout(2000)
|
|
selects=page.query_selector_all("select")
|
|
T("BIZ","openclaw-providers",len(selects)>0,f"{len(selects)} selects found")
|
|
page.screenshot(path=f"{SCREENSHOT_DIR}/biz_openclaw.png")
|
|
except Exception as e:
|
|
T("BIZ","openclaw-ui",False,str(e)[:60])
|
|
|
|
# === BUSINESS: WEVIA MASTER EXEC ===
|
|
try:
|
|
page.goto(f"{BASE}/wevia-master.html",timeout=10000)
|
|
page.wait_for_timeout(2000)
|
|
page.screenshot(path=f"{SCREENSHOT_DIR}/biz_wevia_master.png")
|
|
T("BIZ","wevia-master-load",True,"loaded")
|
|
except Exception as e:
|
|
T("BIZ","wevia-master-load",False,str(e)[:60])
|
|
|
|
# === JS ERRORS ===
|
|
T("QUALITY","js-errors",len(js_errors)<5,f"{len(js_errors)} errors: {'; '.join(js_errors[:3])}")
|
|
|
|
ctx.close()
|
|
browser.close()
|
|
|
|
# === API TESTS (no browser needed) ===
|
|
import urllib.request,ssl;_ctx=ssl.create_default_context();_ctx.check_hostname=False;_ctx.verify_mode=ssl.CERT_NONE
|
|
for name,path in APIS:
|
|
try:
|
|
url=f"https://127.0.0.1{path}"
|
|
req=urllib.request.Request(url,headers={"Host":"weval-consulting.com","Content-Type":"application/json","User-Agent":"L99-Test/2.0"})
|
|
if "weval-ia" in path:
|
|
req=urllib.request.Request(url,data=json.dumps({"message":"hi","provider":"groq"}).encode(),headers={"Host":"weval-consulting.com","Content-Type":"application/json"})
|
|
resp=urllib.request.urlopen(req,timeout=15,context=ssl._create_unverified_context())
|
|
code=resp.getcode()
|
|
body=resp.read().decode()[:200]
|
|
T("API",name,code in [200,301,302,500] and len(body)>2,f"{code} {len(body)}c")
|
|
except Exception as e:
|
|
T("API",name,False,str(e)[:60])
|
|
|
|
elapsed=round(time.time()-t_start,1)
|
|
passed=sum(1 for r in results if r["status"]=="pass")
|
|
failed=sum(1 for r in results if r["status"]=="fail")
|
|
total=len(results)
|
|
|
|
report={
|
|
"ts":time.strftime("%Y%m%d_%H%M%S"),
|
|
"version":"2.0",
|
|
"elapsed":elapsed,
|
|
"pass":passed,"fail":failed,"total":total,
|
|
"score":round(passed/total*100,1) if total else 0,
|
|
"js_errors":len(js_errors),
|
|
"screenshots":len([r for r in results if r.get("screenshot")]),
|
|
"categories":{},
|
|
"results":results,
|
|
"failures":[r for r in results if r["status"]=="fail"]
|
|
}
|
|
for r in results:
|
|
cat=r["cat"]
|
|
if cat not in report["categories"]:report["categories"][cat]={"pass":0,"fail":0}
|
|
report["categories"][cat][r["status"]]+=1
|
|
|
|
# Save
|
|
with open(f"{RESULTS_DIR}/l99-mega-latest.json","w") as f:json.dump(report,f,indent=2)
|
|
print(json.dumps({"pass":passed,"fail":failed,"total":total,"score":report["score"],"elapsed":elapsed,"js_errors":len(js_errors),"screenshots":report["screenshots"]}))
|