开始审核样式

This commit is contained in:
rain
2026-07-15 17:23:19 +08:00
parent 241a7af54c
commit 0dec90ffdd
46 changed files with 999 additions and 964 deletions
+74 -153
View File
@@ -31,179 +31,100 @@ function Assert-NotContains {
$root = Split-Path -Parent $PSScriptRoot
$entryPath = Join-Path $root 'pages/auth/a01-entry.vue'
$loginPath = Join-Path $root 'pages/auth/a02-login.vue'
$legacyLoginPath = Join-Path $root 'pages/auth/a02-login.vue'
$pagesPath = Join-Path $root 'pages.json'
if (-not (Test-Path -LiteralPath $entryPath)) {
throw 'Missing A-01 entry page: pages/auth/a01-entry.vue'
throw 'Missing the single A01 login page.'
}
if (Test-Path -LiteralPath $legacyLoginPath) {
throw 'A02 was merged into A01, so the legacy page file must be removed.'
}
$pages = Get-Content -LiteralPath $pagesPath -Raw -Encoding utf8 | ConvertFrom-Json
if ($pages.pages[0].path -ne 'pages/auth/a01-entry') {
throw 'A-01 entry page must be the first route in pages.json'
throw 'A01 must remain the first application route.'
}
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)."
}
$entry = Get-Content -LiteralPath $entryPath -Raw -Encoding utf8
$login = Get-Content -LiteralPath $loginPath -Raw -Encoding utf8
$accountPasswordLogin = ConvertFrom-Utf8Base64 '6LSm5Y+35a+G56CB55m75b2V'
$wechatLogin = ConvertFrom-Utf8Base64 '5b6u5L+h55m75b2V'
$registerPrompt = ConvertFrom-Utf8Base64 '6L+Y5rKh5pyJ6LSm5Y+377yf'
$registerEntry = ConvertFrom-Utf8Base64 '5rOo5YaM6LSm5Y+3'
$loginEntry = ConvertFrom-Utf8Base64 '55m75b2V'
$dividerGlyph = ConvertFrom-Utf8Base64 '4oyY'
$agreementRequired = ConvertFrom-Utf8Base64 '6K+35YWI6ZiF6K+75bm25ZCM5oSP55u45YWz5Y2P6K6u'
$wechatPending = ConvertFrom-Utf8Base64 '5b6u5L+h55m75b2V5Yqf6IO95YeG5aSH5Lit'
$registerPending = ConvertFrom-Utf8Base64 '5rOo5YaM6aG16Z2i5YeG5aSH5Lit'
$agreementPending = ConvertFrom-Utf8Base64 '5Y2P6K6u6aG16Z2i5YeG5aSH5Lit'
$smsLogin = ConvertFrom-Utf8Base64 '5omL5py66aqM6K+B56CB55m75b2V'
$forgotPassword = ConvertFrom-Utf8Base64 '5b+Y6K6w5a+G56CB'
$getCode = ConvertFrom-Utf8Base64 '6I635Y+W6aqM6K+B56CB'
$loginPending = ConvertFrom-Utf8Base64 '55m75b2V5o6l5Y+j5b6F5o6l5YWl'
$forgotPasswordPending = ConvertFrom-Utf8Base64 '5b+Y6K6w5a+G56CB6aG16Z2i5YeG5aSH5Lit'
$getCodePending = ConvertFrom-Utf8Base64 '6I635Y+W6aqM6K+B56CB5Yqf6IO95b6F5o6l5YWl'
$implicitAgreement = ConvertFrom-Utf8Base64 '55m75b2V5Y2z6KGo56S65ZCM5oSP'
$agreementConfirm = ConvertFrom-Utf8Base64 '5oiR5bey6ZiF6K+75bm25ZCM5oSP'
$agreementGuard = ConvertFrom-Utf8Base64 '6K+35YWI6ZiF6K+75bm25ZCM5oSP55u45YWz5Y2P6K6u'
$legacyAgreementReminder = ConvertFrom-Utf8Base64 '6K+35YWI5Zyo55m75b2V5byV5a+86aG16Z2i5YeG5aSH5Lit6ZiF6K+75bm25ZCM5oSP5Y2P6K6u'
foreach ($requiredEntryCopy in @($wechatLogin, $registerPrompt, $registerEntry, $agreementRequired, $wechatPending, $registerPending, $agreementPending)) {
Assert-Contains -Content $entry -Expected $requiredEntryCopy -Message "Missing A-01 copy: $requiredEntryCopy"
}
Assert-Contains -Content $entry -Expected "url: '/pages/auth/a02-login?agreed=1'" -Message 'A-01 account login must navigate with agreed=1'
Assert-Contains -Content $entry -Expected "<text>$loginEntry</text>" -Message 'A-01 primary entry copy must be 登录'
foreach ($requiredClass in @('auth-header', 'brand-intro', 'entry-actions', 'agreement-row')) {
Assert-Contains -Content $entry -Expected $requiredClass -Message "Missing A-01 page structure: $requiredClass"
}
foreach ($requiredVisualAnchor in @(
'brand-divider--top',
'brand-divider--bottom',
'entry-button--primary',
'entry-button--secondary',
'height: 253rpx',
'padding: 150rpx 56rpx 0',
'width: 426rpx',
'margin: 95rpx 110rpx 0',
'height: 118rpx',
'margin-top: 51rpx',
'margin-top: 98rpx',
'margin-top: 141rpx',
'top: 70rpx',
'width: 64rpx',
'entry-button__content',
'translateX(-20rpx)',
'auth-divider-knot.png',
'auth-title-cloud.png',
# Final decorative surfaces must come from real bitmap assets.
foreach ($asset in @(
'a01-login-header-v1.png',
'a01-login-header-exact-v2.png',
'auth-ink-scenery.png',
'a01-login-scroll-frame-v1.png',
'a01-title-divider-v2.png',
'a01-primary-button.png',
'a01-secondary-button.png',
'entry-button__skin',
'align-items: center',
'white-space: nowrap',
'font-size: 20rpx',
'width: 30rpx',
'height: 30rpx'
)) {
Assert-Contains -Content $entry -Expected $requiredVisualAnchor -Message "Missing A-01 calibrated visual anchor: $requiredVisualAnchor"
}
foreach ($rejectedVisualConstruction in @('link-line', 'button-corner--legacy', 'class="auth-button primary-button"', 'auth-button-corner.png', 'button-corner-asset', '.entry-button::after')) {
Assert-NotContains -Content $entry -Unexpected $rejectedVisualConstruction -Message "A-01 retains rejected visual construction: $rejectedVisualConstruction"
}
foreach ($forbiddenClass in @('entryGuideVisual', 'guide-art', 'entry-hit', 'width: 750rpx', 'min-height: 1625rpx')) {
Assert-NotContains -Content $entry -Unexpected $forbiddenClass -Message "A-01 must not render the whole design image with $forbiddenClass"
}
Assert-NotContains -Content $entry -Unexpected '/static/assets/icons/action/create-cloud-v2.png' -Message 'A-01 must not reuse the mismatched create-cloud asset for its title or divider ornaments'
Assert-Contains -Content $entry -Expected 'filter: brightness(0) invert(1)' -Message 'A-01 primary login icon must render in white'
Assert-NotContains -Content $entry -Unexpected $dividerGlyph -Message 'A-01 divider must not use a text glyph as ornament'
if (([regex]::Matches($entry, 'class="entry-button__skin"')).Count -ne 2) {
throw 'A-01 must render one complete opaque skin image for each entry button'
}
if (([regex]::Matches($entry, 'auth-divider-knot\.png')).Count -ne 2) {
throw 'A-01 must render the dedicated divider-knot asset above and below the subtitle'
}
if ($entry -match '(?s)\.entry-button\s*\{[^}]*\bborder\s*:') {
throw 'A-01 entry buttons must not draw their final border with CSS'
}
if ($entry -match '(?s)\.entry-button--(?:primary|secondary)\s*\{[^}]*\bbackground\s*:') {
throw 'A-01 entry buttons must not draw their final surface with CSS'
}
if ($entry -notmatch '(?s)\.agreement-row\s*\{[^}]*align-items:\s*center') {
throw 'A-01 agreement checkbox and copy must align on one horizontal center line'
}
if ($entry -notmatch '(?s)\.agreement-copy\s*\{[^}]*white-space:\s*nowrap') {
throw 'A-01 agreement copy must remain on a single line'
}
if ($entry -match '(?s)\.auth-page\s*\{[^}]*overflow\s*:\s*hidden') {
throw 'A-01 must allow vertical scrolling on small screens'
}
foreach ($requiredLoginCopy in @($accountPasswordLogin, $smsLogin, $forgotPassword, $getCode, $loginPending, $agreementConfirm, $agreementGuard, $getCodePending)) {
Assert-Contains -Content $login -Expected $requiredLoginCopy -Message "Missing A-02 copy: $requiredLoginCopy"
}
Assert-Contains -Content $login -Expected "url: '/pages/auth/a05-reset-password'" -Message 'A-02 forgot-password entry must navigate to A-05'
foreach ($requiredLoginVisualAnchor in @(
'auth-title-cloud.png',
'login-title-cloud',
'a02-login-panel.png',
'login-panel__skin',
'a01-primary-button.png',
'login-submit__skin',
'login-submit__content',
'agreement-row',
'agreement-icon',
'auth-wechat.png',
'a01-icon-phone-v1.png',
'a01-icon-lock-v1.png',
'a01-icon-eye-open-v1.png',
'a01-icon-eye-closed-pupil-v2.png',
'a01-icon-sms-code-v2.png',
'a02-agreement-unchecked.png',
'a02-agreement-checked.png'
)) {
Assert-Contains -Content $login -Expected $requiredLoginVisualAnchor -Message "Missing A-02 calibrated visual anchor: $requiredLoginVisualAnchor"
Assert-Contains -Content $entry -Expected $asset -Message "A01 is missing asset reference: $asset"
}
if (([regex]::Matches($login, 'class="login-submit__skin"')).Count -ne 1) {
throw 'A-02 must render one complete opaque skin image for its login button'
}
if (([regex]::Matches($login, 'class="login-panel__skin"')).Count -ne 1) {
throw 'A-02 must render one complete opaque skin image for its login panel'
}
if ($login -match '(?s)\.login-panel\s*\{[^}]*\bborder\s*:') {
throw 'A-02 login panel must not draw its final frame with CSS'
}
if ($login -match '(?s)\.login-panel\s*\{[^}]*\bbackground\s*:') {
throw 'A-02 login panel must not draw its final paper surface with CSS'
}
if ($login -match '(?s)\.login-submit\s*\{[^}]*\bborder\s*:') {
throw 'A-02 login button must not draw its final border with CSS'
}
if ($login -match '(?s)\.login-submit\s*\{[^}]*\bbackground\s*:') {
throw 'A-02 login button must not draw its final surface with CSS'
}
if ($login -notmatch '<view class="agreement-row" @click="toggleAgreement">') {
throw 'A-02 must provide one directly clickable agreement row'
}
if (([regex]::Matches($login, '@click\.stop="prepareAgreement"')).Count -ne 2) {
throw 'A-02 agreement row must retain two non-toggling agreement links'
}
foreach ($requiredAgreementState in @('const agreed = ref(false)', 'const isAgreedRoute = () =>', "if (typeof location !== 'undefined') {", "new URLSearchParams(location.hash.split('?')[1] || '')", 'const pages = getCurrentPages()', 'const currentPage = pages[pages.length - 1]', "return currentPage?.options?.agreed === '1'", 'const syncAgreementFromRoute = () =>', 'agreed.value = isAgreedRoute()', 'onShow(() => {', 'syncAgreementFromRoute()', 'const toggleAgreement = () =>', 'if (agreed.value) return true')) {
Assert-Contains -Content $login -Expected $requiredAgreementState -Message "Missing A-02 agreement state: $requiredAgreementState"
}
Assert-NotContains -Content $login -Unexpected 'onLoad((options) =>' -Message 'A-02 must not leave agreement state initialized only on first load'
Assert-NotContains -Content $login -Unexpected $legacyAgreementReminder -Message 'A-02 must not retain its passive return-to-entry agreement reminder'
Assert-NotContains -Content $login -Unexpected 'agreedFromEntry' -Message 'A-02 must use its local agreed state as the submit gate'
if ($login -match '(?s)\.agreement-icon\s*\{[^}]*\bborder\s*:') {
throw 'A-02 agreement icon must not draw its final circle with CSS'
}
if ($login -match '(?s)\.agreement-icon\s*\{[^}]*\bbackground\s*:') {
throw 'A-02 agreement icon must not draw its final state with CSS'
}
if ($login -match '\.agreement-icon::(?:before|after)') {
throw 'A-02 agreement icon must not draw its final state with a pseudo element'
foreach ($obsoleteHeaderAsset in @('auth-header.png', 'brand-seal.png', 'a01-paper-transition-v1.png')) {
Assert-NotContains -Content $entry -Unexpected $obsoleteHeaderAsset -Message "A01 must use the selected design's single exact header bitmap instead of composing $obsoleteHeaderAsset."
}
if ($login -match '(?s)\.auth-page\s*\{[^}]*overflow\s*:\s*hidden') {
throw 'A-02 must allow vertical scrolling on small screens'
$requiredCopy = @(
'55m75b2V5a626LCx',
'5a+G56CB55m75b2V',
'6aqM6K+B56CB55m75b2V',
'5omL5py65Y+3',
'5a+G56CB',
'6aqM6K+B56CB',
'5b+Y6K6w5a+G56CB',
'6I635Y+W6aqM6K+B56CB',
'5b6u5L+h55m75b2V',
'6L+Y5rKh5pyJ6LSm5Y+377yf',
'5rOo5YaM6LSm5Y+3',
'44CK55So5oi35Y2P6K6u44CL',
'44CK6ZqQ56eB5pS/562W44CL'
) | ForEach-Object { ConvertFrom-Utf8Base64 $_ }
foreach ($copy in $requiredCopy) {
Assert-Contains -Content $entry -Expected $copy -Message "A01 is missing required visible copy: $copy"
}
foreach ($forbidden in @('appApi', 'calcMD5', 'loginWithPassword', 'uni.reLaunch', $implicitAgreement)) {
Assert-NotContains -Content $entry -Unexpected $forbidden -Message "A-01 must not contain legacy auth behavior: $forbidden"
Assert-NotContains -Content $login -Unexpected $forbidden -Message "A-02 must not contain legacy auth behavior: $forbidden"
foreach ($contract in @(
"const activeLoginMethod = ref('password')",
'const passwordVisible = ref(false)',
"const LOGIN_METHOD_STORAGE_KEY = 'a01:last-login-method'",
'uni.getStorageSync(LOGIN_METHOD_STORAGE_KEY)',
'uni.setStorageSync(LOGIN_METHOD_STORAGE_KEY, method)',
'const switchLoginMethod = (method) =>',
'const togglePasswordVisibility = () =>',
"url: '/pages/auth/a04-register'",
"url: '/pages/auth/a05-reset-password'",
'class="feedback-toast"',
'class="verification-layer"',
'class="login-submit"'
)) {
Assert-Contains -Content $entry -Expected $contract -Message "A01 is missing state or interaction contract: $contract"
}
Write-Output 'A01-A02-UI-CONTRACT PASS'
foreach ($nativeUi in @('uni.showToast', 'uni.showModal', 'uni.showLoading', 'uni.showActionSheet')) {
Assert-NotContains -Content $entry -Unexpected $nativeUi -Message "A01 must not use native UniApp feedback: $nativeUi"
}
Assert-NotContains -Content $entry -Unexpected "url: '/pages/auth/a02-login" -Message 'A01 must not navigate to A02.'
Assert-NotContains -Content $entry -Unexpected 'brand-intro' -Message 'A01 must remove the legacy oversized brand introduction.'
Assert-NotContains -Content $entry -Unexpected 'min-height: 100vh' -Message 'A01 must not depend on 100vh for its page shell.'
Assert-NotContains -Content $entry -Unexpected 'exact-chrome-overlay' -Message 'A01 must not stack a second full-screen scroll perimeter over the complete scroll frame.'
Assert-NotContains -Content $entry -Unexpected 'auth-design-scenery-v1.png' -Message 'A01 must not use the scenery bitmap that contains stray scroll handles.'
Assert-NotContains -Content $entry -Unexpected 'a01-icon-eye-closed-v1.png' -Message 'A01 hidden-password icon must retain the center pupil instead of using the hollow crossed eye.'
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 preserve the design ratio on short screens and scroll instead of compressing with pixel breakpoints.'
Write-Output 'A01-LOGIN-MERGE-CONTRACT PASS'
-48
View File
@@ -1,48 +0,0 @@
$ErrorActionPreference = 'Stop'
function ConvertFrom-Utf8Base64 {
param([string]$Value)
return [Text.Encoding]::UTF8.GetString([Convert]::FromBase64String($Value))
}
function Assert-Contains {
param(
[string]$Content,
[string]$Expected,
[string]$Message
)
if ($Content -notmatch [regex]::Escape($Expected)) {
throw $Message
}
}
$root = Split-Path -Parent $PSScriptRoot
$loginPath = Join-Path $root 'pages/auth/a02-login.vue'
$pagesPath = Join-Path $root 'pages.json'
$login = Get-Content -LiteralPath $loginPath -Raw -Encoding utf8
$pages = Get-Content -LiteralPath $pagesPath -Raw -Encoding utf8 | ConvertFrom-Json
$registerPrompt = ConvertFrom-Utf8Base64 '6L+Y5rKh5pyJ6LSm5Y+377yf'
$registerEntry = ConvertFrom-Utf8Base64 '5rOo5YaM6LSm5Y+3'
Assert-Contains -Content $login -Expected 'class="register-entry"' -Message 'A-02 must expose a dedicated registration entry below its agreement row'
Assert-Contains -Content $login -Expected $registerPrompt -Message 'A-02 must explain the registration path to new users'
Assert-Contains -Content $login -Expected 'class="register-link" hover-class="text-hover" @click="prepareRegister"' -Message 'A-02 registration copy must provide a focused tap target'
Assert-Contains -Content $login -Expected (">$registerEntry</view>") -Message 'A-02 registration action must be visible'
Assert-Contains -Content $login -Expected "const prepareRegister = () => uni.navigateTo({ url: '/pages/auth/a04-register' })" -Message 'A-02 registration entry must navigate to A-04'
$agreementIndex = $login.IndexOf('class="agreement-row"')
$registerIndex = $login.IndexOf('class="register-entry"')
if ($registerIndex -le $agreementIndex) {
throw 'A-02 registration entry must follow its agreement row in reading order'
}
if ($login -notmatch '(?s)\.register-link\s*\{[^}]*min-height:\s*88rpx') {
throw 'A-02 registration entry must retain a touch-friendly height'
}
if (-not ($pages.pages.path -contains 'pages/auth/a04-register')) {
throw 'A-02 registration entry target must remain declared in pages.json'
}
Write-Output 'A02-REGISTER-ENTRY-CONTRACT PASS'
+32
View File
@@ -0,0 +1,32 @@
$ErrorActionPreference = 'Stop'
$root = Split-Path -Parent $PSScriptRoot
$pages = Get-Content -LiteralPath (Join-Path $root 'pages.json') -Raw -Encoding utf8 | ConvertFrom-Json
$legacyPage = Join-Path $root 'pages/auth/a02-login.vue'
if ($pages.pages.Count -ne 53) { throw "Expected 53 routes, found $($pages.pages.Count)." }
if ($pages.pages.path -contains 'pages/auth/a02-login') { throw 'Legacy A02 route still exists.' }
if (Test-Path -LiteralPath $legacyPage) { throw 'Legacy A02 page file still exists.' }
$ownedFiles = @(
'pages/auth/a01-entry.vue',
'pages/auth/a04-register.vue',
'pages/auth/a05-reset-password.vue',
'pages/auth/a06-auth-status.vue',
'scripts/capture-chrome-page.js'
)
foreach ($relativePath in $ownedFiles) {
$content = Get-Content -LiteralPath (Join-Path $root $relativePath) -Raw -Encoding utf8
if ($content -match '/pages/auth/a02-login') {
throw "Legacy A02 navigation remains in $relativePath."
}
}
foreach ($returnPage in @('pages/auth/a04-register.vue', 'pages/auth/a05-reset-password.vue', 'pages/auth/a06-auth-status.vue')) {
$content = Get-Content -LiteralPath (Join-Path $root $returnPage) -Raw -Encoding utf8
if ($content -notmatch [regex]::Escape("url: '/pages/auth/a01-entry'")) {
throw "$returnPage must return to A01."
}
}
Write-Output 'A02-ROUTE-REMOVAL-CONTRACT PASS'
+1 -1
View File
@@ -8,6 +8,6 @@ $a03File = Join-Path $root 'pages/auth/a03-mobile-verify.vue'
if ($pages.pages.path -contains 'pages/auth/a03-mobile-verify') { throw 'A-03 must not remain in pages.json' }
if (Test-Path -LiteralPath $a03File) { throw 'A-03 page file must be deleted' }
if ($catalog -match '(?m)^\s*a03\s*:') { throw 'A-03 catalog entry must be deleted' }
if ($pages.pages.Count -ne 54) { throw "Expected 54 final routes after the approved G02-to-G01, G04-to-G03, G07-to-G06 and T02-to-T01 state merges, found $($pages.pages.Count)." }
if ($pages.pages.Count -ne 53) { throw "Expected 53 final routes after the approved page-state merges, found $($pages.pages.Count)." }
Write-Output 'A03-ROUTE-REMOVAL-CONTRACT PASS'
+1 -1
View File
@@ -38,7 +38,7 @@ foreach ($required in @(
'const agreed = ref(false)',
'const toggleAgreement = () =>',
'const submitRegister = () =>',
"const prepareLogin = () => uni.navigateTo({ url: '/pages/auth/a02-login' })",
"const prepareLogin = () => uni.navigateTo({ url: '/pages/auth/a01-entry' })",
'if (!/^1\d{10}$/.test(phone.value))',
'if (!password.value)',
'if (password.value !== confirmPassword.value)'
+2 -2
View File
@@ -40,7 +40,7 @@ foreach ($required in @(
'v-model="confirmPassword"',
'const prepareGetCode = () =>',
'const submitReset = () =>',
"const prepareLogin = () => uni.navigateTo({ url: '/pages/auth/a02-login' })",
"const prepareLogin = () => uni.navigateTo({ url: '/pages/auth/a01-entry' })",
'if (!/^1\d{10}$/.test(phone.value))',
'if (!/^\d{6}$/.test(verificationCode.value))',
'if (!password.value)',
@@ -51,7 +51,7 @@ foreach ($required in @(
Assert-Contains -Content $page -Expected $resetCopy -Message 'A-05 must visibly identify the password-reset task'
Assert-Contains -Content $page -Expected $confirmPasswordCopy -Message 'A-05 must require password confirmation'
Assert-Contains -Content $page -Expected $getCodeCopy -Message 'A-05 must expose the verification-code action'
Assert-Contains -Content $page -Expected $loginCopy -Message 'A-05 must provide the A02 return path'
Assert-Contains -Content $page -Expected $loginCopy -Message 'A-05 must provide the A01 return path'
Assert-NotContains -Content $catalog -Unexpected 'a05:' -Message 'A-05 must not remain in the temporary page catalog'
foreach ($forbidden in @(
+1 -1
View File
@@ -16,7 +16,7 @@ $pages = Get-Content -LiteralPath (Join-Path $root 'pages.json') -Raw -Encoding
$catalog = Get-Content -LiteralPath (Join-Path $root 'data/page-catalog.js') -Raw -Encoding utf8
if (-not ($pages.pages.path -contains 'pages/auth/a06-auth-status')) { throw 'A-06 route must remain declared in pages.json' }
if (-not ($pages.pages.path -contains 'pages/auth/a02-login')) { throw 'A-06 must retain the A02 return target' }
if (-not ($pages.pages.path -contains 'pages/auth/a01-entry')) { throw 'A-06 must retain the A01 return target' }
if (-not ($pages.pages.path -contains 'pages/auth/a04-register')) { throw 'A-06 must retain the A04 registration target' }
Assert-NotContains -Content $page -Unexpected 'ModulePage' -Message 'A-06 must not remain a ModulePage shell'
+1 -1
View File
@@ -76,7 +76,7 @@ const run = async () => {
await navigate(send, baseUrl, expected.normal)
await valueOf(send, "document.querySelector('.status-primary')?.click()")
await waitFor(send, "location.href.includes('/pages/auth/a02-login')", 'Default A06 action did not return to A02')
await waitFor(send, "location.href.includes('/pages/auth/a01-entry')", 'Default A06 action did not return to A01')
await navigate(send, `${baseUrl}?status=restricted`, expected.restricted)
await valueOf(send, "document.querySelector('.status-primary')?.click()")
+3
View File
@@ -62,4 +62,7 @@ if ($captureScript -notmatch "item\.url\.startsWith\('http://localhost:5173'\)")
if ($captureScript -match "item\.url\.includes\('localhost:5173'\)") {
throw 'Chrome capture must not use an ambiguous localhost substring when selecting its CDP target'
}
if ($captureScript -notmatch "process\.env\.CHROME_DEBUGGING_PORT \|\| '9222'") {
throw 'Chrome capture must preserve port 9222 by default and allow an isolated QA port.'
}
Write-Output 'CAPTURE-CHROME-PAGE-CONTRACT PASS'
-1
View File
@@ -38,7 +38,6 @@ function Test-AssetDirectory {
# P-00 final routes: each file name identifies the page and its design ID.
Test-ExpectedPage -ExpectedPath 'pages/auth/a01-entry' -PageId 'A-01'
Test-ExpectedPage -ExpectedPath 'pages/auth/a02-login' -PageId 'A-02'
Test-ExpectedPage -ExpectedPath 'pages/genealogy/g01-my-genealogies' -PageId 'G-01'
Test-ExpectedPage -ExpectedPath 'pages/genealogy/g03-create-genealogy' -PageId 'G-03'
Test-ExpectedPage -ExpectedPath 'pages/genealogy/g05-genealogy-overview' -PageId 'G-05'
+4 -4
View File
@@ -9,7 +9,7 @@ $root = Split-Path -Parent $PSScriptRoot
$pagesPath = Join-Path $root 'pages.json'
$pageHeader = ConvertFrom-Utf8Base64 '6aG16Z2i57yW5Y+377ya'
$expectedPages = @(
'pages/auth/a01-entry', 'pages/auth/a02-login', 'pages/auth/a04-register', 'pages/auth/a05-reset-password', 'pages/auth/a06-auth-status',
'pages/auth/a01-entry', 'pages/auth/a04-register', 'pages/auth/a05-reset-password', 'pages/auth/a06-auth-status',
'pages/genealogy/g01-my-genealogies', 'pages/genealogy/g03-create-genealogy', 'pages/genealogy/g05-genealogy-overview', 'pages/genealogy/g06-search-genealogies', 'pages/genealogy/g08-join-application', 'pages/genealogy/g09-my-applications', 'pages/genealogy/g10-application-review', 'pages/genealogy/g11-genealogy-settings', 'pages/genealogy/g12-generation-poems',
'pages/tree/t01-tree-overview', 'pages/tree/t03-member-profile', 'pages/tree/t04-add-relative', 'pages/tree/t05-edit-member', 'pages/tree/t06-edit-relationship', 'pages/tree/t07-member-directory', 'pages/tree/t08-member-states',
'pages/family/f01-family-feed', 'pages/family/f02-publish-feed', 'pages/family/f03-feed-detail', 'pages/family/f04-article-list', 'pages/family/f05-article-detail', 'pages/family/f06-article-editor', 'pages/family/f07-album-list', 'pages/family/f08-album-detail', 'pages/family/f09-media-upload', 'pages/family/f10-video-list',
@@ -20,11 +20,11 @@ $expectedPages = @(
$pages = Get-Content -LiteralPath $pagesPath -Raw -Encoding utf8 | ConvertFrom-Json
$actualPaths = @($pages.pages.path)
if ($actualPaths.Count -ne 54) {
throw "Expected 54 visual routes after the approved G02-to-G01, G04-to-G03, G07-to-G06 and T02-to-T01 state merges, found $($actualPaths.Count)."
if ($actualPaths.Count -ne 53) {
throw "Expected 53 visual routes after the approved page-state merges, found $($actualPaths.Count)."
}
if (Compare-Object -ReferenceObject $expectedPages -DifferenceObject $actualPaths) {
throw 'pages.json routes do not match the 54-route visual delivery contract.'
throw 'pages.json routes do not match the 53-route visual delivery contract.'
}
foreach ($page in $expectedPages) {
-2
View File
@@ -14,7 +14,6 @@ $requiredFiles = @(
'components/AppTabbar.vue',
'components/PageHeader.vue',
'pages/auth/a01-entry.vue',
'pages/auth/a02-login.vue',
'pages/genealogy/g01-my-genealogies.vue',
'pages/genealogy/g03-create-genealogy.vue',
'pages/genealogy/g05-genealogy-overview.vue',
@@ -40,7 +39,6 @@ $pages = Get-Content -Raw -Encoding UTF8 (Join-Path $root 'pages.json') | Conver
$paths = @($pages.pages | ForEach-Object { $_.path })
$requiredRoutes = @(
'pages/auth/a01-entry',
'pages/auth/a02-login',
'pages/genealogy/g01-my-genealogies',
'pages/genealogy/g03-create-genealogy',
'pages/genealogy/g05-genealogy-overview',