File size: 7,037 Bytes
f4c6961
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
import asyncio, pathlib, json
from playwright.async_api import async_playwright
ROOT=pathlib.Path(__file__).parent
OUT=pathlib.Path('/mnt/data')
async def main():
 async with async_playwright() as p:
  browser=await p.chromium.launch(headless=True,executable_path='/usr/bin/chromium',args=['--no-sandbox'])
  page=await browser.new_page(viewport={'width':1512,'height':1000},accept_downloads=True)
  errors=[];page.on('pageerror',lambda e:errors.append(str(e)))
  await page.set_content((ROOT/'index.html').read_text(),wait_until='domcontentloaded')
  await page.add_style_tag(content=(ROOT/'styles.css').read_text())
  for fn in ('source_modelops_engine.js','robustness_engine.js'):
   await page.add_script_tag(content=(ROOT/fn).read_text())
  blobs={n:(ROOT/n).read_text() for n in ('robustness_snapshots.json','benchmark_manifest.json','train.json')}
  await page.evaluate('''(blobs)=>{const old=window.fetch;window.fetch=async (url)=>{if(Object.prototype.hasOwnProperty.call(blobs,String(url)))return {ok:true,json:async()=>JSON.parse(blobs[String(url)])};return old(url);}}''',blobs)
  await page.add_script_tag(content=(ROOT/'app.js').read_text())
  await page.wait_for_function("document.querySelector('#status').textContent==='SNAPSHOT VERIFIED'",timeout=30000)
  checks=[]
  async def ck(name,condition):
   if not condition:raise AssertionError(name+' | browser errors: '+repr(errors))
   checks.append(name);print('PASS',name)
  await ck('hero displays robustness studio','Robustness' in await page.locator('h1').inner_text())
  await ck('4416 records loaded', '4,416' in await page.locator('#snapN').inner_text())
  await ck('eight navigation modules',await page.locator('.nav-btn').count()==8)
  await ck('overview original hybrid baseline 77.8%', '77.8%' in await page.locator('#panel').inner_text())
  await ck('change coverage display', '54 total' in await page.locator('#panel').inner_text())
  await page.locator('#methodSelect').select_option('nb')
  await ck('NB method changes score', '74.1%' in await page.locator('#panel').inner_text())
  await page.locator('#splitSelect').select_option('iid')
  await ck('IID split shows 130 rows', '130 total' in await page.locator('#panel').inner_text())
  await page.locator('#attackSelect').select_option('truncate')
  await ck('destructive edit never scored', 'Not scored' in await page.locator('#panel').inner_text())
  await page.locator('#attackSelect').select_option('synonym')
  await ck('sparse synonym changes show matched coverage', 'Changed inputs' in await page.locator('#panel').inner_text())
  await page.locator('#splitSelect').select_option('challenge')
  await page.locator('#attackSelect').select_option('context')
  await page.locator('[data-view=matrix]').click()
  await ck('stress matrix renders six test conditions', await page.locator('#panel tbody tr').first.count()==1 and 'Information removal' in await page.locator('#panel').inner_text())
  await ck('all model comparisons render', 'Character TF-IDF' in await page.locator('#panel').inner_text())
  await page.locator('[data-view=cases]').click()
  await ck('paired example view', 'Evidence trail' in await page.locator('#panel').inner_text())
  await page.locator('#caseFilter').select_option('flips')
  await ck('flip filter matches changed predictions', await page.locator('.case').count()>0 and await page.locator('.case').count()<=12)
  await page.locator('#caseSearch').fill('ari-')
  await ck('paired search is usable',await page.locator('.case').count()>0)
  await page.locator('[data-view=selective]').click()
  await ck('risk curve renders',await page.locator('.svg-chart').count()==1)
  await page.locator('#coverageRange').fill('50')
  await ck('coverage slider changes sample count', '50%' in await page.locator('#panel').inner_text())
  await page.locator('[data-view=reliability]').click()
  await ck('NB confidence reliability bins render',await page.locator('#panel tbody tr').count()==8)
  await ck('uncalibrated warning displayed', 'uncalibrated' in (await page.locator('#panel').inner_text()).lower())
  await page.locator('[data-view=slices]').click()
  await page.locator('#sliceBy').select_option('domain')
  await ck('domain slice filter', 'Research domain' in await page.locator('#panel').inner_text() or 'Subgroup' in await page.locator('#panel').inner_text())
  await page.locator('[data-view=gates]').click()
  await ck('gate dashboard visible', 'Research gates' in await page.locator('#viewId').inner_text() or 'RESEARCH GATES' in await page.locator('#viewId').inner_text())
  await page.locator('#gateFlip').fill('100')
  await page.locator('#gateDrop').fill('100')
  await page.locator('#gateMin').fill('1')
  await page.locator('#applyGates').click()
  await ck('relaxed gates pass', 'CHECKS PASS' in await page.locator('#panel').inner_text())
  await page.locator('#resetGates').click()
  await ck('gate reset restores strict thresholds','15%' in await page.locator('#panel').inner_text())
  await page.locator('[data-view=sandbox]').click()
  await ck('sandbox has input text',await page.locator('#sandboxText').count()==1)
  await page.locator('#sandboxLang').select_option('es')
  await page.locator('#sandboxExample').click()
  await ck('Spanish example button', 'Los resultados' in await page.locator('#sandboxText').input_value())
  await page.locator('#sandboxRun').click()
  await ck('local prediction creates trace', 'TRANSFORMED' in await page.locator('#panel').inner_text())
  for kind,extension in [('report','.md'),('table','.csv'),('session','.json'),('predictions','.csv')]:
   async with page.expect_download() as info: await page.locator(f'[data-export="{kind}"]').click()
   download=await info.value
   await ck('download '+kind,download.suggested_filename.endswith(extension))
  async with page.expect_download() as info: await page.locator('#exportSummary').click()
  dl=await info.value
  await ck('global research report download', dl.suggested_filename.endswith('.md'))
  await page.locator('[data-view=overview]').click()
  await page.locator('#methodSelect').select_option('hybrid')
  await page.locator('#splitSelect').select_option('challenge')
  await page.locator('#attackSelect').select_option('typo')
  await page.evaluate('window.scrollTo(0,0)')
  await page.screenshot(path=str(OUT/'RobustnessLab_AI_DESKTOP_PREVIEW.png'),full_page=True)
  await ck('desktop no sideways scroll', await page.evaluate('document.documentElement.scrollWidth <= window.innerWidth+3'))
  await page.set_viewport_size({'width':390,'height':844})
  await page.evaluate('window.scrollTo(0,0)')
  await page.screenshot(path=str(OUT/'RobustnessLab_AI_MOBILE_PREVIEW.png'),full_page=True)
  await ck('mobile no sideways scroll', await page.evaluate('document.documentElement.scrollWidth <= window.innerWidth+3'))
  await ck('mobile navigation accessible',await page.locator('[data-view=matrix]').is_visible())
  await ck('no browser JavaScript errors',not errors)
  print('TOTAL BROWSER CHECKS',len(checks),'PASS')
  await browser.close()
asyncio.run(main())