#!/usr/bin/env python3 """V111 E2E proof - fixed querySelector""" import asyncio, json, os from playwright.async_api import async_playwright OUT = "/var/www/html/api/blade-tasks/v111-blade-actions-proof" os.makedirs(OUT, exist_ok=True) async def main(): async with async_playwright() as p: browser = await p.chromium.launch(headless=True, args=['--no-sandbox']) context = await browser.new_context( viewport={'width':1920,'height':1080}, record_video_dir=OUT ) page = await context.new_page() await page.goto("https://weval-consulting.com/all-ia-hub.html?v=v111b", wait_until='load', timeout=30000) await page.wait_for_timeout(2000) await page.click('[data-view="capabilities"]') await page.wait_for_timeout(4000) blade_check = await page.evaluate("""() => { const caps = Array.from(document.querySelectorAll('.cap h3')); const hasBlade = caps.some(h => h.textContent.indexOf('Blade Tasks') >= 0); const pending = document.getElementById('blade-pending'); const done = document.getElementById('blade-done'); const btns = Array.from(document.querySelectorAll('[onclick*=\"pushBladeTask\"]')); return { has_blade_card: hasBlade, blade_pending: pending ? pending.textContent : null, blade_done: done ? done.textContent : null, buttons_count: btns.length, buttons_labels: btns.map(b => b.textContent.trim()) }; }""") print("Blade section:", json.dumps(blade_check, indent=2)) await page.screenshot(path=f"{OUT}/b1-blade-card.png", full_page=True) # Click Office Create office_btn = await page.query_selector('button[onclick*="office_create"]') if office_btn: await office_btn.click() await page.wait_for_timeout(3500) log1 = await page.evaluate("""() => { const log = document.getElementById('blade-log'); return { visible: log && log.style.display !== 'none', text: log ? log.textContent.trim() : '' }; }""") print("\nAfter Office Create:", json.dumps(log1, indent=2)) await page.screenshot(path=f"{OUT}/b2-office.png", full_page=True) # Click DeepSeek ds_btn = await page.query_selector('button[onclick*="deepseek_renew"]') if ds_btn: await ds_btn.click() await page.wait_for_timeout(3500) log2 = await page.evaluate("""() => { const log = document.getElementById('blade-log'); return {text: log ? log.textContent.trim() : ''}; }""") print("\nAfter DeepSeek Renew:", json.dumps(log2, indent=2)) await page.screenshot(path=f"{OUT}/b3-deepseek.png", full_page=True) await context.close() await browser.close() tasks_ok = 'Task created' in log1.get('text','') and 'Task created' in log2.get('text','') report = { 'v111': 'blade-task-push-from-hub-E2E', 'blade_card_present': blade_check['has_blade_card'], 'buttons_count': blade_check['buttons_count'], 'office_create_ok': 'Task created' in log1.get('text',''), 'deepseek_renew_ok': 'Task created' in log2.get('text',''), 'VERDICT': 'WIRED' if tasks_ok else 'PARTIAL' } with open(f"{OUT}/proof.json",'w') as f: json.dump(report, f, indent=2) print("\n=== VERDICT:", report['VERDICT']) print(json.dumps(report, indent=2)) asyncio.run(main())