starmap / scripts /browser_check.py
Agent Manager
Show terrain skyline and observing-location local time
5167728
Raw History Blame Contribute Delete
8.32 kB
import re
"""Functional smoke checks and screenshots against a running Sidereal server."""
import json
import os
from pathlib import Path
from playwright.sync_api import sync_playwright, expect
base = os.environ.get('SIDEREAL_TEST_URL', 'http://127.0.0.1:5173')
out = Path('test-results')
out.mkdir(exist_ok=True)
errors = []
with sync_playwright() as p:
installs = list(Path(os.environ.get('PLAYWRIGHT_BROWSERS_PATH', '/opt/playwright')).glob('chromium-*/chrome-linux*/chrome'))
browser = p.chromium.launch(headless=True, executable_path=str(installs[0]) if installs else None, args=['--no-sandbox'])
context = browser.new_context(viewport={'width': 1600, 'height': 1000}, device_scale_factor=1,
geolocation={'latitude': 47.3769, 'longitude': 8.5417}, permissions=['geolocation'])
page = context.new_page()
page.on('pageerror', lambda e: errors.append(str(e)))
page.goto(base, wait_until='networkidle')
expect(page.locator('canvas').first).to_be_visible()
page.get_by_role('button', name='Pause time', exact=True).click()
page.get_by_label(re.compile('Observing date and time in')).fill('2026-09-05T22:00')
def search(name):
page.get_by_label('Search sky objects').fill(name)
page.get_by_label('Search sky objects').press('Enter')
search('Vega')
expect(page.locator('.object-heading h2')).to_have_text('Vega')
expect(page.locator('.object-stats')).to_contain_text('25 ly')
page.get_by_role('button', name='CENTRE IN SKY VIEW', exact=True).click()
box = page.locator('.sky-canvas').bounding_box()
cx,cy = box['x']+box['width']/2, box['y']+box['height']/2
page.mouse.move(cx,cy)
expect(page.get_by_role('tooltip')).to_contain_text('Vega')
# An off-centre object must stay under the pointer through scroll zoom.
page.mouse.down(); page.mouse.move(cx+65,cy-42,steps=10); page.mouse.up()
page.wait_for_timeout(150)
page.mouse.move(cx+66,cy-42)
expect(page.get_by_role('tooltip')).to_contain_text('Vega')
page.mouse.wheel(0,-320)
page.wait_for_timeout(350)
page.mouse.move(cx+65,cy-42)
expect(page.get_by_role('tooltip')).to_contain_text('Vega')
page.mouse.wheel(0,320)
page.wait_for_timeout(350)
page.mouse.move(cx+66,cy-42)
expect(page.get_by_role('tooltip')).to_contain_text('Vega')
page.mouse.move(10,10)
page.screenshot(path=str(out/'desktop.png'), full_page=True)
search('M31')
expect(page.locator('.object-heading')).to_contain_text('GALAXY')
expect(page.locator('.right-rail')).to_contain_text('BEYOND OUR GALAXY')
search('Saturn')
expect(page.locator('.right-rail')).to_contain_text('THE SOLAR SYSTEM')
expect(page.get_by_role('button',name='ALL PLANETS',exact=True)).to_have_class('active')
expect(page.locator('.solar-distance')).to_contain_text('AU')
page.screenshot(path=str(out/'planet.png'), full_page=True)
search('Mars')
expect(page.get_by_role('button',name='INNER PLANETS',exact=True)).to_have_class('active')
expect(page.locator('[data-planet-position]')).to_have_count(4)
page.screenshot(path=str(out/'inner-planets.png'), full_page=True)
page.get_by_role('button',name='ALL PLANETS',exact=True).click()
expect(page.locator('[data-planet-position]')).to_have_count(8)
search('ISS')
expect(page.locator('.right-rail')).to_contain_text('EARTH / GROUND TRACK')
expect(page.locator('.object-stats')).to_contain_text('Space station')
expect(page.locator('.object-stats')).to_contain_text('1998-11-20')
page.screenshot(path=str(out/'satellite.png'), full_page=True)
for target,label in [('HST','Space telescope'),('sat733','Rocket body'),('SPACEMOBILE-001','Communications satellite')]:
search(target)
expect(page.locator('.object-stats')).to_contain_text(label)
page.screenshot(path=str(out/'communications-satellite.png'), full_page=True)
page.get_by_role('button',name='ALL SKY',exact=True).click()
expect(page.locator('.map-readout')).to_contain_text('180°')
page.get_by_role('button',name='Zoom in',exact=True).click()
expect(page.locator('.map-readout')).to_contain_text('90°')
page.get_by_role('button',name='OFF',exact=True).count() # highlights start on
page.get_by_role('button',name='ON',exact=True).click()
expect(page.get_by_role('button',name='OFF',exact=True)).to_have_attribute('aria-pressed','false')
page.get_by_role('button',name='OFF',exact=True).click()
page.get_by_label('Highlight limit').fill('100')
expect(page.locator('.range-heading')).to_contain_text('100')
page.get_by_label('Highlight limit').fill('30')
stars = page.locator('.layer-row').filter(has_text='Stars').get_by_role('checkbox')
stars.uncheck(); expect(stars).not_to_be_checked(); stars.check()
search('Vega')
page.get_by_role('button',name='CENTRE IN SKY VIEW',exact=True).click()
page.get_by_role('button',name='CONNECT SIMULATOR',exact=False).click()
expect(page.locator('.sim-label')).to_have_text('SIMULATING TRACKING')
page.get_by_label('Field of view preset').select_option('wide')
box = page.locator('.sky-canvas').bounding_box()
cx,cy = box['x']+box['width']/2,box['y']+box['height']/2
page.mouse.move(cx,cy); page.mouse.down(); page.mouse.move(cx+75,cy+20,steps=10); page.mouse.up()
expect(page.locator('.sim-label')).to_have_text('SIMULATING SLEW')
before=page.locator('.scope-strip strong').inner_text()
page.wait_for_timeout(1200)
assert page.locator('.scope-strip strong').inner_text()!=before, 'Simulated mount coordinates did not move'
page.screenshot(path=str(out/'slewing.png'),full_page=True)
page.get_by_role('button',name='STOP',exact=False).click()
expect(page.locator('.sim-label')).to_have_text('SIMULATOR STOPPED')
page.get_by_label('Field of view preset').select_option('camera')
expect(page.get_by_label('Field width in degrees')).to_have_value('0.321')
page.get_by_role('button',name='ZOOM TO FIELD',exact=False).click()
expect(page.locator('.map-readout')).to_contain_text('FIELD 1.60°')
page.screenshot(path=str(out/'field.png'),full_page=True)
page.locator('.location-top').click()
page.get_by_label('Choose a location').select_option(label='Sydney')
page.get_by_role('button',name='UPDATE SKY',exact=False).click()
expect(page.locator('.location-top')).to_contain_text('SYDNEY')
page.locator('.location-top').click()
page.get_by_label('Latitude',exact=True).focus()
page.keyboard.press('Escape')
expect(page.get_by_role('dialog')).to_have_count(0)
page.get_by_role('button',name='LOCATE ME',exact=False).click()
expect(page.locator('.location-top')).to_contain_text('CURRENT LOCATION')
expect(page.locator('.location-top')).to_contain_text('47.377')
page.get_by_role('button',name='ABOUT / DATA & CONTROLS',exact=False).click()
expect(page.get_by_role('dialog')).to_be_visible()
page.get_by_role('button',name='Close about',exact=True).click()
assert page.evaluate('document.documentElement.scrollWidth')==1600
page.set_viewport_size({'width':390,'height':844})
page.get_by_role('button',name='Reset sky view',exact=True).click()
page.screenshot(path=str(out/'mobile-sky.png'),full_page=True)
assert page.evaluate('document.documentElement.scrollWidth')==390, 'Mobile page overflows'
page.get_by_role('button',name='CONTROLS',exact=True).click()
expect(page.locator('.left-rail')).to_be_visible()
page.screenshot(path=str(out/'mobile-controls.png'),full_page=True)
page.get_by_role('button',name='OBJECT',exact=True).click()
expect(page.locator('.right-rail')).to_be_visible()
page.screenshot(path=str(out/'mobile-object.png'),full_page=True)
page.get_by_role('button',name='SKY',exact=True).click()
page.get_by_label(re.compile('Observing date and time in')).fill('2025-01-01T22:00')
page.get_by_role('button',name='CONTROLS',exact=True).click()
expect(page.locator('.left-rail')).to_contain_text('Satellite predictions unavailable')
browser.close()
print(json.dumps({'browser_errors':errors,'checks':'location, time, search, hover, all contexts, layers, zoom, draggable field, slew, stop, camera, mobile','screenshots':len(list(out.glob('*.png')))}))
assert not errors