601451f22b
Overlay ~150 upstream items onto our V8.12 base, preserving trade-pro
theme, registry tests, and design docs. Re-applied our patch set
(discovery/env_for/blocks.css/type-mapping/theme_color/frontend entries,
test_theme_pro_v3 mods) — all anchors survived upstream evolution.
New platform enhancement (fixes upgrade-introduced regression):
multilingual.site_locale now honors settings_json.locale, plus
PUT /api/i18n/sites/{id}/locale — standalone English sites get
<html lang='en'> under the V8.15 locale-rewrite pipeline.
compose: adopt V8.21.3 (image 8.21.3-dev.1, /api/ready probes, MySQL/S3
env) with project name pinned to siteforge-v8-10 (data volumes).
Tests: 356 passed / 11 failed — all 11 confirmed pre-existing in
pristine V8.21.3 on this host (10 upstream Windows env + our build test
now green after locale fix). Patch registry updated in plan doc.
Co-Authored-By: Claude Code <noreply@anthropic.com>
72 lines
4.6 KiB
Python
72 lines
4.6 KiB
Python
"""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())
|