- Reference docs: known issues, user journey, location redesign, mission merge plan - Scripts: fill_location_state, merge_missions, migrate_location, migrate_state - Tests: e2e test suite, asset entries unit tests - Demo: location board, hifi prototypes, test screenshots - Data backup: asset log entries and state nodes - Update .gitignore Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
141 lines
5.9 KiB
Python
141 lines
5.9 KiB
Python
"""Test the location board demo click functionality using Playwright."""
|
|
import asyncio
|
|
from pathlib import Path
|
|
from playwright.async_api import async_playwright
|
|
|
|
DEMO_PATH = Path(__file__).resolve().parent / "location_board_demo.html"
|
|
FILE_URL = f"file:///{DEMO_PATH.as_posix()}"
|
|
|
|
|
|
async def main():
|
|
async with async_playwright() as p:
|
|
browser = await p.chromium.launch(headless=True)
|
|
page = await browser.new_page(viewport={"width": 1400, "height": 900})
|
|
await page.goto(FILE_URL, wait_until="commit", timeout=10000)
|
|
await page.wait_for_timeout(3000) # let canvas render (skip font loading)
|
|
|
|
# --- Test 1: Check initial state ---
|
|
scope = await page.text_content("#scope-indicator")
|
|
print(f"Test 1 - Initial scope: {scope}")
|
|
|
|
# --- Test 2: Get canvas bounding box and try clicking a planet ---
|
|
canvas = page.locator("#map-canvas")
|
|
box = await canvas.bounding_box()
|
|
if not box:
|
|
print("ERROR: Canvas not found!")
|
|
await browser.close()
|
|
return
|
|
|
|
print(f"Canvas: x={box['x']:.0f} y={box['y']:.0f} w={box['width']:.0f} h={box['height']:.0f}")
|
|
|
|
# The solar system view has the sun at center of canvas
|
|
# Planets orbit around it. Let's log JS state to see where bodies are.
|
|
body_positions = await page.evaluate("""
|
|
() => {
|
|
const result = [];
|
|
const keys = ['sun','mercury','venus','earth','mars','jupiter','saturn','uranus','neptune','pluto'];
|
|
for (const k of keys) {
|
|
const b = BD[k];
|
|
if (b) result.push({
|
|
key: k,
|
|
name: b.n,
|
|
sx: b._x,
|
|
sy: b._y,
|
|
r: b.r,
|
|
hasMoons: (b.moons && typeof b.moons==='object') ? Object.keys(b.moons).join(',') : 'none'
|
|
});
|
|
}
|
|
return result;
|
|
}
|
|
""")
|
|
print("\nBody positions (CSS pixels from canvas top-left):")
|
|
for bp in body_positions:
|
|
sx = bp['sx']
|
|
sy = bp['sy']
|
|
if sx is not None and sy is not None:
|
|
# Convert to page coordinates (add canvas offset)
|
|
px = sx + box['x']
|
|
py = sy + box['y']
|
|
print(f" {bp['name']:12s} screen=({sx:6.1f},{sy:6.1f}) page=({px:6.1f},{py:6.1f}) r={bp['r']} moons={bp['hasMoons']}")
|
|
else:
|
|
print(f" {bp['name']:12s} screen=(undefined) - NOT RENDERED")
|
|
|
|
# --- Test 3: Try clicking Jupiter ---
|
|
jupiter = [b for b in body_positions if b['key'] == 'jupiter']
|
|
if jupiter and jupiter[0]['sx'] is not None:
|
|
jx = jupiter[0]['sx'] + box['x']
|
|
jy = jupiter[0]['sy'] + box['y']
|
|
jr = jupiter[0]['r'] + 5 # hit radius
|
|
print(f"\nTest 3 - Clicking Jupiter at page ({jx:.0f}, {jy:.0f}) r={jr}")
|
|
|
|
# Take pre-click screenshot
|
|
await page.screenshot(path=str(DEMO_PATH.parent / "pre_click.png"))
|
|
print(" Screenshot: pre_click.png")
|
|
|
|
# Click
|
|
await page.mouse.click(jx, jy)
|
|
await page.wait_for_timeout(500)
|
|
|
|
scope_after = await page.text_content("#scope-indicator")
|
|
back_visible = await page.evaluate("() => document.getElementById('back-btn').classList.contains('visible')")
|
|
print(f" After click - scope: {scope_after}")
|
|
print(f" Back button visible: {back_visible}")
|
|
print(f" View stack: {await page.evaluate('() => JSON.stringify(viewStack)')}")
|
|
|
|
await page.screenshot(path=str(DEMO_PATH.parent / "post_click.png"))
|
|
print(" Screenshot: post_click.png")
|
|
else:
|
|
print("\nTest 3 - Jupiter not found in rendered bodies!")
|
|
|
|
# --- Test 4: Check JS console for errors ---
|
|
console_msgs = []
|
|
page.on("console", lambda msg: console_msgs.append(f"[{msg.type}] {msg.text}"))
|
|
# Trigger a re-render
|
|
await page.evaluate("() => { render(); }")
|
|
await page.wait_for_timeout(300)
|
|
errors = [m for m in console_msgs if 'error' in m.lower() or 'Error' in m]
|
|
if errors:
|
|
print(f"\nJS errors: {errors}")
|
|
else:
|
|
print("\nNo JS errors detected")
|
|
|
|
# --- Test 5: Check didDrag state and event flow ---
|
|
print("\n--- Event Debug ---")
|
|
# Inject debug listener
|
|
await page.evaluate("""
|
|
() => {
|
|
const canvas = document.getElementById('map-canvas');
|
|
canvas.addEventListener('click', (e) => {
|
|
console.log('CLICK on canvas at', e.clientX, e.clientY, 'didDrag=', window._didDrag || didDrag);
|
|
}, true); // capture phase
|
|
|
|
// Store for inspection
|
|
window._debugClick = (x, y) => {
|
|
const r = canvas.getBoundingClientRect();
|
|
const t = hitTest(x - r.left, y - r.top);
|
|
console.log('hitTest result:', t, 'didDrag=', didDrag, 'dragOn=', dragOn);
|
|
return t;
|
|
};
|
|
}
|
|
""")
|
|
|
|
# Try click with explicit coordinates
|
|
if jupiter and jupiter[0]['sx'] is not None:
|
|
result = await page.evaluate(f"() => window._debugClick({jx - box['x']}, {jy - box['y']})")
|
|
print(f"hitTest at Jupiter position result: {result}")
|
|
|
|
# Also try clicking center of canvas minus offset
|
|
cx = box['width'] / 2
|
|
cy = box['height'] / 2
|
|
for offset_y in [0, -20, -50, -100, 50, 100]:
|
|
test_x = cx
|
|
test_y = cy + offset_y
|
|
r = await page.evaluate(f"() => window._debugClick({test_x}, {test_y})")
|
|
print(f" hitTest at canvas({test_x:.0f}, {test_y:.0f}): {r}")
|
|
|
|
await browser.close()
|
|
|
|
|
|
if __name__ == "__main__":
|
|
asyncio.run(main())
|