104 lines
4.0 KiB
JavaScript
104 lines
4.0 KiB
JavaScript
import assert from 'node:assert/strict'
|
|
import { chromium } from 'playwright'
|
|
import { installCertFixture } from './mp-pl-plan-cert-fixture.mjs'
|
|
|
|
// 挂载真实 Web 弹窗与附件组件,仅替换 API 边界,不写入业务数据库。
|
|
const origin = process.env.PLAN_CERT_TEST_ORIGIN || 'http://localhost:3006'
|
|
const browser = await chromium.launch({ headless: true, channel: 'chrome' })
|
|
const context = await browser.newContext({ viewport: { width: 1440, height: 1000 } })
|
|
const fixture = await installCertFixture(context)
|
|
const page = await context.newPage()
|
|
const errors = []
|
|
page.on('pageerror', (error) => errors.push(error.message))
|
|
page.setDefaultTimeout(15000)
|
|
let releaseUpload
|
|
const saves = () =>
|
|
fixture.calls.filter((c) => c.method === 'PATCH' && c.path.endsWith('/product-certs'))
|
|
try {
|
|
await page.goto(`${origin}/#/m/pl/plan-cert?mpTicket=cert-fixture`)
|
|
await page.getByText('YS001', { exact: true }).first().waitFor()
|
|
await page.evaluate(async () => {
|
|
const { createVNode, render, defineComponent, ref, h } = await import(
|
|
'/node_modules/.vite/deps/vue.js'
|
|
)
|
|
const { default: Dialog } = await import(
|
|
'/src/components/business/pl-plan-cert-upload-dialog/index.vue'
|
|
)
|
|
const host = document.createElement('div')
|
|
document.body.appendChild(host)
|
|
const Wrapper = defineComponent({
|
|
setup() {
|
|
const visible = ref(true)
|
|
return () => [
|
|
h(
|
|
'button',
|
|
{
|
|
id: 'reopen-web-cert',
|
|
onClick: () => {
|
|
visible.value = true
|
|
}
|
|
},
|
|
'重新打开 Web 证书'
|
|
),
|
|
h(Dialog, {
|
|
visible: visible.value,
|
|
planId: 'plan-1',
|
|
'onUpdate:visible': (v) => {
|
|
visible.value = v
|
|
}
|
|
})
|
|
]
|
|
}
|
|
})
|
|
const vnode = createVNode(Wrapper)
|
|
vnode.appContext = document.querySelector('#app').__vue_app__._context
|
|
render(vnode, host)
|
|
})
|
|
const dialog = page.getByRole('dialog').filter({ hasText: '上传危化品证书' })
|
|
await dialog.getByText('测试易制毒产品', { exact: true }).waitFor()
|
|
assert.equal(await dialog.locator('input[type="file"]').count(), 3)
|
|
// 使用最后一个产品的附件,确保保护覆盖所有嵌套循环中的上传组件。
|
|
fixture.uploadGate = new Promise((resolve) => {
|
|
releaseUpload = resolve
|
|
})
|
|
await dialog
|
|
.locator('input[type="file"]')
|
|
.last()
|
|
.setInputFiles({
|
|
name: 'legal-cert.pdf',
|
|
mimeType: 'application/pdf',
|
|
buffer: Buffer.from('%PDF-1.4\nfixture')
|
|
})
|
|
await dialog.locator('.is-uploading').waitFor()
|
|
await dialog.getByRole('button', { name: '保存', exact: true }).click()
|
|
// toast 表明真实处理函数已完成,不以固定等待推断没有请求。
|
|
await page
|
|
.getByText(/^(附件正在上传,请稍候再保存|证书保存成功)$/)
|
|
.first()
|
|
.waitFor()
|
|
assert.equal(saves().length, 0, '附件未上传完成时不能提交旧 URL')
|
|
assert.equal(
|
|
await page.getByText('附件正在上传,请稍候再保存', { exact: true }).isVisible(),
|
|
true
|
|
)
|
|
assert.equal(await dialog.isVisible(), true)
|
|
releaseUpload()
|
|
await dialog.locator('.is-uploading').waitFor({ state: 'hidden' })
|
|
await dialog.getByRole('button', { name: '保存', exact: true }).click()
|
|
await dialog.waitFor({ state: 'hidden' })
|
|
assert.equal(saves().length, 1)
|
|
assert.ok(JSON.stringify(saves()[0].body).includes('/fixtures/cert.pdf'))
|
|
// 关闭销毁后重新打开,不遗留上传引用;正常保存仍可用。
|
|
await page.locator('#reopen-web-cert').click()
|
|
await dialog.getByText('测试易制毒产品', { exact: true }).waitFor()
|
|
await dialog.getByRole('button', { name: '保存', exact: true }).click()
|
|
await dialog.waitFor({ state: 'hidden' })
|
|
assert.equal(saves().length, 2)
|
|
assert.deepEqual(errors, [])
|
|
assert.deepEqual(fixture.unknown, [])
|
|
console.log('PASS: Web 附件上传中阻止保存、上传后提交新 URL、销毁重开正常保存')
|
|
} finally {
|
|
releaseUpload?.()
|
|
await browser.close()
|
|
}
|