Files
cms-SiteForge/scripts/browser_mobile_v8213.py
T

72 lines
4.6 KiB
Python
Raw Normal View History

"""Offline Chromium check for real four-theme mobile templates without localhost/file navigation.
Uses page.set_content to work in CI sandboxes that block navigation to localhost/file URLs.
Tests actual rendered HTML, CSS, and JS; external image loading is not asserted.
"""
from pathlib import Path
import json,re,sys
from playwright.sync_api import sync_playwright, expect
ROOT=Path(__file__).resolve().parents[1]
SAMPLE=ROOT/'examples'/'mobile-showcase'
def inline(theme,page_name="index.html"):
path=SAMPLE/theme
html=(path/page_name).read_text('utf-8')
css='\n'.join((path/'assets'/name).read_text('utf-8') for name in
['theme.css','blocks.css','factory.css','pro-base.css','pro.css','commercial.css','custom.css'])
html=re.sub(r'<link\b[^>]*rel="stylesheet"[^>]*>', '',html)
html=re.sub(r'<script defer src="assets/[^"<>]+"></script>', '',html)
html=html.replace('</head>','<style>'+css+'</style></head>')
js=(path/'assets/pro.js').read_text('utf-8')
html=html.replace('</body>','<script>'+js+'</script></body>')
return html
def run():
results=[]
with sync_playwright() as pw:
browser=pw.chromium.launch(executable_path='/usr/bin/chromium',headless=True,args=['--no-sandbox','--disable-dev-shm-usage'])
try:
for theme in ['automotive','industrial','corporate','minimal']:
page=browser.new_page(viewport={'width':390,'height':844},device_scale_factor=1)
errors=[]
page.on('pageerror',lambda e:errors.append(str(e)))
page.set_content(inline(theme),wait_until='domcontentloaded')
assert page.locator('.sf-mobile-tabs').is_visible(),theme+' tabs absent'
assert page.locator('[data-mobile-open-menu]').count()==1
assert not page.locator('#pro-navigation').is_visible(),theme+' drawer initially visible'
page.locator('[data-pro-menu]').click()
assert page.locator('#pro-navigation').is_visible(),theme+' drawer not open'
expect(page.locator('.sf-mobile-drawer-backdrop')).to_be_visible(timeout=3000)
assert page.locator('[data-pro-menu]').get_attribute('aria-expanded')=='true'
page.keyboard.press('Escape')
assert not page.locator('#pro-navigation').is_visible(),theme+' Esc fails'
page.locator('[data-mobile-open-menu]').click()
assert page.locator('#pro-navigation').is_visible(),theme+' tabs menu failed'
page.locator('.sf-mobile-drawer-backdrop').click(position={'x':4,'y':100})
assert not page.locator('#pro-navigation').is_visible(),theme+' backdrop close fails'
assert page.locator('.sf-mobile-tabs').evaluate('(el)=>getComputedStyle(el).display')=='grid'
overflow=page.evaluate('document.documentElement.scrollWidth - window.innerWidth')
for filename in ['index.html','listing.html','product.html','article.html']:
for width in (375,390,430):
sub=browser.new_page(viewport={'width':width,'height':844})
sub.set_content(inline(theme,filename),wait_until='domcontentloaded')
assert sub.locator('.sf-mobile-tabs').is_visible(),f'{theme}/{filename}: tabs missing'
excess=sub.evaluate('document.documentElement.scrollWidth - window.innerWidth')
assert excess<=1,f'{theme}/{filename} width={width} overflow={excess}'
sub.close()
page.set_viewport_size({'width':1440,'height':900})
assert not page.locator('.sf-mobile-tabs').is_visible(),theme+' desktop tabs leakage'
assert page.locator('#pro-navigation').is_visible(),theme+' desktop nav hidden'
assert not errors,theme+' script errors: '+str(errors)
results.append({'theme':theme,'drawer':'PASS','tabs':'PASS','responsive':'PASS','mobile_horizontal_overflow_px':overflow,'page_types_tested':4,'javascript_errors':len(errors)})
if theme=='automotive':
page.set_viewport_size({'width':390,'height':844})
page.wait_for_timeout(350);page.screenshot(path=str(ROOT/'reports'/'mobile-v8213-automotive.png'),full_page=True)
page.close()
finally:browser.close()
out=ROOT/'reports'/'mobile-v8213-browser.json';out.parent.mkdir(exist_ok=True,parents=True)
out.write_text(json.dumps(results,ensure_ascii=False,indent=2),encoding='utf-8')
print(json.dumps(results,ensure_ascii=False,indent=2))
return 0
if __name__=='__main__':sys.exit(run())