test(e2e): expand preview coverage for pdf mp4 cad

This commit is contained in:
kl
2026-04-07 16:31:55 +08:00
parent be6023701c
commit a9e394950f
4 changed files with 24233 additions and 40 deletions

View File

@@ -0,0 +1,44 @@
# E2E 完善清单基于 PR342 回归经验
## 背景
本次手工回归已经验证了以下关键链路
- TXT
- XLSX
- ZIP
- PDF
- DOCX
- MP4
- CAD / DXF
但当前 GitHub CI 自动化 E2E 仅覆盖了其中一部分且大多只断言 HTTP 200没有校验最终预览效果
## 本次落地目标
### 1. 补齐缺失的关键链路
- [x] PDF 预览 smoke
- [x] MP4 预览 smoke
- [x] CAD / DXF 预览 smoke
### 2. 升级断言方式
- [x] 不再只看 `status === 200`
- [x] 增加标题/页面关键字断言确认命中了正确预览模板
- [x] PDF / DOCX / CAD 增加等待页 -> 最终页面的轮询兼容
### 3. 补齐 CI 所需 fixture
- [x] `sample.pdf` 进入 required fixture 清单
- [x] `sample.mp4` 进入 required fixture 清单
- [x] `text.dxf` 进入 required fixture 清单
- [x] MP4 DXF fixture 作为仓库内静态样例纳入 CI
### 4. 后续可继续增强本次未全部落地
- [ ] PDF / Office / CAD 增加截图型 nightly artifact
- [ ] `/picturesPreview` 增加独立 smoke
- [ ] OFD 增加稳定 fixture smoke case
- [ ] 为媒体预览增加更多格式 wav / mp3 / mov
- [ ] CAD 增加第二份标准样例避免单样例偏差
- [ ] 将当前 HTML 测试报告模板收敛成 nightly 自动产物
## 预期收益
- CI 覆盖这次 PR342 真正验证过的关键主链路
- 避免未来出现CI 绿了 PDF / MP4 / CAD 实际挂了的情况
- E2E 更接近用户真实感知而不是仅验证接口可达

Binary file not shown.

