This commit is contained in:
2026-08-12 12:19:02 +08:00
parent f9ff9086d5
commit 11e085e30f
24 changed files with 230 additions and 50 deletions
@@ -0,0 +1,52 @@
import { readFileSync } from 'node:fs'
import { resolve } from 'node:path'
import { describe, expect, it } from 'vitest'
const pages = [
['src/modules/container-loading/pages/ContainersView.vue', "key: 'cabinetNo'"],
['src/modules/loading-lists/components/LoadingListsView.vue', "key: 'preloadNo'"],
['src/modules/ocean-bookings/pages/OceanBookingsView.vue', "prop: 'bookingNo'"],
['src/modules/port-schedules/pages/PortSchedulesView.vue', "prop: 'schedule.scheduleNo'"],
['src/modules/trucking/pages/TruckAppointmentsView.vue', "key: 'appointmentNo'"],
['src/modules/customs/pages/CustomsCasesView.vue', "prop: 'customsNo'"],
['src/modules/outbound-dispatch/pages/OutboundDispatchesView.vue', "prop: 'orderNo'"],
] as const
function source(path: string) {
return readFileSync(resolve(process.cwd(), path), 'utf8')
}
describe('domestic outbound list responsive contracts', () => {
it.each(pages)('%s keeps the operation column first and fixed left', (path, firstBusinessColumn) => {
const content = source(path)
const firstAction = content.indexOf("label: '操作'")
expect(firstAction).toBeGreaterThan(-1)
expect(firstAction).toBeLessThan(content.indexOf(firstBusinessColumn, firstAction))
const actionObjects = [...content.matchAll(/\{[^{}]*label: '操作'[^{}]*\}/g)].map((match) => match[0])
expect(actionObjects.length).toBeGreaterThan(0)
for (const column of actionObjects) expect(column).toContain("fixed: 'left'")
})
it.each(pages)('%s gives every business column a stable width constraint', (path) => {
const content = source(path)
const columns = [...content.matchAll(/\{[^{}]*(?:key|prop): '[^']+'[^{}]*label: '[^']+'[^{}]*\}/g)]
.map((match) => match[0])
.filter((column) => !column.includes("type: 'input'") && !column.includes("type: 'select'") && !column.includes("type: 'daterange'"))
expect(columns.length).toBeGreaterThan(1)
for (const column of columns) expect(column).toMatch(/\b(?:width|minWidth):\s*\d+/)
})
it('keeps shared 320px degradation rules for filters, actions and pagination', () => {
const queryToolbar = source('src/shared/components/QueryToolbar.vue')
const dataTable = source('src/shared/components/DataTable.vue')
const listLayout = source('src/shared/components/ListPageLayout.vue')
expect(queryToolbar).toContain('@media (max-width: 720px)')
expect(queryToolbar).toContain('.query-toolbar__field { width: 100%; }')
expect(queryToolbar).toContain('grid-template-columns: repeat(auto-fit, minmax(120px, 1fr))')
expect(dataTable).toContain('@media (max-width: 720px)')
expect(dataTable).toContain('flex-direction: column')
expect(dataTable).toContain('.data-table__page-buttons { flex-wrap: wrap; }')
expect(listLayout).toContain('min-width: 0')
})
})