Files
cms-SiteForge/scripts/studio_canvas_isolated_browser_v822.py
浅念 8884e100f9 upgrade: adopt V8.31.1 (theme 1.3/1.4 redesigns, editor deep-canvas, guided launch, component library)
Overlay 190 upstream items (V8.22→8.31) preserving trade-pro theme,
registry tests, and design docs. Re-applied full patch set on identical
anchors (discovery/env_for/blocks.css/type-mapping/locale-override/
theme_color/frontend entries/test_theme_pro_v3 mods) plus compose pins.

Verified: theme suites 35/35; dual-baseline full run 415 passed vs
pristine 386+29 ours, FAILED-set diff EMPTY (same 10 Windows env fails).
Live: container 8.31.1-dev.1 healthy, hesupipe 192 entries intact,
trade-pro build 203 pages 0 errors.

Co-Authored-By: Claude Code <noreply@anthropic.com>
2026-10-26 09:43:17 +08:00

49 lines
3.5 KiB
Python

"""Chromium-backed canvas interaction smoke without accessing a network endpoint.
Tests the shipped studio-canvas-bridge.js in a real sandboxed srcdoc iframe.
Server-authenticated editor E2E is separately covered by studio_canvas_smoke_v822.py.
"""
from pathlib import Path
from playwright.sync_api import sync_playwright
ROOT=Path(__file__).resolve().parents[1]
BRIDGE=(ROOT/'app/static/studio-canvas-bridge.js').read_text(encoding='utf-8')
DOC='''<!doctype html><html><head><style>
body{margin:0;font-family:Arial}.sf-section{min-height:160px;padding:20px;background:#f7f9fb;margin-bottom:12px}
.sf-layout-grid{display:grid;grid-template-columns:var(--sf-layout-cols);gap:8px}
.sf-layout-column{min-height:200px;background:#eee}
</style></head><body>
<section class="sf-section" data-block="a"><div><h1>First block</h1><p>hello</p></div></section>
<section class="sf-section" data-block="b"><div><h2>Second block</h2><p>description</p></div></section>
<section class="sf-section" data-block="c"><div><h2>Layout</h2><div class="sf-layout-grid" data-layout="c" style="--sf-layout-cols:1fr 1fr"><div class="sf-layout-column"><p>Left</p></div><div class="sf-layout-column"><p>Right</p></div></div></div></section>
</body></html>'''
def run():
# `iframe.srcdoc` is used here just as in the production editor.
with sync_playwright() as playwright:
browser=playwright.chromium.launch(headless=True,executable_path='/usr/bin/chromium',args=['--no-sandbox'])
page=browser.new_page(viewport={'width':1280,'height':950})
page.set_content('<html><body><iframe id="preview" sandbox="allow-scripts" style="width:950px;height:850px"></iframe></body></html>')
page.evaluate('''content=>{window.events=[];window.addEventListener('message',e=>{if(e.source===document.querySelector('iframe').contentWindow)events.push(e.data)});document.querySelector('iframe').srcdoc=content;}''',DOC.replace('</body>','<script>'+BRIDGE+'</script></body>'))
frame=page.frame_locator('#preview')
frame.locator('.sf-canvas-toolbar').first.wait_for(state='attached',timeout=8000)
assert frame.locator('.sf-canvas-toolbar').count()==3
frame.locator('.sf-section[data-block="a"]').click(position={'x':50,'y':80})
assert frame.locator('.sf-section.sf-canvas-selected[data-block="a"]').count()==1
assert page.evaluate('events.some(x=>x.action==="select"&&x.blockId==="a")')
frame.locator('.sf-section[data-block="a"]').hover()
frame.locator('.sf-section[data-block="a"] > .sf-canvas-toolbar [data-action="duplicate"]').click()
assert page.evaluate('events.some(x=>x.action==="duplicate"&&x.blockId==="a")')
frame.locator('.sf-section[data-block="a"]').hover()
frame.locator('.sf-section[data-block="a"] > .sf-canvas-toolbar [data-action="add-after"]').click()
assert page.evaluate('events.some(x=>x.action==="add-after"&&x.blockId==="a")')
frame.locator('.sf-section[data-block="c"]').hover()
assert frame.locator('.sf-canvas-resize').count()==1
# Verify a real keyboard resize message using the same bounds as production.
frame.locator('.sf-canvas-resize').focus()
frame.locator('.sf-canvas-resize').press('ArrowRight')
assert page.evaluate('events.some(x=>x.action==="resize-columns"&&x.blockId==="c"&&x.widths[0]>1)')
assert not page.evaluate('events.some(x=>x.action==="execute")')
print('PASS: Chromium sandbox canvas selected, duplicate, add-after, keyboard column resize / postMessage')
browser.close()
if __name__=='__main__':run()