| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568 |
- import assert from 'node:assert/strict'
- import { chromium } from 'playwright'
- const browser = await chromium.launch({ headless: true, channel: 'chrome' })
- const context = await browser.newContext({
- viewport: { width: 1440, height: 1000 },
- permissions: ['clipboard-read', 'clipboard-write']
- })
- const page = await context.newPage()
- await page.clock.setFixedTime(new Date('2026-10-25T04:00:00Z'))
- page.setDefaultTimeout(60000)
- const errors = []
- page.on('pageerror', (error) => errors.push(error.message))
- page.on('console', (msg) => {
- if (msg.type() === 'error') console.error('CONSOLE', msg.text())
- })
- page.on('requestfailed', (request) => console.error('FAILED', request.url(), request.failure()))
- page.on('response', (response) => {
- if (response.status() >= 400) console.error('HTTP', response.status(), response.url())
- })
- const rows = Array.from({ length: 7 }, (_, i) => ({
- id: `plan-${i}`,
- planNo: `PL${i}`,
- planDate: '2026-10-24',
- followStatus: 'pending',
- vehicleId: `v${Math.floor(i / 2)}`,
- licensePlate: ['皖HA3690', '皖H10291', '皖H57837', '皖LB1283'][Math.floor(i / 2)],
- driverId: i < 2 ? 'driver-1' : undefined,
- driverName: i < 2 ? '测试司机' : undefined,
- products: [{ productId: i % 2 ? 'p2' : 'p1', productName: i % 2 ? '98酸' : 'cp酸' }],
- calendarRoute: '山峡库 → 永恒',
- load: { customerName: '山峡化工有限公司', calendarCustomerName: '山峡库' },
- deliveries: [{ customerName: '永恒有限公司', calendarCustomerName: '永恒' }]
- }))
- let failNext = false
- await context.addInitScript(() => {
- localStorage.setItem(
- 'sys-v3.0.2-user',
- JSON.stringify({
- isLogin: true,
- accessToken: 'calendar-fixture',
- info: {
- id: 'fixture',
- userId: 'fixture',
- userName: '测试用户',
- role: 'admin',
- roles: ['admin']
- }
- })
- )
- localStorage.setItem('sys-version', '3.0.2')
- })
- await context.route('**/api/**', async (route) => {
- const url = new URL(route.request().url())
- if (!url.pathname.startsWith('/api/')) return route.continue()
- const path = url.pathname.replace(/^\/api/, '')
- if (path === '/transport/plan/') {
- if (failNext) {
- failNext = false
- return route.fulfill({ status: 500, json: { detail: 'fixture failure' } })
- }
- const list = url.searchParams.get('planDateFrom')?.slice(0, 7) === '2026-10' ? rows : []
- return route.fulfill({
- json: {
- list: list.map((item) => ({ calendarVehicleType: 'self', ...item })),
- total: list.length
- }
- })
- }
- let data = {}
- if (path === '/web/auth/current-user')
- data = {
- id: 'fixture',
- userId: 'fixture',
- userName: '测试用户',
- role: 'admin',
- roles: ['admin']
- }
- else if (path === '/web/auth/menu-codes')
- data = {
- all: false,
- menuCodes: [
- 'pl:dispatch-calendar:list',
- 'pl:plan:list',
- 'pl:inbound:list',
- 'pl:outbound:list'
- ]
- }
- else if (path.includes('favorites') || path.includes('upgrade-logs')) data = []
- return route.fulfill({
- json: { code: path.startsWith('/transport/') ? 0 : 200, msg: 'ok', data }
- })
- })
- try {
- await page.goto(
- `${process.env.CALENDAR_TEST_ORIGIN || 'http://localhost:3006'}/#/pl/calendar-module/dispatch-calendar`
- )
- await page.getByText('派车日历', { exact: true }).first().click()
- await page.getByRole('tab', { name: '实际派车信息', exact: true }).click()
- const panel = page.locator('.dispatch-calendar-page')
- await panel.locator('.plate-number').first().waitFor({ timeout: 15000 })
- assert.equal(await panel.locator('.trip-card').count(), 7)
- assert.equal(await panel.locator('.vehicle-card').count(), 4)
- assert.equal(await panel.locator('.calendar-controls label').count(), 0)
- assert.equal(await panel.locator('.calendar-controls .el-select').count(), 1)
- assert.equal(await panel.getByLabel('司机筛选').count(), 0)
- assert.equal(await panel.locator('.trip-route').first().textContent(), '山峡库 → 永恒')
- await page.waitForFunction(() => {
- const button = document.querySelector('.dispatch-calendar-page .el-button--primary')
- return button && getComputedStyle(button).backgroundColor === 'rgb(31, 78, 121)'
- })
- for (const selector of ['.calendar-weekdays', '.plate-number', '.el-button--primary']) {
- assert.equal(
- await panel
- .locator(selector)
- .first()
- .evaluate((el) => getComputedStyle(el).backgroundColor),
- 'rgb(31, 78, 121)'
- )
- }
- assert.equal(await panel.locator('.calendar-day').count(), 35)
- const daily = panel.locator('[data-date="2026-10-24"]')
- assert.match(await daily.locator('.day-total').textContent(), /合计\s*7\s*车次/)
- assert.equal(await daily.getByText('未填写司机', { exact: true }).count(), 0)
- assert.equal(await daily.locator('.day-summary:visible').count(), 0)
- const copyButton = daily.getByRole('button', { name: '复制2026-10-24派车计划', exact: true })
- assert.ok(await panel.locator('[data-date="2026-10-01"] .day-copy-button').isDisabled())
- await copyButton.click()
- let copiedText = await page.evaluate(() => navigator.clipboard.readText())
- assert.match(copiedText, /^运输计划 10\.24\n• 皖HA3690 \/ cp酸 山峡库 - 永恒/)
- assert.equal(copiedText.split('\n').length, 5)
- await page.clock.setFixedTime(new Date('2026-10-23T04:00:00Z'))
- await copyButton.click()
- assert.match(await page.evaluate(() => navigator.clipboard.readText()), /^明日计划 10\.24/)
- await page.clock.setFixedTime(new Date('2026-10-22T04:00:00Z'))
- await copyButton.click()
- assert.match(await page.evaluate(() => navigator.clipboard.readText()), /^后日计划 10\.24/)
- await page.clock.setFixedTime(new Date('2026-10-25T04:00:00Z'))
- await daily.getByRole('button', { name: '查看2026-10-24货品汇总' }).click({ timeout: 2000 })
- const summaryPopup = page.locator('.calendar-summary-popper:visible')
- await summaryPopup.waitFor()
- assert.match(await summaryPopup.textContent(), /2026-10-24.*货品汇总/)
- assert.match(await summaryPopup.locator('.day-total').textContent(), /合计\s*7\s*车次/)
- assert.equal(await summaryPopup.locator('.product-total').count(), 2)
- await page.waitForFunction(() => {
- const popup = Array.from(document.querySelectorAll('.calendar-summary-popper')).find(
- (el) => el.getBoundingClientRect().width > 0
- )
- return popup && getComputedStyle(popup).opacity === '1'
- })
- await summaryPopup.screenshot({ path: '/tmp/shanxia-calendar-summary-popover.png' })
- await panel.locator('.title-bar-heading').click()
- await summaryPopup.waitFor({ state: 'hidden' })
- assert.equal(
- await daily.locator('.day-summary').evaluate((el) => getComputedStyle(el).backgroundColor),
- 'rgba(0, 0, 0, 0)'
- )
- await panel.locator('.el-select').click()
- await page
- .locator('.el-select-dropdown__item:visible')
- .getByText('皖HA3690', { exact: true })
- .click()
- assert.equal(await panel.locator('.trip-card').count(), 2)
- await panel.getByRole('button', { name: '重置筛选', exact: true }).click()
- assert.equal(await panel.locator('.trip-card').count(), 7)
- await panel.getByRole('button', { name: '下月', exact: true }).click()
- await panel.getByText('本月暂无派车计划', { exact: true }).waitFor()
- assert.equal(await panel.locator('.calendar-day').count(), 42)
- await panel.getByRole('button', { name: '上月', exact: true }).click()
- await daily.locator('.plate-number').first().waitFor()
- await daily.locator('.day-number').click()
- assert.ok((await daily.getAttribute('class')).includes('selected'))
- await page.setViewportSize({ width: 2560, height: 1300 })
- assert.equal(
- await daily
- .locator('.vehicle-grid')
- .evaluate((el) => getComputedStyle(el).gridTemplateColumns.split(' ').length),
- 2
- )
- await daily.screenshot({ path: '/tmp/shanxia-dispatch-calendar-day.png' })
- await page.screenshot({ path: '/tmp/shanxia-dispatch-calendar-web.png' })
- // 捕获浏览器打印调用,验证独立打印文档使用当前月历而非整个后台。
- await page.evaluate(() => {
- const append = document.body.appendChild
- document.body.appendChild = function (node) {
- const result = append.call(this, node)
- if (node.tagName === 'IFRAME') {
- node.contentWindow.print = () => {
- window.calendarPrintCalled = true
- }
- document.body.appendChild = append
- }
- return result
- }
- })
- await panel.getByRole('button', { name: '打印日历', exact: true }).click()
- await page.waitForFunction(() => window.calendarPrintCalled === true)
- const printFrame = page.frameLocator('iframe[aria-hidden="true"]')
- assert.equal(await printFrame.locator('.trip-card').count(), 7)
- assert.match(
- await printFrame.locator('.day-print-summary .day-total').textContent(),
- /合计\s*7\s*车次/
- )
- assert.equal(await printFrame.locator('.calendar-controls').count(), 0)
- assert.equal(await printFrame.locator('h1').textContent(), '2026年10月派车日历')
- await page.emulateMedia({ media: 'print' })
- assert.equal(
- await printFrame
- .locator('.day-content')
- .first()
- .evaluate((el) => getComputedStyle(el).maxHeight),
- 'none'
- )
- assert.equal(
- await printFrame
- .locator('.trip-route')
- .first()
- .evaluate((el) => getComputedStyle(el).overflow),
- 'visible'
- )
- await page.emulateMedia({ media: 'screen' })
- await page.evaluate(() =>
- document
- .querySelector('iframe[aria-hidden="true"]')
- .contentWindow.dispatchEvent(new Event('afterprint'))
- )
- assert.equal(await page.locator('iframe[aria-hidden="true"]').count(), 0)
- failNext = true
- await panel.getByRole('button', { name: '刷新', exact: true }).click()
- await panel.getByRole('alert').waitFor()
- assert.equal(await panel.locator('.trip-card').count(), 0)
- await panel.getByRole('button', { name: '重试', exact: true }).click()
- await daily.locator('.plate-number').first().waitFor()
- assert.equal(await panel.locator('.trip-card').count(), 7)
- // 繁忙日保持七天等宽、无横向滚动,车辆卡片按车次数倒序。
- rows.splice(
- 0,
- rows.length,
- ...Array.from({ length: 11 }, (_, index) => ({
- id: `dense-${index}`,
- planNo: `DENSE${index}`,
- planDate: '2026-10-24',
- followStatus: 'pending',
- vehicleId: `dense-v${index % 6}`,
- licensePlate: ['皖H57837', '皖M7A663', '皖H31656', '一票到', '皖AM8516', '皖HA6900'][
- index % 6
- ],
- calendarRoute: '安庆山峡 → 厦门圣益',
- products: [
- {
- productId: `product-${index % 7}`,
- productName: [
- '50% 工业硫酸',
- '30%液碱',
- '氨水',
- '30% 工业硫酸',
- '32%液碱',
- '精制硫酸',
- '98% 工业硫酸'
- ][index % 7]
- }
- ]
- }))
- )
- await page.setViewportSize({ width: 1440, height: 1000 })
- await panel.getByRole('button', { name: '刷新', exact: true }).click()
- await daily.getByText('皖M7A663', { exact: true }).first().waitFor()
- assert.ok(
- await panel.locator('.calendar-scroll').evaluate((el) => el.scrollWidth <= el.clientWidth)
- )
- const widths = await panel
- .locator('.calendar-weekdays span')
- .evaluateAll((nodes) => nodes.map((node) => node.getBoundingClientRect().width))
- assert.equal(widths.length, 7)
- assert.ok(Math.max(...widths) - Math.min(...widths) < 1)
- const actionRow = await daily.locator('.day-vehicle-scope > .el-button').evaluateAll((buttons) =>
- buttons.map((button) => {
- const r = button.getBoundingClientRect()
- return { top: r.top, bottom: r.bottom, right: r.right }
- })
- )
- assert.equal(actionRow.length, 3, '车辆范围、复制在同一行')
- assert.ok(
- await panel.locator('.day-number').evaluateAll((buttons) =>
- buttons.every((button) => {
- const range = document.createRange()
- range.selectNodeContents(button)
- return range.getClientRects().length === 1
- })
- ),
- '两位数日期不换行'
- )
- assert.equal(await daily.locator('.day-heading .day-summary-button').count(), 1)
- assert.ok(
- await daily.locator('.day-heading').evaluate((heading) => {
- const row = heading.getBoundingClientRect()
- const summary = heading.querySelector('.day-summary-button').getBoundingClientRect()
- const date = heading.querySelector('.day-number').getBoundingClientRect()
- const weekday = heading.querySelector('.day-weekday').getBoundingClientRect()
- return (
- Math.abs((row.left + row.right - summary.left - summary.right) / 2) < 1 &&
- date.right <= summary.left &&
- summary.right <= weekday.left
- )
- }),
- '合计在日期标题栏正中间,且不与日期、星期重叠'
- )
- assert.ok(
- actionRow.every(
- (r) => Math.abs(r.top - actionRow[0].top) < 1 && Math.abs(r.bottom - actionRow[0].bottom) < 1
- )
- )
- assert.ok(
- await daily.locator('.day-vehicle-scope').evaluate((el) => el.scrollWidth <= el.clientWidth),
- '操作行不能横向溢出'
- )
- const tripCounts = await daily
- .locator('.vehicle-card')
- .evaluateAll((cards) => cards.map((card) => card.querySelectorAll('.trip-card').length))
- assert.equal(tripCounts.length, 6)
- assert.deepEqual(
- tripCounts,
- [...tripCounts].sort((a, b) => b - a)
- )
- assert.ok(
- await daily
- .locator('.day-content')
- .evaluate(
- (el) => el.scrollHeight <= el.clientHeight && getComputedStyle(el).overflowY === 'visible'
- )
- )
- assert.equal(await daily.locator('.trip-card').count(), 11)
- const weekdayWidths = await panel
- .locator('.calendar-weekdays')
- .evaluate((el) => getComputedStyle(el).gridTemplateColumns)
- assert.equal(
- await panel
- .locator('.calendar-grid')
- .evaluate((el) => getComputedStyle(el).gridTemplateColumns),
- weekdayWidths
- )
- assert.ok(
- await daily
- .locator('.vehicle-card')
- .evaluateAll((cards) => cards.every((card) => card.scrollWidth <= card.clientWidth))
- )
- await page.setViewportSize({ width: 2560, height: 1300 })
- const rowCards = await daily.locator('.vehicle-card').evaluateAll((cards) =>
- cards.map((card) => {
- const rect = card.getBoundingClientRect()
- return { top: rect.top, bottom: rect.bottom }
- })
- )
- for (const card of rowCards) {
- for (const sibling of rowCards.filter((item) => Math.abs(item.top - card.top) < 1))
- assert.ok(Math.abs(sibling.bottom - card.bottom) < 1)
- }
- await daily.screenshot({ path: '/tmp/shanxia-dispatch-calendar-dense.png' })
- await page.screenshot({ path: '/tmp/shanxia-dispatch-calendar-dense-web.png' })
- await page.setViewportSize({ width: 600, height: 1000 })
- assert.ok(
- await panel.locator('.calendar-grid').evaluate((el) => el.scrollWidth <= el.clientWidth)
- )
- const availableWidth = await daily.locator('.day-content').evaluate((el) => el.clientWidth)
- assert.equal(
- await daily
- .locator('.vehicle-grid')
- .evaluate((el) => getComputedStyle(el).gridTemplateColumns.split(' ').length),
- availableWidth >= 420 ? 3 : availableWidth >= 280 ? 2 : 1
- )
- rows.push({ ...rows[0], id: 'dense-duplicate', planNo: 'DENSE-DUP' })
- await page.setViewportSize({ width: 1440, height: 1000 })
- await panel.getByRole('button', { name: '刷新', exact: true }).click()
- const mergedTask = daily.locator('.trip-card').filter({ hasText: '· 2车次' })
- await mergedTask.waitFor()
- assert.equal(await daily.locator('.trip-card').count(), 11)
- assert.match(await mergedTask.getAttribute('title'), /DENSE0/)
- assert.match(await mergedTask.getAttribute('title'), /DENSE-DUP/)
- assert.match(await daily.locator('.day-summary-button').textContent(), /合计\s*12\s*车次/)
- await daily.getByRole('button', { name: '查看2026-10-24货品汇总' }).click()
- const mergedSummary = page.locator('.calendar-summary-popper:visible')
- await mergedSummary.waitFor()
- assert.match(await mergedSummary.locator('.day-total').textContent(), /合计\s*12\s*车次/)
- const productCounts = await mergedSummary.locator('.product-total dd strong').allTextContents()
- assert.equal(
- productCounts.reduce((sum, value) => sum + Number(value), 0),
- 12
- )
- await panel.locator('.title-bar-heading').click()
- await mergedSummary.waitFor({ state: 'hidden' })
- await daily
- .locator('.vehicle-card')
- .first()
- .screenshot({ path: '/tmp/shanxia-calendar-merged-trip.png' })
- // 一计划三送货段,货品和收货方分别对应;相同段再合并,计划车次不膨胀。
- rows.splice(0, rows.length, {
- id: 'multi-stop',
- planNo: 'MULTI',
- planDate: '2026-10-24',
- followStatus: 'pending',
- vehicleId: 'v-multi',
- licensePlate: '皖H21522',
- load: {
- customerId: 'load',
- customerName: '安庆山峡化工有限公司',
- calendarCustomerName: '安庆山峡'
- },
- products: [
- { id: 'pa', productId: 'a', productName: '氯化钠' },
- { id: 'pb', productId: 'b', productName: '次氯酸钠' }
- ],
- deliveries: [
- {
- id: 's1',
- seq: 1,
- customerId: '甲',
- customerName: '甲有限公司',
- calendarCustomerName: '甲',
- products: [{ planProductId: 'pa', productId: 'a', productName: '氯化钠' }]
- },
- {
- id: 's2',
- seq: 2,
- customerId: '乙',
- customerName: '乙有限公司',
- calendarCustomerName: '乙',
- products: [{ planProductId: 'pb', productId: 'b', productName: '次氯酸钠' }]
- },
- {
- id: 's3',
- seq: 3,
- customerId: '丙',
- customerName: '丙有限公司',
- calendarCustomerName: '丙',
- products: [{ planProductId: 'pa', productId: 'a', productName: '氯化钠' }]
- }
- ]
- })
- await panel.getByRole('button', { name: '刷新', exact: true }).click()
- await daily.getByText('皖H21522', { exact: true }).waitFor()
- assert.equal(await daily.locator('.trip-card').count(), 3)
- assert.deepEqual(await daily.locator('.trip-route').allTextContents(), [
- '山峡 → 甲',
- '山峡 → 乙',
- '山峡 → 丙'
- ])
- assert.match(await daily.locator('.day-summary-button').textContent(), /合计\s*1\s*车次/)
- rows[0].deliveries[2].customerId = '甲'
- rows[0].deliveries[2].calendarCustomerName = '甲'
- rows[0].deliveries[2].customerName = '甲有限公司'
- await panel.getByRole('button', { name: '刷新', exact: true }).click()
- await daily.getByText(/2段次/).waitFor()
- assert.equal(await daily.locator('.trip-card').count(), 2)
- assert.match(await daily.locator('.trip-card').first().textContent(), /氯化钠.*1车次.*2段次/)
- assert.match(await daily.locator('.day-summary-button').textContent(), /合计\s*1\s*车次/)
- await daily.getByRole('button', { name: '查看2026-10-24货品汇总' }).click()
- const stopSummary = page.locator('.calendar-summary-popper:visible')
- await stopSummary.waitFor()
- assert.match(await stopSummary.locator('.day-total').textContent(), /合计\s*1\s*车次/)
- assert.deepEqual(await stopSummary.locator('.product-total dd strong').allTextContents(), [
- '1',
- '1'
- ])
- await panel.locator('.title-bar-heading').click()
- await stopSummary.waitFor({ state: 'hidden' })
- await daily.locator('.vehicle-card').screenshot({ path: '/tmp/shanxia-calendar-multi-stop.png' })
- // 每天独立默认自有;全部包含承运商与未知车辆,汇总随当天筛选变化。
- const base = rows[0]
- rows.splice(
- 0,
- rows.length,
- { ...base, id: 'own', vehicleId: 'own', licensePlate: '皖OWN', calendarVehicleType: 'self' },
- {
- ...base,
- id: 'carrier',
- vehicleId: 'carrier',
- licensePlate: '皖OUT',
- calendarVehicleType: 'carrier'
- },
- {
- ...base,
- id: 'unknown',
- vehicleId: 'unknown',
- licensePlate: '皖UNKNOWN',
- calendarVehicleType: 'unknown'
- },
- {
- ...base,
- id: 'other-day',
- planDate: '2026-10-25',
- vehicleId: 'carrier-next',
- licensePlate: '皖NEXT',
- calendarVehicleType: 'carrier'
- }
- )
- await panel.getByRole('button', { name: '刷新', exact: true }).click()
- await daily.getByText('皖OWN', { exact: true }).waitFor()
- assert.equal(await daily.locator('.vehicle-card').count(), 1)
- const nextDay = panel.locator('[data-date="2026-10-25"]')
- assert.equal(await nextDay.locator('.vehicle-card').count(), 0)
- await daily.getByRole('button', { name: '全部', exact: true }).click()
- assert.equal(await daily.locator('.vehicle-card').count(), 3)
- await copyButton.click()
- copiedText = await page.evaluate(() => navigator.clipboard.readText())
- assert.match(copiedText, /皖OUT/)
- assert.match(copiedText, /皖UNKNOWN/)
- assert.ok(!copiedText.includes('皖NEXT'), '只复制点击的日期')
- assert.match(await daily.locator('.day-summary-button').textContent(), /合计\s*3\s*车次/)
- assert.equal(await nextDay.locator('.vehicle-card').count(), 0)
- await daily.getByRole('button', { name: '查看2026-10-24货品汇总' }).click()
- const ownershipSummary = page.locator('.calendar-summary-popper:visible')
- assert.match(await ownershipSummary.locator('.day-total').textContent(), /合计\s*3\s*车次/)
- await panel.locator('.title-bar-heading').click()
- await nextDay.getByRole('button', { name: '全部', exact: true }).click()
- assert.equal(await nextDay.locator('.vehicle-card').count(), 1)
- await daily.getByRole('button', { name: '山峡车辆', exact: true }).click()
- assert.equal(await daily.locator('.vehicle-card').count(), 1)
- assert.equal(await nextDay.locator('.vehicle-card').count(), 1)
- await page.locator('.calendar-weekdays').click()
- await page.locator('.calendar-summary-popper:visible').waitFor({ state: 'hidden' })
- await copyButton.click()
- copiedText = await page.evaluate(() => navigator.clipboard.readText())
- assert.match(copiedText, /皖OWN/)
- assert.ok(
- !copiedText.includes('皖OUT') && !copiedText.includes('皖UNKNOWN'),
- '复制跟随当天自有车辆筛选'
- )
- await page.evaluate(() => {
- window.__copyWrite = navigator.clipboard.writeText.bind(navigator.clipboard)
- window.__copyExec = document.execCommand
- navigator.clipboard.writeText = async () => {
- throw new Error('fixture clipboard denied')
- }
- document.execCommand = () => false
- })
- await copyButton.click()
- await page.getByText('复制失败,请检查浏览器剪贴板权限后重试', { exact: true }).waitFor()
- await page.evaluate(() => {
- navigator.clipboard.writeText = window.__copyWrite
- document.execCommand = window.__copyExec
- })
- await page.screenshot({ path: '/tmp/calendar-copy-web.png' })
- await page.screenshot({ path: '/tmp/calendar-daily-ownership-web.png' })
- assert.deepEqual(errors, [])
- console.log(
- 'PASS: 日历加载、权限路由、相同任务合并且总车次不变、货品统计弹出、日格无独立滚动、车辆筛选、客户简称和蓝色配色、重置、切月、日期定位、七天无横向溢出、车辆车次排序、同排对齐和窄屏布局、隔离打印和错误重试。'
- )
- } catch (error) {
- console.error('PAGE:', await page.locator('body').innerText())
- console.error('ERRORS:', errors)
- console.error(
- 'ROUTES:',
- await page.evaluate(() =>
- document
- .querySelector('#app')
- ?.__vue_app__?.config.globalProperties.$router?.getRoutes()
- .filter((r) => r.path.startsWith('/pl'))
- .map((r) => ({ name: r.name, path: r.path }))
- )
- )
- await page.screenshot({ path: '/tmp/shanxia-dispatch-calendar-failure.png' })
- throw error
- } finally {
- await browser.close()
- }
|