Files
cms-SiteForge/tests/test_professional_ui_v811.py
T
浅念 5c7643fcf2 upgrade: adopt V8.12.0-dev.1 (V8.11 unified professional UI + V8.12 workflow usability)
- Overlay 26 changed files from SiteForge_Enterprise_V8_12 (UI layer only:
  professional-ui.js/css, workspace/factory-v2/operations/editor templates,
  +2 test files, compose/ci/scripts/docs)
- Re-apply v8_workflows type-mapping fix (类型/分类) lost in upgrade
- Pin compose project name to siteforge-v8-10 so existing data volumes
  (hesupipe site 483295c29ea0, 193 entries) keep attached
- Drop stray .s10_* state files; ignore .s10_*/.sf_*/.s87_* patterns
- Plan/spec revisions per plan-review round 1 (icons are new design,
  real test assertions, recorded deviations)

Tests: 226 passed / 1 env-only failure (test needs node binary in PATH,
absent in python:3.12-slim container; host node v24 --check all 9 JS OK)

Co-Authored-By: Claude Code <noreply@anthropic.com>
2026-10-22 17:02:45 +08:00

86 lines
3.5 KiB
Python

"""V8.11: specialized tools share a single task-oriented UI without changing APIs."""
from test_factory import client
PROFESSIONAL = {
'/editor/{site}/{entry}': 'editor',
'/theme-gallery': 'theme',
'/factory-studio': 'factory',
'/operations': 'operations',
'/production-v8': 'production',
}
def create_site(client):
response = client.post('/api/sites', json={'name': 'V8.11 UI', 'theme': 'corporate'})
assert response.status_code == 201, response.text
sid = response.json()['id']
entry = client.get(f'/api/sites/{sid}/entries').json()[0]
return sid, entry['id']
def test_all_professional_pages_load_unified_shell(client):
site, entry = create_site(client)
for pattern, page_type in PROFESSIONAL.items():
uri = pattern.format(site=site, entry=entry)
response = client.get(uri)
assert response.status_code == 200, uri
assert f'data-sf-page="{page_type}"' in response.text, uri
assert '/ui/professional-ui.js' in response.text
assert '/ui/professional-ui.css' in response.text
def test_shared_navigation_assets_are_real_routes(client):
css = client.get('/ui/professional-ui.css')
js = client.get('/ui/professional-ui.js')
assert css.status_code == 200 and js.status_code == 200
assert 'sf-bar-nav' in css.text and '.sf-editor-mobile-tabs' in css.text
for code in ('siteforge:selected-site', 'sfGlobalSite', 'aria-current', 'MutationObserver'):
assert code in js.text
def test_site_switcher_avoids_cross_site_editor_paths(client):
js = client.get('/ui/professional-ui.js').text
assert "ctx==='editor'" in js
assert "location.assign(route('design'))" in js
assert 'items.some(s=>s.id===wanted)' in js # selected ID validated against visible sites
assert 'siteforge:selected-site' in client.get('/ui/workspace.js').text
def test_professional_forms_keep_validation_and_csrf(client):
js = client.get('/ui/professional-ui.js').text
assert "addEventListener('invalid'" in js
assert "aria-invalid" in js
assert 'X-SiteForge-CSRF' in client.get('/ui/operations.js').text
assert 'X-SiteForge-CSRF' in client.get('/ui/workspace.js').text
def test_operations_are_split_into_three_steps(client):
shell = client.get('/ui/professional-ui.js').text
assert '② 生成静态网站' in shell
assert '③ 审批与发布' in shell
assert "role','tabpanel'" in shell
page = client.get('/operations').text
assert all(word in page for word in ('CMS 数据迁移', '生产构建任务', '远程发布'))
def test_editor_preserves_draft_publish_and_mobile_panels(client):
site, entry = create_site(client)
html = client.get(f'/editor/{site}/{entry}').text
assert 'Studio.save()' in html and 'Studio.publishDesign()' in html
js = client.get('/ui/professional-ui.js').text
assert all(word in js for word in ('结构', '页面预览', '属性设置', "dataset.mobilePane"))
assert 'sf-editor-actiongroup' in js
def test_health_and_main_workspace_match_unified_release(client):
assert client.get('/api/health').json()['version'] == '8.12.0-dev.1'
assert 'const headings=' in client.get('/ui/workspace.js').text
assert 'new URLSearchParams(location.search)' in client.get('/ui/workspace.js').text
def test_existing_theme_and_content_apis_unchanged(client):
sid, _ = create_site(client)
assert client.get('/api/themes').status_code == 200
assert client.get(f'/api/sites/{sid}/entries').status_code == 200
assert client.get(f'/api/sites/{sid}/builds').status_code == 200