test(client): align contracts with current behavior

This commit is contained in:
2026-08-30 18:26:37 +08:00
parent da92b75ae1
commit e22c671de4
2 changed files with 18 additions and 13 deletions
@@ -34,7 +34,7 @@ test('exposes real list, draft, submit, and detail workflow entries without canc
assert.match(source, /function submitOrder\(\)/) assert.match(source, /function submitOrder\(\)/)
assert.match(source, /async function openDetail\(order: FirstLegOrder\)/) assert.match(source, /async function openDetail\(order: FirstLegOrder\)/)
assert.match(source, /Promise\.allSettled\(\[/) assert.match(source, /Promise\.allSettled\(\[/)
assert.match(source, /const orderPageRequest = isCreatePage\.value\s*\? store\.loadWarehouseType\('DOMESTIC', true\)\s*:\s*store\.load\(\)/) assert.match(source, /const orderPageRequest = isCreatePage\.value\s*\? store\.loadWarehouseType\('DOMESTIC', true\)\s*:\s*store\.load\(\{ includeDrafts: true \}\)/)
assert.match(source, /Promise\.allSettled\(\[\s*orderPageRequest,\s*companyRequest/) assert.match(source, /Promise\.allSettled\(\[\s*orderPageRequest,\s*companyRequest/)
assert.match(source, /tenantStore\.loadCompanyContext\(\)/) assert.match(source, /tenantStore\.loadCompanyContext\(\)/)
assert.match(source, /await store\.loadDetail\(order\.id\)/) assert.match(source, /await store\.loadDetail\(order\.id\)/)
@@ -58,7 +58,7 @@ test('defers approval checks to the server when the member cannot read the compa
assert.match(source, /const canViewCompanyProfile = computed/) assert.match(source, /const canViewCompanyProfile = computed/)
assert.match(source, /const companySubmissionBlocked = computed\(\(\) => companyAuditLoaded\.value/) assert.match(source, /const companySubmissionBlocked = computed\(\(\) => companyAuditLoaded\.value/)
assert.match(source, /const knownCompanyAuditStatus = companyAuditLoaded\.value \? tenantStore\.company\.auditStatus : undefined/) assert.match(source, /const knownCompanyAuditStatus = companyAuditLoaded\.value \? tenantStore\.company\.auditStatus : undefined/)
assert.match(source, /store\.submit\([^\n]*knownCompanyAuditStatus\)/) assert.match(source, /store\.submitSaved\(savedOrder\.id, knownCompanyAuditStatus\)/)
}) })
test('renders dynamic cargo lines and a responsive editor dialog', () => { test('renders dynamic cargo lines and a responsive editor dialog', () => {
@@ -91,7 +91,7 @@ test('uses the shared query toolbar and data table without metric cards', () =>
assert.match(source, /async function searchOrders\(model: QueryModel\)/) assert.match(source, /async function searchOrders\(model: QueryModel\)/)
assert.match(source, /await store\.load\(\{/) assert.match(source, /await store\.load\(\{/)
assert.match(source, /<DataTable v-model:page="tablePage" v-model:page-size="tablePageSize" :data="pagedOrders" :columns="visibleOrderColumns"/) assert.match(source, /<DataTable v-model:page="tablePage" v-model:page-size="tablePageSize" :data="pagedOrders" :columns="visibleOrderColumns"/)
assert.match(source, /\{ key: 'actions', label: '操作', width: 128, fixed: 'left', align: 'center', headerAlign: 'center', slotName: 'actions' \}/) assert.match(source, /\{ key: 'actions', label: '操作', width: 216, fixed: 'left', align: 'center', headerAlign: 'center', slotName: 'actions' \}/)
assert.doesNotMatch(source, /order-metrics|订单概览/) assert.doesNotMatch(source, /order-metrics|订单概览/)
}) })
@@ -236,10 +236,12 @@ test('keeps the seven-stage progress and business summary usable on mobile', ()
}) })
test('keeps the first viewport compact and moves create into the table toolbar', () => { test('keeps the first viewport compact and moves create into the table toolbar', () => {
const queryToolbarSource = source.slice(source.indexOf('<QueryToolbar'), source.indexOf('</QueryToolbar>') + '</QueryToolbar>'.length)
assert.match(source, /class="order-table-toolbar"/) assert.match(source, /class="order-table-toolbar"/)
assert.match(source, /<strong>订单列表<\/strong><span>共 \{\{ filteredOrders\.length \}\} 条<\/span>/) assert.match(source, /<strong>订单列表<\/strong><span>共 \{\{ filteredOrders\.length \}\} 条<\/span>/)
assert.match(source, /class="order-table-toolbar"[\s\S]*order:first-leg:create[\s\S]*创建订单[\s\S]*class="order-eligibility is-pending"/) assert.match(source, /class="order-table-toolbar"[\s\S]*order:first-leg:create[\s\S]*创建订单[\s\S]*class="order-eligibility is-pending"/)
assert.doesNotMatch(source, /<QueryToolbar[\s\S]*?<template #actions>/) assert.match(queryToolbarSource, /<template #actions>[\s\S]*下载唛头[\s\S]*导出订单信息/)
assert.doesNotMatch(queryToolbarSource, /order:first-leg:create|创建订单/)
assert.match(source, /client-main:has\(> \.first-leg-page:not\(\.is-create-route\)\) > \.client-page-heading > div\) \{ position: absolute; width: 1px; height: 1px;/) assert.match(source, /client-main:has\(> \.first-leg-page:not\(\.is-create-route\)\) > \.client-page-heading > div\) \{ position: absolute; width: 1px; height: 1px;/)
}) })
@@ -319,6 +321,7 @@ test('collects the backend-required first-leg fields', () => {
}) })
test('distills order creation into the confirmed prototype sections with server pricing', () => { test('distills order creation into the confirmed prototype sections with server pricing', () => {
const cargoTableSource = source.slice(source.indexOf('<table class="cargo-edit-table">'), source.indexOf('</table>', source.indexOf('<table class="cargo-edit-table">')))
assert.match(source, /<h3>目的地信息<\/h3>/) assert.match(source, /<h3>目的地信息<\/h3>/)
assert.match(source, /<h3>客户下单<\/h3>/) assert.match(source, /<h3>客户下单<\/h3>/)
assert.match(source, /<h3>货物明细<\/h3>/) assert.match(source, /<h3>货物明细<\/h3>/)
@@ -326,8 +329,10 @@ test('distills order creation into the confirmed prototype sections with server
assert.ok(source.indexOf('<h3>目的地信息</h3>') < source.indexOf('<h3>货物明细</h3>')) assert.ok(source.indexOf('<h3>目的地信息</h3>') < source.indexOf('<h3>货物明细</h3>'))
assert.match(source, /class="segmented-options"/) assert.match(source, /class="segmented-options"/)
assert.match(source, /class="prototype-form-row prototype-form-row--tabs"/) assert.match(source, /class="prototype-form-row prototype-form-row--tabs"/)
for (const heading of ['商品信息', '箱规、数量与重量', '报关与产品资料', '货件与备注']) { assert.match(source, /<table class="cargo-edit-table">/)
assert.match(source, new RegExp(`<h4>${heading}</h4>`)) assert.match(source, /上传 Excel[\s\S]*下载模板[\s\S]*添加行[\s\S]*删除所选行/)
for (const heading of ['SKU NO.', '中文品名', '箱规长 cm', '总毛重', '报关 HS CODE', '货件编号', '跟踪编号', 'UPC NO.']) {
assert.ok(cargoTableSource.includes(heading))
} }
assert.match(source, /参考运费/) assert.match(source, /参考运费/)
assert.match(source, /仅供参考,最终以实际结算为准/) assert.match(source, /仅供参考,最终以实际结算为准/)
@@ -389,8 +394,8 @@ test('shows field-level validation and concise guidance for required order input
assert.match(source, /prop="consigneePartySnapshot\.address" required/) assert.match(source, /prop="consigneePartySnapshot\.address" required/)
assert.match(source, /:prop="`items\.\$\{index\}\.cargoNameCn`" required/) assert.match(source, /:prop="`items\.\$\{index\}\.cargoNameCn`" required/)
assert.match(source, /:prop="`items\.\$\{index\}\.grossWeightKg`" required/) assert.match(source, /:prop="`items\.\$\{index\}\.grossWeightKg`" required/)
assert.match(source, /label="UPC NO\."[^>]*:required="form\.destinationType === 'FBA'"[^>]*>\s*<el-input v-model="item\.upc"/) assert.match(source, /:prop="`items\.\$\{index\}\.upc`"[^>]*:required="form\.destinationType === 'FBA'"[^>]*>\s*<el-input v-model="item\.upc"/)
assert.match(source, /placeholder="例如:蓝牙音箱"/) assert.match(source, /v-model="item\.cargoNameCn"[^>]*placeholder="中文品名"/)
assert.match(source, /\.order-form :deep\(\.el-form-item__error\).*position: static/) assert.match(source, /\.order-form :deep\(\.el-form-item__error\).*position: static/)
}) })
@@ -421,8 +426,8 @@ test('shows the full customer-safe order detail without platform-only controls',
for (const field of [ for (const field of [
'贸易条款', '发货方式', '报关方式', '运输渠道', '收货要求', '目的仓类型', '海关查验', '贸易条款', '发货方式', '报关方式', '运输渠道', '收货要求', '目的仓类型', '海关查验',
'提交时间', '完成时间', 'SKU NO.', 'UPC NO.', '报关 HS CODE', '清关 HS CODE', '每箱数量', '提交时间', '完成时间', 'SKU NO.', 'UPC NO.', '报关 HS CODE', '清关 HS CODE', '每箱数量',
'总净重', '清关申报单价', '中英文材质', '中英文用途', '产品规格', 'Shipment ID', '总净重', '清关申报单价', '中英文材质', '中英文用途', '产品规格', '货件编号',
'Reference ID', '危险品', '跟踪编号', '危险品',
]) { ]) {
assert.match(source, new RegExp(field)) assert.match(source, new RegExp(field))
} }
+3 -3
View File
@@ -26,12 +26,12 @@ test('style source contract: constrains the desktop sidebar and gives the menu i
test('style source contract: presents native grouped rows matching the prototype active and divider states', () => { test('style source contract: presents native grouped rows matching the prototype active and divider states', () => {
assert.doesNotMatch(compact, /\.client-sidebar \.el-menu|\.el-menu-item|\.el-sub-menu/) assert.doesNotMatch(compact, /\.client-sidebar \.el-menu|\.el-menu-item|\.el-sub-menu/)
assert.match(compact, /\.client-nav-menu,[^\{]*\.client-nav-submenu\s*\{[^}]*margin:\s*0[^}]*padding:\s*0[^}]*list-style:\s*none/) assert.match(compact, /\.client-nav-menu,[^\{]*\.client-nav-submenu\s*\{[^}]*margin:\s*0[^}]*padding:\s*0[^}]*list-style:\s*none/)
assert.match(compact, /\.client-sidebar-group-trigger,[^\{]*\.client-sidebar-link\s*\{[^}]*height:\s*44px[^}]*border-radius:\s*10px[^}]*color:\s*rgba\(255, 255, 255, \.72\)/) assert.match(compact, /\.client-sidebar-group-trigger,[^\{]*\.client-sidebar-link\s*\{[^}]*height:\s*46px[^}]*border-radius:\s*10px[^}]*color:\s*rgba\(255, 255, 255, \.82\)/)
assert.match(compact, /\.client-nav-submenu \.client-sidebar-link\[aria-current="page"\]\s*\{[^}]*background:\s*rgba\(30, 136, 229, \.25\)[^}]*color:\s*#fff/) assert.match(compact, /\.client-nav-submenu \.client-sidebar-link\[aria-current="page"\]\s*\{[^}]*background:\s*rgba\(30, 136, 229, \.25\)[^}]*color:\s*#fff/)
assert.match(compact, /\.client-nav-node\.is-active-parent > \.client-sidebar-group-trigger\s*\{[^}]*color:\s*#fff/) assert.match(compact, /\.client-nav-node\.is-active-parent > \.client-sidebar-group-trigger\s*\{[^}]*color:\s*#fff/)
assert.match(compact, /\.client-nav-node\.has-divider-before\s*\{[^}]*border-top:\s*1px solid rgba\(255, 255, 255, \.09\)/) assert.match(compact, /\.client-nav-node\.has-divider-before\s*\{[^}]*border-top:\s*1px solid rgba\(255, 255, 255, \.09\)/)
assert.match(compact, /\.client-nav-submenu\s*\{[^}]*padding:\s*2px 0 2px 12px/) assert.match(compact, /\.client-nav-submenu\s*\{[^}]*padding:\s*2px 0 2px 12px/)
assert.match(compact, /\.client-nav-submenu \.client-sidebar-link\s*\{[^}]*height:\s*40px[^}]*margin:\s*1px 0[^}]*padding:\s*0 12px[^}]*border-radius:\s*9px/) assert.match(compact, /\.client-nav-submenu \.client-sidebar-link\s*\{[^}]*height:\s*42px[^}]*margin:\s*1px 0[^}]*padding:\s*0 14px 0 22px[^}]*border-radius:\s*9px/)
assert.match(compact, /\.client-sidebar \.client-nav-submenu \.client-sidebar-node-icon\s*\{[^}]*width:\s*16px[^}]*height:\s*16px[^}]*flex:\s*0 0 16px/) assert.match(compact, /\.client-sidebar \.client-nav-submenu \.client-sidebar-node-icon\s*\{[^}]*width:\s*16px[^}]*height:\s*16px[^}]*flex:\s*0 0 16px/)
assert.match(compact, /\.client-sidebar-group-trigger\s*\{[^}]*border:\s*0[^}]*background:\s*transparent/) assert.match(compact, /\.client-sidebar-group-trigger\s*\{[^}]*border:\s*0[^}]*background:\s*transparent/)
assert.match(compact, /\.client-sidebar-link\s*\{[^}]*text-decoration:\s*none/) assert.match(compact, /\.client-sidebar-link\s*\{[^}]*text-decoration:\s*none/)
@@ -40,7 +40,7 @@ test('style source contract: presents native grouped rows matching the prototype
}) })
test('style source contract: makes navigation and drawer controls touch sized with visible keyboard focus', () => { test('style source contract: makes navigation and drawer controls touch sized with visible keyboard focus', () => {
assert.match(compact, /\.client-sidebar-group-trigger,[^\{]*\.client-sidebar-link\s*\{[^}]*height:\s*44px/) assert.match(compact, /\.client-sidebar-group-trigger,[^\{]*\.client-sidebar-link\s*\{[^}]*height:\s*46px/)
assert.match(compact, /\.client-sidebar-group-trigger:focus-visible,\s*\.client-sidebar-link:focus-visible,[\s\S]*?\.client-sidebar-logout:focus-visible\s*\{[^}]*outline:\s*2px solid #6db9ff[^}]*outline-offset:\s*2px/) assert.match(compact, /\.client-sidebar-group-trigger:focus-visible,\s*\.client-sidebar-link:focus-visible,[\s\S]*?\.client-sidebar-logout:focus-visible\s*\{[^}]*outline:\s*2px solid #6db9ff[^}]*outline-offset:\s*2px/)
assert.match(compact, /\.client-sidebar-logout\s*\{[^}]*height:\s*44px[^}]*background:\s*rgba\(239, 68, 68, \.12\)/) assert.match(compact, /\.client-sidebar-logout\s*\{[^}]*height:\s*44px[^}]*background:\s*rgba\(239, 68, 68, \.12\)/)
}) })