browser_check.py

back to table · edit · history · where entries came from · files · download

4520 bytes, as of the version from 2026-11-11 08:15 (current). Recorded here, not run.

"""Render authenticated live HTML with public assets, without sending credentials to a browser.
PYTHONPATH=<shared browser dependencies> python browser_check.py
TMPDIR contains page.html and stored-document.json captured from NumberDB.
"""
import os,json,pathlib,re,hashlib,platform,importlib.metadata
from playwright.sync_api import sync_playwright
P=pathlib.Path(os.environ['TMPDIR']);doc=json.loads((P/'stored-document.json').read_text())
with sync_playwright() as pw:
 browser=pw.chromium.launch(headless=True,args=['--no-sandbox','--disable-dev-shm-usage','--disable-gpu'])
 page=browser.new_page(viewport={'width':1440,'height':1050});errors=[]
 page.on('pageerror',lambda e:errors.append(str(e)))
 page.route('https://numberdb.org/T714',lambda route:route.fulfill(status=200,content_type='text/html',body=(P/'page.html').read_text()))
 page.goto('https://numberdb.org/T714',wait_until='domcontentloaded')
 page.wait_for_function('typeof MathJax !== "undefined" && !!MathJax.typesetPromise',timeout=30000)
 page.evaluate('MathJax.typesetPromise()')
 page.locator('details.prose-more').evaluate_all('(els)=>els.forEach(e=>e.open=true)')
 body=page.locator('body').inner_text();(P/'rendered-text.txt').write_text(body)
 nums=[v if isinstance(v,str) else v['number'] for ns in doc['Numbers'].values() for xs in ns.values() for v in xs.values()]
 out={'method':'Authenticated live HTML replayed at its original URL with public assets fetched without credentials','html_sha256':hashlib.sha256((P/'page.html').read_bytes()).hexdigest(),'decimal_count':sum(s in body for s in nums),'page_errors':errors,'math_errors':page.locator('mjx-merror,[data-mml-node=merror]').all_text_contents(),'python':platform.python_version(),'playwright':importlib.metadata.version('playwright'),'chromium':browser.version}
 links=page.locator('a').evaluate_all('(els)=>els.map(e=>({text:e.innerText,href:e.href}))')
 out['missing_fragment_targets']=[a['href'] for a in links if a['href'].startswith('https://numberdb.org/T714#') and page.locator('[id="'+a['href'].split('#',1)[1]+'"]').count()==0]
 heading=page.get_by_text('Similar tables',exact=True);assert heading.count()==1
 section=heading.locator('xpath=following-sibling::div[1]');out['similar_text']=section.inner_text();out['similar_links']=section.locator('a.HREF').evaluate_all('(els)=>els.map(e=>({text:e.innerText,href:e.href}))')
 authenticated={x['url']:x for x in json.loads((P/'companion-link-check.json').read_text())}
 for link in out['similar_links']:
  response=page.request.get(link['href']);link['target_http_status']=response.status
  link['authenticated_target']=authenticated[link['href']]
  link['accessible_in_authorized_context']=response.status==200 or (link['href']=='https://numberdb.org/T713' and response.status==404 and authenticated[link['href']]['status']=='offered_for_review' and authenticated[link['href']]['authenticated_page_bytes']>1000)
 assert {l['href'] for l in out['similar_links']}=={'https://numberdb.org/'+t for t in ['T713','T699','T353','T176']}
 section.screenshot(path=str(P/'similar-tables.png'))
 page.screenshot(path=str(P/'rendered-full.png'),full_page=True)
 page.screenshot(path=str(P/'rendered-top.png'))
 for name in ['Definition','Formulas','Data properties','References']:
  h=page.get_by_text(name,exact=True)
  if h.count()==1:
   h.scroll_into_view_if_needed();page.screenshot(path=str(P/('rendered-'+name.lower().replace(' ','-')+'.png')))
 def texts(x):
  if isinstance(x,str):yield x
  elif isinstance(x,dict):
   for v in x.values():yield from texts(v)
  elif isinstance(x,list):
   for v in x:yield from texts(v)
 formulas=[f for t in texts(doc) for f in re.findall(r'\$([^$]+)\$',t)]
 out['all_math']=page.evaluate('''async fs => {let es=[];for (const f of fs){try {let n=await MathJax.tex2svgPromise(f);if(n.querySelector('mjx-merror,[data-mml-node=merror]'))es.push(f);}catch(e){es.push(f);}} return {count:fs.length,errors:es};}''',formulas)
 out['invalid_tex_rejected']=page.evaluate('''async () => {let n=await MathJax.tex2svgPromise('\\\\frac{1}{');return !!n.querySelector('mjx-merror,[data-mml-node=merror]');}''')
 (P/'browser-results.json').write_text(json.dumps(out,indent=2));print(json.dumps(out,indent=2))
 assert out['decimal_count']==44 and not out['math_errors'] and not out['page_errors'] and not out['missing_fragment_targets']
 assert not out['all_math']['errors'] and out['invalid_tex_rejected']
 assert all(l['accessible_in_authorized_context'] for l in out['similar_links'])
 browser.close()