126 lines
5.6 KiB
Python
126 lines
5.6 KiB
Python
#!/usr/bin/env python3
|
|
"""V123 E2E - Test pinning workflow"""
|
|
import asyncio, json, os
|
|
from playwright.async_api import async_playwright
|
|
|
|
OUT = "/var/www/html/api/blade-tasks/v123-pins-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}, record_video_dir=OUT)
|
|
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=v123", wait_until='load', timeout=30000)
|
|
await page.wait_for_timeout(2000)
|
|
await page.click('[data-view="dashboards"]')
|
|
await page.wait_for_timeout(3500)
|
|
|
|
# Initial: no pins, first tile is alphabetical first
|
|
initial = await page.evaluate("""() => {
|
|
const tiles = document.querySelectorAll('#dash-grid a');
|
|
return {
|
|
tile_count: tiles.length,
|
|
first_tile: tiles[0]?.href.split('/').pop(),
|
|
star_buttons: document.querySelectorAll('#dash-grid button[title*="Pin"],#dash-grid button[title*="Unpin"]').length,
|
|
pinned_class: document.querySelectorAll('.dash-tile.pinned').length,
|
|
count_text: document.getElementById('dash-count')?.textContent
|
|
};
|
|
}""")
|
|
print("Initial:", json.dumps(initial, indent=2))
|
|
await page.screenshot(path=f"{OUT}/01-initial.png", full_page=True)
|
|
|
|
# Pin "ethica-dashboard-live.html" via JS (simulate click)
|
|
await page.evaluate("__dashTogglePin('ethica-dashboard-live.html')")
|
|
await page.wait_for_timeout(800)
|
|
|
|
after_pin = await page.evaluate("""() => {
|
|
const tiles = document.querySelectorAll('#dash-grid a');
|
|
return {
|
|
first_tile: tiles[0]?.href.split('/').pop(),
|
|
pinned_count: document.querySelectorAll('.dash-tile.pinned').length,
|
|
count_text: document.getElementById('dash-count')?.textContent,
|
|
url_hash: window.location.hash
|
|
};
|
|
}""")
|
|
print("After pin ethica:", json.dumps(after_pin, indent=2))
|
|
await page.screenshot(path=f"{OUT}/02-pinned-ethica.png", full_page=True)
|
|
|
|
# Pin a second
|
|
await page.evaluate("__dashTogglePin('crm-dashboard-live.html')")
|
|
await page.wait_for_timeout(800)
|
|
|
|
after_pin2 = await page.evaluate("""() => {
|
|
const tiles = document.querySelectorAll('#dash-grid a');
|
|
return {
|
|
first_2: [tiles[0]?.href.split('/').pop(), tiles[1]?.href.split('/').pop()],
|
|
pinned_count: document.querySelectorAll('.dash-tile.pinned').length,
|
|
count_text: document.getElementById('dash-count')?.textContent,
|
|
url_hash: window.location.hash
|
|
};
|
|
}""")
|
|
print("After pin crm:", json.dumps(after_pin2, indent=2))
|
|
await page.screenshot(path=f"{OUT}/03-pinned-two.png", full_page=True)
|
|
|
|
# Reload with hash preserved
|
|
await page.reload(wait_until='load')
|
|
await page.wait_for_timeout(2000)
|
|
await page.click('[data-view="dashboards"]')
|
|
await page.wait_for_timeout(3000)
|
|
|
|
after_reload = await page.evaluate("""() => {
|
|
const tiles = document.querySelectorAll('#dash-grid a');
|
|
return {
|
|
first_2: [tiles[0]?.href.split('/').pop(), tiles[1]?.href.split('/').pop()],
|
|
pinned_count: document.querySelectorAll('.dash-tile.pinned').length,
|
|
url_hash: window.location.hash
|
|
};
|
|
}""")
|
|
print("After reload:", json.dumps(after_reload, indent=2))
|
|
await page.screenshot(path=f"{OUT}/04-after-reload.png", full_page=True)
|
|
|
|
# Unpin one
|
|
await page.evaluate("__dashTogglePin('ethica-dashboard-live.html')")
|
|
await page.wait_for_timeout(800)
|
|
after_unpin = await page.evaluate("""() => ({
|
|
pinned_count: document.querySelectorAll('.dash-tile.pinned').length,
|
|
url_hash: window.location.hash,
|
|
count_text: document.getElementById('dash-count')?.textContent
|
|
})""")
|
|
print("After unpin:", json.dumps(after_unpin, indent=2))
|
|
|
|
await ctx.close()
|
|
await browser.close()
|
|
|
|
verdict = 'WIRED' if (
|
|
initial['star_buttons'] > 60 and
|
|
after_pin['pinned_count'] == 1 and
|
|
after_pin2['pinned_count'] == 2 and
|
|
'pins=' in after_pin['url_hash'] and
|
|
after_reload['pinned_count'] == 2 and # persisted via URL
|
|
after_unpin['pinned_count'] == 1 and
|
|
not errs
|
|
) else 'PARTIAL'
|
|
|
|
report = {
|
|
'v123': 'pinning-url-hash',
|
|
'initial_star_buttons': initial['star_buttons'],
|
|
'first_pin_works': after_pin['pinned_count'] == 1,
|
|
'second_pin_works': after_pin2['pinned_count'] == 2,
|
|
'pinned_go_first': after_pin2['first_2'][0] in ('crm-dashboard-live.html','ethica-dashboard-live.html'),
|
|
'url_hash_persists': 'pins=' in after_pin['url_hash'],
|
|
'reload_preserves': after_reload['pinned_count'] == 2,
|
|
'unpin_works': after_unpin['pinned_count'] == 1,
|
|
'js_errors': errs[:3],
|
|
'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())
|