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

110 lines
4.6 KiB
Python

#!/usr/bin/env python3
"""V137 E2E - Refresh button + age indicator work"""
import asyncio, json, os
from playwright.async_api import async_playwright
OUT = "/var/www/html/api/blade-tasks/v137-refresh-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'])
ctx = await browser.new_context(viewport={'width':1920,'height':1080})
page = await ctx.new_page()
errs = []
page.on('pageerror', lambda e: errs.append(str(e)))
await page.goto("https://weval-consulting.com/all-ia-hub.html?v=v137", wait_until='load', timeout=30000)
await page.wait_for_timeout(3500) # wait for initial fetch
initial = await page.evaluate("""() => {
const btn = document.getElementById('v137-refresh-btn');
const kpi = document.getElementById('v135-kpi-live');
return {
btn_exists: !!btn,
btn_title: btn?.title,
btn_disabled: btn?.disabled,
kpi_innerHTML: kpi?.innerHTML,
kpi_title_has_scan: kpi?.title?.includes('Scan:'),
kpi_has_ago: kpi?.innerHTML?.includes('ago') || kpi?.innerHTML?.includes('just now')
};
}""")
print("Initial:", json.dumps(initial, indent=2))
# Click refresh btn
await page.click('#v137-refresh-btn')
await page.wait_for_timeout(300)
during = await page.evaluate("""() => {
const btn = document.getElementById('v137-refresh-btn');
return {
animation: btn?.style.animation,
disabled: btn?.disabled
};
}""")
print("During refresh:", json.dumps(during))
await page.wait_for_timeout(1500) # wait for completion
after = await page.evaluate("""() => {
const btn = document.getElementById('v137-refresh-btn');
const kpi = document.getElementById('v135-kpi-live');
return {
btn_disabled: btn?.disabled,
animation: btn?.style.animation,
kpi_still_valid: !!kpi?.innerHTML?.includes('%')
};
}""")
print("After refresh:", json.dumps(after))
# Verify click banner still opens modal (backward compat V136)
await page.click('#v135-kpi-live')
await page.wait_for_timeout(1200)
modal_state = await page.evaluate("() => document.getElementById('v136-health-modal')?.style.display")
print("Modal after banner click:", modal_state)
await page.keyboard.press('Escape')
await page.wait_for_timeout(500)
# Click refresh btn while modal closed should NOT open modal (stopPropagation test)
await page.click('#v137-refresh-btn')
await page.wait_for_timeout(300)
modal_state2 = await page.evaluate("() => document.getElementById('v136-health-modal')?.style.display")
print("Modal after refresh click (should be none):", modal_state2)
await ctx.close()
await browser.close()
verdict = 'OK' if (
initial['btn_exists'] and
initial['kpi_title_has_scan'] and
initial['kpi_has_ago'] and
not initial['btn_disabled'] and
'v137spin' in (during['animation'] or '') and
during['disabled'] and
not after['btn_disabled'] and
after['kpi_still_valid'] and
modal_state == 'flex' and # banner click opens modal
modal_state2 in (None, 'none') and # refresh click does NOT open modal
not errs
) else 'PARTIAL'
report = {
'v137': 'refresh-button-age-indicator',
'btn_exists': initial['btn_exists'],
'age_indicator_in_banner': initial['kpi_has_ago'],
'scan_info_in_tooltip': initial['kpi_title_has_scan'],
'spin_animation_active': 'v137spin' in (during['animation'] or ''),
'btn_disabled_during': during['disabled'],
'btn_reenabled_after': not after['btn_disabled'],
'banner_click_still_opens_modal': modal_state == 'flex',
'refresh_click_stopPropagation_works': modal_state2 in (None, 'none'),
'js_errors': errs,
'VERDICT': verdict
}
with open(f"{OUT}/proof.json",'w') as f: json.dump(report, f, indent=2)
print("=== VERDICT:", verdict)
print(json.dumps(report, indent=2))
asyncio.run(main())