67 lines
5.8 KiB
JavaScript
67 lines
5.8 KiB
JavaScript
import fs from 'node:fs'
|
|
|
|
const read = (file) => fs.readFileSync(file, 'utf8')
|
|
const expect = (condition, message) => {
|
|
if (!condition) {
|
|
console.error(`FAIL: ${message}`)
|
|
process.exit(1)
|
|
}
|
|
console.log(`PASS: ${message}`)
|
|
}
|
|
|
|
const home = read('packages/kbx-ui/src/shell/KbxHomePage.vue')
|
|
expect(home.includes('allAttentionQueue') && home.includes('attentionCount:'), 'home module rail derives action pressure from the same attention truth as the home queue')
|
|
expect(home.includes("['ArrowLeft','ArrowRight','Home','End']") && home.includes('focusModuleRail'), 'home module rail is keyboard navigable without requiring mouse selection')
|
|
expect(home.includes('data-home-module="ALL"') && home.includes(':data-home-module="item.module"'), 'home module rail exposes stable focus targets')
|
|
expect(home.includes("explorer?.focus({preventScroll:true})"), 'module selection lands focus on the filtered work explorer')
|
|
expect(home.includes('@media(forced-colors:active)') && home.includes('button:focus-visible'), 'home module rail preserves active/focus cues in high-contrast navigation')
|
|
|
|
const sectionHeader = read('packages/kbx-ui/src/components/KbxSectionHeader.vue')
|
|
expect(sectionHeader.includes('countUnit?:string') && sectionHeader.includes("countUnit:'건'"), 'standard section heading owns count units instead of forcing screen-specific count markup')
|
|
|
|
for (const [file, slot] of [
|
|
['packages/kbx-ui/src/components/KbxMasterPage.vue', 'list-actions'],
|
|
['packages/kbx-ui/src/components/KbxMasterPage.vue', 'detail-actions'],
|
|
['packages/kbx-ui/src/components/KbxTransactionPage.vue', 'header-actions'],
|
|
['packages/kbx-ui/src/components/KbxTransactionPage.vue', 'detail-actions'],
|
|
['packages/kbx-ui/src/components/KbxQueuePage.vue', 'queue-actions'],
|
|
['packages/kbx-ui/src/components/KbxReconcilePage.vue', 'comparison-actions'],
|
|
]) {
|
|
expect(read(file).includes(`slot name="${slot}"`), `${file.split('/').at(-1)} exposes standard ${slot} work-surface actions`)
|
|
}
|
|
|
|
const order = read('apps/web/src/modules/oms/orders/register/OrderRegisterPage.vue')
|
|
expect(order.includes('const pageContext = computed') && order.includes(':context="pageContext"'), 'OMS order registration makes current record/status/error context explicit')
|
|
expect(order.includes('<template #detail-actions>') && order.includes('focusNextError') && order.includes('addLineAndFocus'), 'OMS order registration exposes row-add and error recovery beside the detail work surface')
|
|
expect(order.includes('detail-count-unit="종"'), 'OMS order detail count uses business-meaningful unit')
|
|
|
|
const purchase = read('apps/web/src/modules/erp/purchases/PurchasePage.vue')
|
|
expect(purchase.includes('useKbxDirtyState') && purchase.includes('useKbxWorkspaceBinding'), 'ERP purchase draft participates in workspace dirty-state recovery')
|
|
expect(purchase.includes('KbxLookupDialog') && purchase.includes('lookupRegistry.item.resolveByCode'), 'ERP purchase grid supports both F2 lookup and direct item-code resolution')
|
|
expect(purchase.includes('KbxValidationError') && purchase.includes('validateDraft()'), 'ERP purchase draft has field/row validation before save intent')
|
|
expect(!purchase.includes("status.value='CONFIRMED'") && purchase.includes('상태를 변경하지 않았습니다'), 'ERP purchase does not fabricate authoritative workflow state on the client')
|
|
expect(purchase.includes('editing-policy') && purchase.includes('row-duplicate-requested'), 'ERP purchase detail supports real fast-entry grid interactions')
|
|
|
|
const move = read('apps/web/src/modules/erp/inventory-move/InventoryMovePage.vue')
|
|
expect(move.includes('WAREHOUSE_MUST_DIFFER') && move.includes('INSUFFICIENT_STOCK'), 'ERP inventory move gives immediate cross-field and stock UX validation')
|
|
expect(move.includes('metadata?.availableQty') && move.includes('KbxLookupDialog'), 'ERP inventory move resolves item availability into the editing grid')
|
|
expect(!move.includes('status.value=t.to') && move.includes('상태를 변경하지 않았습니다'), 'ERP inventory move does not simulate Domain workflow transitions on the client')
|
|
expect(move.includes('useKbxPageShortcuts') && move.includes("key:'F8'"), 'ERP inventory move participates in the common save keyboard contract')
|
|
|
|
const wmsPage = read('apps/web/src/modules/wms/picking/WmsPickingPage.vue')
|
|
const wmsVm = read('apps/web/src/modules/wms/picking/useWmsPicking.ts')
|
|
expect(wmsPage.includes(':task-context="taskContext"') && wmsPage.includes(':instruction="stageTitle"'), 'WMS picking exposes task context and next instruction through the T09 template contract')
|
|
expect(wmsPage.includes('<template #notice>') && wmsPage.includes('pendingCommands') && wmsPage.includes('오프라인'), 'WMS picking dedicates a persistent notice surface to offline/retry truth')
|
|
expect(wmsPage.includes('다음 행동') && wmsPage.includes('중복 스캔하지 말고'), 'WMS picking tells the operator what to do next and prevents ambiguous repeat scans')
|
|
expect(wmsVm.includes("return '위치 스캔'") && wmsVm.includes("return '상품 스캔'"), 'WMS scanner labels use operator-facing Korean terminology')
|
|
|
|
const referenceHtml = read('apps/web/fe-reference/index.html')
|
|
const referenceJs = read('apps/web/fe-reference/kbx-fe.js')
|
|
const referenceCss = read('apps/web/fe-reference/kbx-fe.css')
|
|
expect(referenceHtml.includes('FE Reference Lab v53'), 'static HTML reference identifies the v53 golden-screen interaction build')
|
|
expect(referenceJs.includes('moduleAttentionCount') && referenceJs.includes('확인 ${moduleAttentionCount(module)}'), 'static JavaScript reference mirrors module attention pressure')
|
|
expect(referenceJs.includes("e.key==='ArrowRight'") && referenceJs.includes("e.key==='Home'"), 'static JavaScript module rail mirrors keyboard navigation')
|
|
expect(referenceCss.includes('.home-module-rail button:focus-visible'), 'static HTML reference visibly exposes module keyboard focus')
|
|
|
|
console.log('PASS: FE golden-screen interaction hardening v53 contract')
|