Files
weval-l99/v95_full_authed_e2e.py
2026-04-24 04:38:58 +02:00

178 lines
8.6 KiB
Python

#!/usr/bin/env python3
"""V95 - Full E2E authed scenario business - ZERO MANUAL
DOCTRINE #100 pattern: persistent browser context + session injected
"""
import asyncio, json, os, urllib.request, http.cookiejar
from playwright.async_api import async_playwright
SESSION_DIR = "/opt/weval-l99/browser-sessions/weval"
OUTPUT_DIR = "/var/www/html/api/blade-tasks/v95-full-authed"
os.makedirs(OUTPUT_DIR + "/videos", exist_ok=True)
os.makedirs(OUTPUT_DIR + "/screenshots", exist_ok=True)
PAGES = [
{"name": "01-weval-technology-platform", "url": "https://weval-consulting.com/weval-technology-platform.html", "wait": 4000},
{"name": "02-enterprise-model-V93", "url": "https://weval-consulting.com/enterprise-model.html", "wait": 8000},
{"name": "03-wevia-em-big4", "url": "https://weval-consulting.com/wevia-em-big4.html", "wait": 6000},
{"name": "04-agents-archi", "url": "https://weval-consulting.com/agents-archi.html", "wait": 6000},
{"name": "05-value-streaming", "url": "https://weval-consulting.com/value-streaming.html", "wait": 5000},
{"name": "06-wevia-master", "url": "https://weval-consulting.com/wevia-master.html", "wait": 4000},
{"name": "07-business-kpi-dashboard", "url": "https://weval-consulting.com/business-kpi-dashboard.php", "wait": 4000},
]
async def main():
# Fresh session - get PHPSESSID from response JSON
req = urllib.request.Request(
"http://127.0.0.1/api/opus-test-session-v94.php?k=WEVADS2026",
headers={"Host": "weval-consulting.com"}
)
try:
resp_data = urllib.request.urlopen(req, timeout=5).read().decode()
print(f"DEBUG resp_data: {resp_data!r}")
resp_json = json.loads(resp_data)
session_id = resp_json.get("session_id")
except Exception as e:
print(f"DEBUG exception: {e}")
session_id = None
print(f"Fresh session: {session_id}")
if not session_id or not isinstance(session_id, str):
print(f"ABORT: no valid session_id (got {type(session_id).__name__})")
return
async with async_playwright() as p:
# Launch NEW context with video (persistent doesn't support video directly)
browser = await p.chromium.launch(headless=True, args=['--no-sandbox', '--disable-setuid-sandbox'])
context = await browser.new_context(
viewport={'width': 1920, 'height': 1080},
record_video_dir=OUTPUT_DIR + "/videos",
record_video_size={'width': 1920, 'height': 1080}
)
await context.add_cookies([{
"name": "PHPSESSID",
"value": session_id,
"domain": ".weval-consulting.com",
"path": "/",
"secure": True,
"httpOnly": True,
"sameSite": "Lax"
}])
await context.add_init_script("try { localStorage.setItem('weval_internal', 'yacine-2026'); } catch(e){}")
page = await context.new_page()
errs = []
page.on("pageerror", lambda e: errs.append(f"[{page.url}] {str(e)[:200]}"))
page.on("console", lambda m: errs.append(f"[{page.url}] console.{m.type}: {m.text[:150]}") if m.type == "error" else None)
results = []
for p_info in PAGES:
start = asyncio.get_event_loop().time()
page_errs = []
try:
await page.goto(p_info['url'], wait_until='load', timeout=30000)
await page.wait_for_timeout(p_info['wait'])
diag = await page.evaluate("""() => {
const canvases = document.querySelectorAll('canvas');
const svgs = document.querySelectorAll('svg');
const allEls = document.querySelectorAll('canvas, svg, .node, .card, .agent, [class*="agent-"], [class*="node-"], circle, rect');
// Overlap detection
let overlap = 0;
const rects = [];
for (let i = 0; i < Math.min(allEls.length, 150); i++) {
const r = allEls[i].getBoundingClientRect();
if (r.width > 5 && r.height > 5) rects.push(r);
}
for (let i = 0; i < rects.length; i++) {
for (let j = i+1; j < rects.length; j++) {
const r1 = rects[i], r2 = rects[j];
const ox = Math.max(0, Math.min(r1.right, r2.right) - Math.max(r1.left, r2.left));
const oy = Math.max(0, Math.min(r1.bottom, r2.bottom) - Math.max(r1.top, r2.top));
const overlapArea = ox * oy;
const smallerArea = Math.min(r1.width*r1.height, r2.width*r2.height);
if (smallerArea > 0 && overlapArea / smallerArea > 0.7) overlap++;
}
}
// Count empty or anonymous
const anonymous = Array.from(document.querySelectorAll('[title]')).filter(el => {
const t = (el.getAttribute('title') || '').trim();
return !t || t === 'null' || t === 'undefined' || t === 'Sync';
}).length;
const emptyBlocks = Array.from(document.querySelectorAll('.agent, .node, .card, [class*="agent-"]')).filter(el => {
return !el.textContent.trim() || el.textContent.trim().length < 3;
}).length;
return {
final_url: location.href,
title: document.title,
is_login: location.href.includes('/login'),
body_len: document.body.innerText.length,
canvas: canvases.length,
svg: svgs.length,
img: document.querySelectorAll('img').length,
all_visual_els: allEls.length,
overlapping_pairs: overlap,
anonymous_elements: anonymous,
empty_blocks: emptyBlocks,
AG_length: typeof AG !== 'undefined' ? AG.length : -1,
DP_length: typeof DP !== 'undefined' ? DP.length : -1,
AG_dead: typeof AG !== 'undefined' ? AG.filter(a => a && a.rm === 'dead').length : -1
};
}""")
await page.screenshot(path=f"{OUTPUT_DIR}/screenshots/{p_info['name']}.png", full_page=True)
results.append({
"name": p_info['name'],
"url": p_info['url'],
"ok": not diag['is_login'],
"diag": diag,
"duration_ms": int((asyncio.get_event_loop().time() - start) * 1000)
})
except Exception as e:
results.append({"name": p_info['name'], "url": p_info['url'], "err": str(e)[:200]})
await context.close()
await browser.close()
# Final report
report = {
"ts": "2026-04-20T16:00:00Z",
"total": len(PAGES),
"ok_authenticated": sum(1 for r in results if r.get('ok')),
"still_login": sum(1 for r in results if r.get('diag', {}).get('is_login')),
"errored": sum(1 for r in results if r.get('err')),
"results": results,
"js_errors": errs[:30]
}
with open("/var/www/html/api/playwright-v95-full-authed-scenario.json", "w") as f:
json.dump(report, f, indent=2)
print(json.dumps({
"total": report['total'],
"ok_authenticated": report['ok_authenticated'],
"still_login": report['still_login'],
"errored": report['errored'],
"per_page": [{
"name": r['name'],
"ok": r.get('ok'),
"canvas": r.get('diag', {}).get('canvas', 0),
"svg": r.get('diag', {}).get('svg', 0),
"body": r.get('diag', {}).get('body_len', 0),
"overlap": r.get('diag', {}).get('overlapping_pairs', 0),
"empty_blocks": r.get('diag', {}).get('empty_blocks', 0),
"anonymous": r.get('diag', {}).get('anonymous_elements', 0),
"AG": r.get('diag', {}).get('AG_length', -1),
"AG_dead": r.get('diag', {}).get('AG_dead', -1),
"DP": r.get('diag', {}).get('DP_length', -1)
} for r in results]
}, indent=2))
asyncio.run(main())