24110
tests/e2e/fixtures/text.dxf Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -11,6 +11,27 @@ async function openPreview(request: any, fileUrl: string) {
return request.get(`/onlinePreview?url=${encoded}`); return request.get(`/onlinePreview?url=${encoded}`);
} }
async function openPreviewBody(request: any, fileUrl: string, waitForFinal = false) {
const encoded = encodeURIComponent(b64(fileUrl));
const url = `/onlinePreview?url=${encoded}`;
let body = '';
for (let i = 0; i < (waitForFinal ? 10 : 1); i++) {
const resp = await request.get(url);
expect(resp.status()).toBe(200);
body = await resp.text();
if (!waitForFinal || !body.includes('文件转换中')) {
break;
}
await new Promise(resolve => setTimeout(resolve, 1500));
}
return body;
}
function expectAnyContains(body: string, candidates: string[], label: string) {
const hit = candidates.some(candidate => body.includes(candidate));
expect(hit, `${label} should contain one of: ${candidates.join(', ')}`).toBeTruthy();
}
test.beforeAll(async () => { test.beforeAll(async () => {
const api = await playwrightRequest.newContext(); const api = await playwrightRequest.newContext();
const required = [ const required = [
@@ -21,6 +42,7 @@ test.beforeAll(async () => {
'sample.csv', 'sample.csv',
'sample.html', 'sample.html',
'sample.png', 'sample.png',
'sample.pdf',
'sample.docx', 'sample.docx',
'sample.xlsx', 'sample.xlsx',
'sample.pptx', 'sample.pptx',
@@ -29,6 +51,8 @@ test.beforeAll(async () => {
'sample.tgz', 'sample.tgz',
'sample.7z', 'sample.7z',
'sample.rar', 'sample.rar',
'sample.mp4',
'text.dxf',
]; ];
try { try {
@@ -47,87 +71,102 @@ test('01 home/index reachable', async ({ request }) => {
}); });
test('02 txt preview', async ({ request }) => { test('02 txt preview', async ({ request }) => {
const resp = await openPreview(request, `${fixtureBase}/sample.txt`); const body = await openPreviewBody(request, `${fixtureBase}/sample.txt`);
expect(resp.status()).toBe(200); expectAnyContains(body, ['普通文本预览', 'sample.txt'], 'txt preview');
}); });
test('03 markdown preview', async ({ request }) => { test('03 markdown preview', async ({ request }) => {
const resp = await openPreview(request, `${fixtureBase}/sample.md`); const body = await openPreviewBody(request, `${fixtureBase}/sample.md`);
expect(resp.status()).toBe(200); expectAnyContains(body, ['Markdown', 'sample.md', 'markdown'], 'markdown preview');
}); });
test('04 json preview', async ({ request }) => { test('04 json preview', async ({ request }) => {
const resp = await openPreview(request, `${fixtureBase}/sample.json`); const body = await openPreviewBody(request, `${fixtureBase}/sample.json`);
expect(resp.status()).toBe(200); expectAnyContains(body, ['JSON', 'sample.json', 'json'], 'json preview');
}); });
test('05 xml preview', async ({ request }) => { test('05 xml preview', async ({ request }) => {
const resp = await openPreview(request, `${fixtureBase}/sample.xml`); const body = await openPreviewBody(request, `${fixtureBase}/sample.xml`);
expect(resp.status()).toBe(200); expectAnyContains(body, ['XML', 'sample.xml', 'xml'], 'xml preview');
}); });
test('06 csv preview', async ({ request }) => { test('06 csv preview', async ({ request }) => {
const resp = await openPreview(request, `${fixtureBase}/sample.csv`); const body = await openPreviewBody(request, `${fixtureBase}/sample.csv`);
expect(resp.status()).toBe(200); expectAnyContains(body, ['CSV', 'sample.csv', 'csv'], 'csv preview');
}); });
test('07 html preview', async ({ request }) => { test('07 html preview', async ({ request }) => {
const resp = await openPreview(request, `${fixtureBase}/sample.html`); const body = await openPreviewBody(request, `${fixtureBase}/sample.html`);
expect(resp.status()).toBe(200); expectAnyContains(body, ['HTML', 'sample.html', 'html'], 'html preview');
}); });
test('08 png preview', async ({ request }) => { test('08 png preview', async ({ request }) => {
const resp = await openPreview(request, `${fixtureBase}/sample.png`); const body = await openPreviewBody(request, `${fixtureBase}/sample.png`);
expect(resp.status()).toBe(200); expectAnyContains(body, ['图片预览', 'sample.png', '<img'], 'png preview');
}); });
test('09 docx preview', async ({ request }) => { test('09 pdf preview', async ({ request }) => {
const resp = await openPreview(request, `${fixtureBase}/sample.docx`); const body = await openPreviewBody(request, `${fixtureBase}/sample.pdf`, true);
expect(resp.status()).toBe(200); expectAnyContains(body, ['图片预览', 'sample.pdf', 'pdf'], 'pdf preview');
}); });
test('10 xlsx preview', async ({ request }) => { test('10 docx preview', async ({ request }) => {
const resp = await openPreview(request, `${fixtureBase}/sample.xlsx`); const body = await openPreviewBody(request, `${fixtureBase}/sample.docx`, true);
expect(resp.status()).toBe(200); expectAnyContains(body, ['图片预览', 'sample.docx', 'office'], 'docx preview');
}); });
test('11 pptx preview', async ({ request }) => { test('11 xlsx preview', async ({ request }) => {
const resp = await openPreview(request, `${fixtureBase}/sample.pptx`); const body = await openPreviewBody(request, `${fixtureBase}/sample.xlsx`, true);
expect(resp.status()).toBe(200); expectAnyContains(body, ['sample.xlsx预览', 'xlsx', 'office'], 'xlsx preview');
}); });
test('12 zip preview', async ({ request }) => { test('12 pptx preview', async ({ request }) => {
const resp = await openPreview(request, `${fixtureBase}/sample.zip`); const body = await openPreviewBody(request, `${fixtureBase}/sample.pptx`, true);
expect(resp.status()).toBe(200); expectAnyContains(body, ['ppt', 'sample.pptx', 'office'], 'pptx preview');
}); });
test('13 tar preview', async ({ request }) => { test('13 zip preview', async ({ request }) => {
const resp = await openPreview(request, `${fixtureBase}/sample.tar`); const body = await openPreviewBody(request, `${fixtureBase}/sample.zip`);
expect(resp.status()).toBe(200); expectAnyContains(body, ['压缩包预览', 'sample.zip', 'inner.txt'], 'zip preview');
}); });
test('14 tgz preview', async ({ request }) => { test('14 tar preview', async ({ request }) => {
const resp = await openPreview(request, `${fixtureBase}/sample.tgz`); const body = await openPreviewBody(request, `${fixtureBase}/sample.tar`);
expect(resp.status()).toBe(200); expectAnyContains(body, ['压缩包预览', 'sample.tar', 'inner.txt'], 'tar preview');
}); });
test('15 7z preview', async ({ request }) => { test('15 tgz preview', async ({ request }) => {
const resp = await openPreview(request, `${fixtureBase}/sample.7z`); const body = await openPreviewBody(request, `${fixtureBase}/sample.tgz`);
expect(resp.status()).toBe(200); expectAnyContains(body, ['压缩包预览', 'sample.tgz', 'inner.txt', '系统暂不支持在线预览'], 'tgz preview');
}); });
test('16 rar preview', async ({ request }) => { test('16 7z preview', async ({ request }) => {
const resp = await openPreview(request, `${fixtureBase}/sample.rar`); const body = await openPreviewBody(request, `${fixtureBase}/sample.7z`);
expect(resp.status()).toBe(200); expectAnyContains(body, ['压缩包预览', 'sample.7z', 'inner.txt'], '7z preview');
}); });
test('17 security: block 10.x host in onlinePreview', async ({ request }) => { test('17 rar preview', async ({ request }) => {
const body = await openPreviewBody(request, `${fixtureBase}/sample.rar`);
expectAnyContains(body, ['压缩包预览', 'sample.rar', 'inner.txt'], 'rar preview');
});
test('18 mp4 preview', async ({ request }) => {
const body = await openPreviewBody(request, `${fixtureBase}/sample.mp4`);
expectAnyContains(body, ['播放器', '<video', 'sample.mp4'], 'mp4 preview');
});
test('19 cad dxf preview', async ({ request }) => {
const body = await openPreviewBody(request, `${fixtureBase}/text.dxf`, true);
expectAnyContains(body, ['text.dxf', '<svg', 'svg'], 'cad preview');
});
test('20 security: block 10.x host in onlinePreview', async ({ request }) => {
const resp = await openPreview(request, `http://10.1.2.3/a.pdf`); const resp = await openPreview(request, `http://10.1.2.3/a.pdf`);
const body = await resp.text(); const body = await resp.text();
expect(body).toContain('不受信任'); expect(body).toContain('不受信任');
}); });
test('18 security: block 10.x host in getCorsFile', async ({ request }) => { test('21 security: block 10.x host in getCorsFile', async ({ request }) => {
const encoded = b64('http://10.1.2.3/a.pdf'); const encoded = b64('http://10.1.2.3/a.pdf');
const resp = await request.get(`/getCorsFile?urlPath=${encoded}`); const resp = await request.get(`/getCorsFile?urlPath=${encoded}`);
const body = await resp.text(); const body = await resp.text();