Files
jiapuapp/tests/module-page-visual-contract.ps1
T

69 lines
3.1 KiB
PowerShell

$ErrorActionPreference = 'Stop'
$root = Split-Path -Parent $PSScriptRoot
$componentPath = Join-Path $root 'components/ModulePage.vue'
if (-not (Test-Path -LiteralPath $componentPath)) { throw 'Missing shared module page component' }
$component = Get-Content -LiteralPath $componentPath -Raw -Encoding utf8
foreach ($anchor in @(
'const moduleState = ref(',
'["loading", "empty", "success", "error"].includes(query.state)',
'module-state--${moduleState}',
'empty: {',
'success: {',
'error: {',
'module-content-frame.png',
'module-field-frame.png',
'<AppLoading',
'<AppButton',
'<AppToast',
'<ModulePageBackground',
':style="moduleAssetStyle"',
'@use "../styles/adaptive-frame-profiles.scss" as adaptive;',
'@include adaptive.adaptive-module-field;',
'@include adaptive.adaptive-module-content;',
'const moduleAssetStyle = computed(() => ({',
'"--module-content-asset": `url(${contentAsset.value})`',
'"--module-field-asset": `url(${fieldAsset.value})`',
'query.state'
)) {
if ($component -notmatch [regex]::Escape($anchor)) { throw "ModulePage is missing high-spec anchor: $anchor" }
}
foreach ($forbidden in @(
'class="page-intro"',
'g03-create-flow-panel.png',
'g06-search-input-wide.png',
'application-status-card.png',
'background: var(--module-field-asset) center / 100% 100% no-repeat;',
'background: var(--module-content-asset) center / 100% 100% no-repeat;',
'height: 100%;'
)) {
if ($component -match [regex]::Escape($forbidden)) { throw "ModulePage must not keep obsolete shared surface: $forbidden" }
}
foreach ($className in @('module-panel', 'form-row', 'list-card', 'detail-card', 'timeline-row', 'settings-row', 'status-card')) {
foreach ($property in @('border', 'border-radius', 'box-shadow')) {
if ($component -match "(?s)\.$className\s*\{[^}]*\b$property\s*:") {
throw "ModulePage must not construct .$className with CSS $property"
}
}
}
if ($component -match '::before|::after') { throw 'ModulePage must not draw visible decorations with CSS pseudo-elements' }
if ($component -match '<image\b') { throw 'ModulePage must use approved container backgrounds instead of decorative image layers' }
if ($component -match '(?im)(?<![-\w])position\s*:') { throw 'ModulePage ordinary content must not use position declarations' }
foreach ($rule in @(
'(?s)\.module-page\s*\{[^}]*display:\s*flex;[^}]*flex-direction:\s*column;',
'(?s)\.module-page__header,\s*\.module-page__content,\s*\.module-page__loading\s*\{[^}]*z-index:\s*1;',
'(?s)\.module-lead\s*\{[^}]*background:\s*url\("/static/assets/modules/genealogy/transparent/section-divider\.png"\) center / 100% auto no-repeat;',
'(?s)\.module-lead\s*\{[^}]*display:\s*flex;[^}]*align-items:\s*center;[^}]*justify-content:\s*center;',
'(?s)\.form-row,\s*\.settings-row\s*\{[^}]*@include\s+adaptive\.adaptive-module-field;',
'(?s)\.list-card,\s*\.detail-card,\s*\.timeline-row,\s*\.status-card\s*\{[^}]*@include\s+adaptive\.adaptive-module-content;'
)) {
if ($component -notmatch $rule) { throw "ModulePage document-flow background rule missing: $rule" }
}
Write-Output 'MODULE-PAGE-VISUAL-CONTRACT PASS'