视觉审核完成30%
This commit is contained in:
@@ -33,6 +33,7 @@ $root = Split-Path -Parent $PSScriptRoot
|
||||
$entryPath = Join-Path $root 'pages/auth/a01-entry.vue'
|
||||
$legacyLoginPath = Join-Path $root 'pages/auth/a02-login.vue'
|
||||
$pagesPath = Join-Path $root 'pages.json'
|
||||
$globalStylesPath = Join-Path $root 'styles/global.scss'
|
||||
|
||||
if (-not (Test-Path -LiteralPath $entryPath)) {
|
||||
throw 'Missing the single A01 login page.'
|
||||
@@ -48,19 +49,59 @@ if ($pages.pages[0].path -ne 'pages/auth/a01-entry') {
|
||||
if ($pages.pages.path -contains 'pages/auth/a02-login') {
|
||||
throw 'pages.json must not retain the legacy A02 route.'
|
||||
}
|
||||
if ($pages.pages.Count -ne 53) {
|
||||
throw "Expected 53 final routes after the A02 merge, found $($pages.pages.Count)."
|
||||
if ($pages.pages.Count -ne 52) {
|
||||
throw "Expected 52 active routes after the A02 merge and A06 archive, found $($pages.pages.Count)."
|
||||
}
|
||||
|
||||
$entry = Get-Content -LiteralPath $entryPath -Raw -Encoding utf8
|
||||
$globalStyles = Get-Content -LiteralPath $globalStylesPath -Raw -Encoding utf8
|
||||
|
||||
# Typography has one owner, and the title decoration participates in normal flow.
|
||||
Assert-Contains -Content $globalStyles -Expected 'font-family: "STKaiti", "KaiTi", serif' -Message 'Global styles must own the STKaiti/KaiTi font contract.'
|
||||
Assert-NotContains -Content $entry -Unexpected 'font-family:' -Message 'A01 must inherit the global font contract instead of overriding it locally.'
|
||||
|
||||
$headingRule = [regex]::Match($entry, '(?ms)^\.login-heading\s*\{(?<Body>.*?)^\}')
|
||||
if (-not $headingRule.Success) {
|
||||
throw 'A01 is missing the login heading style rule.'
|
||||
}
|
||||
Assert-Contains -Content $headingRule.Groups['Body'].Value -Expected 'flex-direction: column;' -Message 'A01 login heading must lay out its title and divider vertically in normal flow.'
|
||||
Assert-NotContains -Content $headingRule.Groups['Body'].Value -Unexpected 'position:' -Message 'A01 login heading must not use positioning for ordinary vertical layout.'
|
||||
|
||||
$titleRule = [regex]::Match($entry, '(?ms)^\.login-title\s*\{(?<Body>.*?)^\}')
|
||||
if (-not $titleRule.Success) {
|
||||
throw 'A01 is missing the login title style rule.'
|
||||
}
|
||||
Assert-NotContains -Content $titleRule.Groups['Body'].Value -Unexpected 'position:' -Message 'A01 login title must remain in normal flow.'
|
||||
|
||||
$dividerRule = [regex]::Match($entry, '(?ms)^\.title-divider\s*\{(?<Body>.*?)^\}')
|
||||
if (-not $dividerRule.Success) {
|
||||
throw 'A01 is missing the title divider style rule.'
|
||||
}
|
||||
foreach ($positioning in @('position: absolute', 'left: 50%', 'translateX(')) {
|
||||
Assert-NotContains -Content $dividerRule.Groups['Body'].Value -Unexpected $positioning -Message "A01 title divider must not use manual positioning: $positioning"
|
||||
}
|
||||
Assert-Contains -Content $dividerRule.Groups['Body'].Value -Expected 'width: 360rpx;' -Message 'A01 title divider must be wide enough to remain visible on paper.'
|
||||
Assert-Contains -Content $dividerRule.Groups['Body'].Value -Expected 'height: 60rpx;' -Message 'A01 title divider must retain a legible knot and line weight.'
|
||||
Assert-Contains -Content $dividerRule.Groups['Body'].Value -Expected 'filter: brightness(0.68) saturate(1.5) contrast(1.2);' -Message 'A01 title divider must keep sufficient contrast against the paper background.'
|
||||
|
||||
$brandSealRule = [regex]::Match($entry, '(?ms)^\.brand-seal\s*\{(?<Body>.*?)^\}')
|
||||
if (-not $brandSealRule.Success) {
|
||||
throw 'A01 is missing the brand seal style rule.'
|
||||
}
|
||||
Assert-Contains -Content $brandSealRule.Groups['Body'].Value -Expected 'width: 184rpx;' -Message 'A01 brand seal must use the approved smaller width.'
|
||||
Assert-Contains -Content $brandSealRule.Groups['Body'].Value -Expected 'height: 221rpx;' -Message 'A01 brand seal must preserve its aspect ratio at the approved smaller height.'
|
||||
Assert-Contains -Content $brandSealRule.Groups['Body'].Value -Expected 'top: 64rpx;' -Message 'A01 brand seal must keep its approved vertical anchor.'
|
||||
Assert-Contains -Content $brandSealRule.Groups['Body'].Value -Expected 'left: 50%;' -Message 'A01 brand seal must remain horizontally centered.'
|
||||
|
||||
# Final decorative surfaces must come from real bitmap assets.
|
||||
foreach ($asset in @(
|
||||
'a01-red-hall-ink-backdrop-v1.png',
|
||||
'brand-seal.png',
|
||||
'a01-title-divider-v2.png',
|
||||
'a01-primary-button.png',
|
||||
'a01-secondary-button.png',
|
||||
'a01-vnext-divider-v1.png',
|
||||
'a01-scroll-primary-v3.png',
|
||||
'a01-scroll-secondary-v3.png',
|
||||
'a01-scroll-toast-v3.png',
|
||||
'a01-scroll-dialog-v3.png',
|
||||
'auth-wechat.png',
|
||||
'a01-icon-phone-v1.png',
|
||||
'a01-icon-lock-v1.png',
|
||||
@@ -80,10 +121,24 @@ foreach ($obsoleteVisualAsset in @(
|
||||
'a01-login-scroll-frame-v1.png',
|
||||
'a01-vnext-scroll-v1.png',
|
||||
'auth-ink-scenery.png'
|
||||
'a01-title-divider-v2.png',
|
||||
'a01-primary-button-v2.png',
|
||||
'a01-secondary-button-v2.png',
|
||||
'a02-login-panel.png'
|
||||
)) {
|
||||
Assert-NotContains -Content $entry -Unexpected $obsoleteVisualAsset -Message "A01 must not retain the rejected header, scenery, or scroll asset: $obsoleteVisualAsset"
|
||||
}
|
||||
|
||||
$buttonSkinTags = [regex]::Matches($entry, '<image class="button-skin"[^>]+>')
|
||||
if ($buttonSkinTags.Count -ne 2) {
|
||||
throw "A01 must have exactly two visible login button skins, found $($buttonSkinTags.Count)."
|
||||
}
|
||||
foreach ($buttonSkinTag in $buttonSkinTags) {
|
||||
Assert-Contains -Content $buttonSkinTag.Value -Expected 'mode="aspectFit"' -Message 'A01 button skins must use uniform aspectFit rendering.'
|
||||
Assert-NotContains -Content $buttonSkinTag.Value -Unexpected '/opaque/' -Message 'A01 visible button skins must use cleaned transparent v2 assets.'
|
||||
Assert-NotContains -Content $buttonSkinTag.Value -Unexpected 'mode="scaleToFill"' -Message 'A01 button skins must not distort fixed artwork with scaleToFill.'
|
||||
}
|
||||
|
||||
$requiredCopy = @(
|
||||
'55m75b2V5a626LCx',
|
||||
'5a+G56CB55m75b2V',
|
||||
@@ -137,4 +192,13 @@ Assert-NotContains -Content $entry -Unexpected 'a01-icon-eye-closed-v1.png' -Mes
|
||||
Assert-NotContains -Content $entry -Unexpected 'a01-icon-verification-v1.png' -Message 'A01 SMS field must use a message-code icon instead of a success-state checkmark.'
|
||||
Assert-NotContains -Content $entry -Unexpected 'a01-icon-sms-code-v1.svg' -Message 'A01 SMS field must use the custom generated icon instead of the temporary third-party SVG.'
|
||||
Assert-NotContains -Content $entry -Unexpected '@media (max-height:' -Message 'A01 must scroll naturally on short screens instead of compressing the selected design with height breakpoints.'
|
||||
Assert-NotContains -Content $entry -Unexpected 'feedback-toast__skin' -Message 'A01 feedback Toast must use the dedicated nine-slice border asset instead of an absolutely stretched image.'
|
||||
|
||||
$feedbackToastRule = [regex]::Match($entry, '(?ms)^\.feedback-toast\s*\{(?<Body>.*?)^\}')
|
||||
if (-not $feedbackToastRule.Success) {
|
||||
throw 'A01 is missing the custom feedback Toast style rule.'
|
||||
}
|
||||
Assert-Contains -Content $feedbackToastRule.Groups['Body'].Value -Expected "border-image-source: url('/static/assets/foundation/transparent/a01-scroll-toast-v3.png');" -Message 'A01 feedback Toast must use the approved v3 nine-slice asset.'
|
||||
Assert-Contains -Content $feedbackToastRule.Groups['Body'].Value -Expected 'border-image-slice:' -Message 'A01 feedback Toast must declare fixed decorative slices.'
|
||||
Assert-Contains -Content $feedbackToastRule.Groups['Body'].Value -Expected 'fill' -Message 'A01 feedback Toast nine-slice must fill the paper center.'
|
||||
Write-Output 'A01-LOGIN-MERGE-CONTRACT PASS'
|
||||
|
||||
Reference in New Issue
Block a user