first commit
This commit is contained in:
@@ -0,0 +1,9 @@
|
||||
node_modules/
|
||||
playwright-report/
|
||||
test-results/
|
||||
|
||||
__pycache__/
|
||||
fixtures/archive-tmp/
|
||||
fixtures/sample.docx
|
||||
fixtures/sample.xlsx
|
||||
fixtures/sample.pptx
|
||||
@@ -0,0 +1,69 @@
|
||||
# kkFileView E2E MVP
|
||||
|
||||
This folder contains a first MVP of end-to-end automated tests.
|
||||
|
||||
## What is covered
|
||||
|
||||
- Basic preview smoke checks for common file types (txt/md/json/xml/csv/html/png)
|
||||
- Office Phase-2 smoke checks (docx/xlsx/pptx)
|
||||
- Archive smoke checks (zip/tar/tgz/7z/rar)
|
||||
- Basic endpoint reachability
|
||||
- Security regression checks for blocked internal-network hosts (`10.*`) on:
|
||||
- `/onlinePreview`
|
||||
- `/getCorsFile`
|
||||
- Basic performance smoke checks (configurable threshold): txt/docx/xlsx preview response time
|
||||
- CI combined run command available via `npm run test:ci`
|
||||
|
||||
## Local run
|
||||
|
||||
1. Build server jar:
|
||||
|
||||
```bash
|
||||
mvn -q -pl server -DskipTests package
|
||||
```
|
||||
|
||||
2. Install deps + browser:
|
||||
|
||||
```bash
|
||||
cd tests/e2e
|
||||
npm install
|
||||
npx playwright install --with-deps chromium
|
||||
pip3 install -r requirements.txt
|
||||
```
|
||||
|
||||
> Prerequisite: ensure `python3`, `zip`, and `7z` (or `bsdtar` as a fallback) are available in PATH for archive fixtures.
|
||||
|
||||
3. Generate fixtures and start fixture server:
|
||||
|
||||
```bash
|
||||
cd /path/to/kkFileView
|
||||
npm run gen:all
|
||||
cd tests/e2e/fixtures && python3 -m http.server 18080
|
||||
```
|
||||
|
||||
4. Start kkFileView in another terminal:
|
||||
|
||||
```bash
|
||||
JAR_PATH=$(ls server/target/kkFileView-*.jar | head -n 1)
|
||||
KK_TRUST_HOST='*' KK_NOT_TRUST_HOST='10.*,172.16.*,192.168.*' java -jar "$JAR_PATH"
|
||||
```
|
||||
|
||||
5. Run tests:
|
||||
|
||||
```bash
|
||||
cd tests/e2e
|
||||
KK_BASE_URL=http://127.0.0.1:8012 FIXTURE_BASE_URL=http://127.0.0.1:18080 npm test
|
||||
```
|
||||
|
||||
Optional:
|
||||
|
||||
```bash
|
||||
# smoke only (self-contained: will auto-generate fixtures)
|
||||
npm run test:smoke
|
||||
|
||||
# perf smoke (self-contained; default threshold 15000ms)
|
||||
E2E_MAX_PREVIEW_MS=15000 npm run test:perf
|
||||
|
||||
# CI-style combined run (single fixture generation)
|
||||
E2E_MAX_PREVIEW_MS=20000 npm run test:ci
|
||||
```
|
||||
Binary file not shown.
@@ -0,0 +1,3 @@
|
||||
name,value
|
||||
kkFileView,1
|
||||
e2e,1
|
||||
|
@@ -0,0 +1 @@
|
||||
<!doctype html><html><body><h1>kkFileView fixture</h1></body></html>
|
||||
@@ -0,0 +1,4 @@
|
||||
{
|
||||
"app": "kkFileView",
|
||||
"e2e": true
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
# kkFileView
|
||||
|
||||
This is a markdown fixture.
|
||||
Binary file not shown.
@@ -0,0 +1,19 @@
|
||||
%PDF-1.1
|
||||
1 0 obj<< /Type /Catalog /Pages 2 0 R >>endobj
|
||||
2 0 obj<< /Type /Pages /Kids [3 0 R] /Count 1 >>endobj
|
||||
3 0 obj<< /Type /Page /Parent 2 0 R /MediaBox [0 0 200 200] /Contents 4 0 R >>endobj
|
||||
4 0 obj<< /Length 44 >>stream
|
||||
BT /F1 12 Tf 72 120 Td (kkFileView e2e pdf) Tj ET
|
||||
endstream
|
||||
endobj
|
||||
xref
|
||||
0 5
|
||||
0000000000 65535 f
|
||||
0000000010 00000 n
|
||||
0000000060 00000 n
|
||||
0000000117 00000 n
|
||||
0000000212 00000 n
|
||||
trailer<< /Root 1 0 R /Size 5 >>
|
||||
startxref
|
||||
306
|
||||
%%EOF
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 68 B |
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -0,0 +1 @@
|
||||
kkFileView e2e sample text
|
||||
@@ -0,0 +1 @@
|
||||
<root><name>kkFileView</name><e2e>true</e2e></root>
|
||||
Binary file not shown.
File diff suppressed because it is too large
Load Diff
Generated
+78
@@ -0,0 +1,78 @@
|
||||
{
|
||||
"name": "kkfileview-e2e",
|
||||
"version": "0.1.0",
|
||||
"lockfileVersion": 3,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "kkfileview-e2e",
|
||||
"version": "0.1.0",
|
||||
"devDependencies": {
|
||||
"@playwright/test": "^1.55.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@playwright/test": {
|
||||
"version": "1.58.2",
|
||||
"resolved": "https://registry.npmjs.org/@playwright/test/-/test-1.58.2.tgz",
|
||||
"integrity": "sha512-akea+6bHYBBfA9uQqSYmlJXn61cTa+jbO87xVLCWbTqbWadRVmhxlXATaOjOgcBaWU4ePo0wB41KMFv3o35IXA==",
|
||||
"dev": true,
|
||||
"license": "Apache-2.0",
|
||||
"dependencies": {
|
||||
"playwright": "1.58.2"
|
||||
},
|
||||
"bin": {
|
||||
"playwright": "cli.js"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
}
|
||||
},
|
||||
"node_modules/fsevents": {
|
||||
"version": "2.3.2",
|
||||
"resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz",
|
||||
"integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==",
|
||||
"dev": true,
|
||||
"hasInstallScript": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"darwin"
|
||||
],
|
||||
"engines": {
|
||||
"node": "^8.16.0 || ^10.6.0 || >=11.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/playwright": {
|
||||
"version": "1.58.2",
|
||||
"resolved": "https://registry.npmjs.org/playwright/-/playwright-1.58.2.tgz",
|
||||
"integrity": "sha512-vA30H8Nvkq/cPBnNw4Q8TWz1EJyqgpuinBcHET0YVJVFldr8JDNiU9LaWAE1KqSkRYazuaBhTpB5ZzShOezQ6A==",
|
||||
"dev": true,
|
||||
"license": "Apache-2.0",
|
||||
"dependencies": {
|
||||
"playwright-core": "1.58.2"
|
||||
},
|
||||
"bin": {
|
||||
"playwright": "cli.js"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
},
|
||||
"optionalDependencies": {
|
||||
"fsevents": "2.3.2"
|
||||
}
|
||||
},
|
||||
"node_modules/playwright-core": {
|
||||
"version": "1.58.2",
|
||||
"resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.58.2.tgz",
|
||||
"integrity": "sha512-yZkEtftgwS8CsfYo7nm0KE8jsvm6i/PTgVtB8DL726wNf6H2IMsDuxCpJj59KDaxCtSnrWan2AeDqM7JBaultg==",
|
||||
"dev": true,
|
||||
"license": "Apache-2.0",
|
||||
"bin": {
|
||||
"playwright-core": "cli.js"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
{
|
||||
"name": "kkfileview-e2e",
|
||||
"private": true,
|
||||
"version": "0.1.0",
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"gen:fixtures": "node ./scripts/generate-fixtures.mjs",
|
||||
"gen:office": "python3 ./scripts/generate-office-fixtures.py",
|
||||
"gen:all": "npm run gen:fixtures && npm run gen:office",
|
||||
"pretest": "npm run gen:all",
|
||||
"test": "playwright test",
|
||||
"test:headed": "playwright test --headed",
|
||||
"pretest:smoke": "npm run gen:all",
|
||||
"test:smoke": "playwright test specs/preview-smoke.spec.ts",
|
||||
"pretest:perf": "npm run gen:all",
|
||||
"test:perf": "playwright test specs/perf-smoke.spec.ts",
|
||||
"test:ci": "npm run gen:all && playwright test specs/preview-smoke.spec.ts specs/perf-smoke.spec.ts"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@playwright/test": "^1.55.0"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
import { defineConfig } from '@playwright/test';
|
||||
|
||||
export default defineConfig({
|
||||
testDir: './specs',
|
||||
timeout: 30_000,
|
||||
expect: { timeout: 10_000 },
|
||||
retries: process.env.CI ? 1 : 0,
|
||||
reporter: [['list'], ['html', { outputFolder: 'playwright-report', open: 'never' }]],
|
||||
use: {
|
||||
baseURL: process.env.KK_BASE_URL || 'http://127.0.0.1:8012',
|
||||
trace: 'on-first-retry',
|
||||
},
|
||||
});
|
||||
@@ -0,0 +1,3 @@
|
||||
python-docx==1.1.2
|
||||
openpyxl==3.1.5
|
||||
python-pptx==1.0.2
|
||||
@@ -0,0 +1,130 @@
|
||||
import fs from 'node:fs';
|
||||
import path from 'node:path';
|
||||
import { execFileSync } from 'node:child_process';
|
||||
import { fileURLToPath } from 'node:url';
|
||||
|
||||
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
||||
const fixturesDir = path.resolve(__dirname, '..', 'fixtures');
|
||||
fs.mkdirSync(fixturesDir, { recursive: true });
|
||||
|
||||
const write = (name, content) => fs.writeFileSync(path.join(fixturesDir, name), content);
|
||||
|
||||
write('sample.txt', 'kkFileView e2e sample text');
|
||||
write('sample.md', '# kkFileView\n\nThis is a markdown fixture.');
|
||||
write('sample.json', JSON.stringify({ app: 'kkFileView', e2e: true }, null, 2));
|
||||
write('sample.xml', '<root><name>kkFileView</name><e2e>true</e2e></root>');
|
||||
write('sample.csv', 'name,value\nkkFileView,1\ne2e,1\n');
|
||||
write('sample.html', '<!doctype html><html><body><h1>kkFileView fixture</h1></body></html>');
|
||||
|
||||
// archive fixtures (contains inner.txt) - generate if missing
|
||||
const archiveWork = path.join(fixturesDir, 'archive-tmp');
|
||||
fs.mkdirSync(archiveWork, { recursive: true });
|
||||
const innerFile = path.join(archiveWork, 'inner.txt');
|
||||
fs.writeFileSync(innerFile, 'kkFileView archive inner file');
|
||||
|
||||
const ensureArchive = (name, generator) => {
|
||||
const out = path.join(fixturesDir, name);
|
||||
if (fs.existsSync(out)) return;
|
||||
try {
|
||||
generator(out);
|
||||
} catch (err) {
|
||||
try {
|
||||
fs.rmSync(out, { force: true });
|
||||
} catch {
|
||||
// ignore cleanup errors; original error will be rethrown
|
||||
}
|
||||
throw err;
|
||||
}
|
||||
};
|
||||
|
||||
const buildDeterministicTar = (out, gzip = false) => {
|
||||
const py = String.raw`import io, tarfile, gzip
|
||||
from pathlib import Path
|
||||
|
||||
out = Path(r'''${out}''')
|
||||
inner_path = Path(r'''${innerFile}''')
|
||||
data = inner_path.read_bytes()
|
||||
use_gzip = ${gzip ? 'True' : 'False'}
|
||||
|
||||
if use_gzip:
|
||||
with out.open('wb') as f:
|
||||
with gzip.GzipFile(filename='', mode='wb', fileobj=f, mtime=0) as gz:
|
||||
with tarfile.open(fileobj=gz, mode='w', format=tarfile.USTAR_FORMAT) as tf:
|
||||
info = tarfile.TarInfo('inner.txt')
|
||||
info.size = len(data)
|
||||
info.mtime = 946684800 # 2000-01-01 00:00:00 UTC
|
||||
info.uid = 0
|
||||
info.gid = 0
|
||||
info.uname = 'root'
|
||||
info.gname = 'root'
|
||||
tf.addfile(info, io.BytesIO(data))
|
||||
else:
|
||||
with tarfile.open(out, mode='w', format=tarfile.USTAR_FORMAT) as tf:
|
||||
info = tarfile.TarInfo('inner.txt')
|
||||
info.size = len(data)
|
||||
info.mtime = 946684800 # 2000-01-01 00:00:00 UTC
|
||||
info.uid = 0
|
||||
info.gid = 0
|
||||
info.uname = 'root'
|
||||
info.gname = 'root'
|
||||
tf.addfile(info, io.BytesIO(data))
|
||||
`;
|
||||
execFileSync('python3', ['-c', py]);
|
||||
};
|
||||
|
||||
try {
|
||||
ensureArchive('sample.zip', out => {
|
||||
execFileSync('zip', ['-X', '-q', '-r', out, 'inner.txt'], { cwd: archiveWork });
|
||||
});
|
||||
|
||||
ensureArchive('sample.tar', out => {
|
||||
buildDeterministicTar(out, false);
|
||||
});
|
||||
|
||||
ensureArchive('sample.tgz', out => {
|
||||
buildDeterministicTar(out, true);
|
||||
});
|
||||
|
||||
ensureArchive('sample.7z', out => {
|
||||
try {
|
||||
execFileSync('7z', ['a', '-bd', '-y', '-mtc=off', '-mta=off', '-mtm=off', out, 'inner.txt'], {
|
||||
cwd: archiveWork,
|
||||
});
|
||||
} catch (err) {
|
||||
if (err && typeof err === 'object' && 'code' in err && err.code === 'ENOENT') {
|
||||
execFileSync('bsdtar', ['-a', '-cf', out, 'inner.txt'], { cwd: archiveWork });
|
||||
} else {
|
||||
throw err;
|
||||
}
|
||||
}
|
||||
});
|
||||
} catch (err) {
|
||||
console.error('Failed to create archive fixtures. Ensure python3, zip, 7z (or bsdtar) are available in PATH.');
|
||||
throw err instanceof Error ? err : new Error(String(err));
|
||||
} finally {
|
||||
fs.rmSync(archiveWork, { recursive: true, force: true });
|
||||
}
|
||||
|
||||
const rarFixture = path.join(fixturesDir, 'sample.rar');
|
||||
if (!fs.existsSync(rarFixture)) {
|
||||
throw new Error(
|
||||
'Missing required fixture tests/e2e/fixtures/sample.rar. Restore it from git (e.g. `git checkout -- tests/e2e/fixtures/sample.rar`) before running e2e.'
|
||||
);
|
||||
}
|
||||
|
||||
// 1x1 png
|
||||
write(
|
||||
'sample.png',
|
||||
Buffer.from(
|
||||
'iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAAC0lEQVR42mP8/x8AAwMCAO7Zx1sAAAAASUVORK5CYII=',
|
||||
'base64'
|
||||
)
|
||||
);
|
||||
|
||||
// tiny valid pdf
|
||||
write(
|
||||
'sample.pdf',
|
||||
`%PDF-1.1\n1 0 obj<< /Type /Catalog /Pages 2 0 R >>endobj\n2 0 obj<< /Type /Pages /Kids [3 0 R] /Count 1 >>endobj\n3 0 obj<< /Type /Page /Parent 2 0 R /MediaBox [0 0 200 200] /Contents 4 0 R >>endobj\n4 0 obj<< /Length 44 >>stream\nBT /F1 12 Tf 72 120 Td (kkFileView e2e pdf) Tj ET\nendstream\nendobj\nxref\n0 5\n0000000000 65535 f \n0000000010 00000 n \n0000000060 00000 n \n0000000117 00000 n \n0000000212 00000 n \ntrailer<< /Root 1 0 R /Size 5 >>\nstartxref\n306\n%%EOF\n`
|
||||
);
|
||||
|
||||
console.log('fixtures generated in', fixturesDir);
|
||||
@@ -0,0 +1,35 @@
|
||||
#!/usr/bin/env python3
|
||||
from pathlib import Path
|
||||
|
||||
from docx import Document
|
||||
from openpyxl import Workbook
|
||||
from pptx import Presentation
|
||||
|
||||
fixtures = Path(__file__).resolve().parent.parent / "fixtures"
|
||||
fixtures.mkdir(parents=True, exist_ok=True)
|
||||
|
||||
# DOCX
|
||||
_doc = Document()
|
||||
_doc.add_heading("kkFileView E2E", level=1)
|
||||
_doc.add_paragraph("This is a DOCX fixture for Phase-2 E2E.")
|
||||
_doc.save(fixtures / "sample.docx")
|
||||
|
||||
# XLSX
|
||||
_wb = Workbook()
|
||||
_ws = _wb.active
|
||||
_ws.title = "Sheet1"
|
||||
_ws["A1"] = "name"
|
||||
_ws["B1"] = "value"
|
||||
_ws["A2"] = "kkFileView"
|
||||
_ws["B2"] = 2
|
||||
_wb.save(fixtures / "sample.xlsx")
|
||||
|
||||
# PPTX
|
||||
_prs = Presentation()
|
||||
slide_layout = _prs.slide_layouts[1]
|
||||
slide = _prs.slides.add_slide(slide_layout)
|
||||
slide.shapes.title.text = "kkFileView E2E"
|
||||
slide.placeholders[1].text = "This is a PPTX fixture for Phase-2 E2E."
|
||||
_prs.save(fixtures / "sample.pptx")
|
||||
|
||||
print("office fixtures generated in", fixtures)
|
||||
@@ -0,0 +1,49 @@
|
||||
import { test, expect, request as playwrightRequest } from '@playwright/test';
|
||||
import type { APIRequestContext } from '@playwright/test';
|
||||
|
||||
const fixtureBase = process.env.FIXTURE_BASE_URL || 'http://127.0.0.1:18080';
|
||||
const DEFAULT_MAX_MS = 15000;
|
||||
const envMaxMs = Number(process.env.E2E_MAX_PREVIEW_MS);
|
||||
const maxMs = Number.isFinite(envMaxMs) && envMaxMs >= 1 ? Math.floor(envMaxMs) : DEFAULT_MAX_MS;
|
||||
|
||||
function b64(v: string): string {
|
||||
return Buffer.from(v).toString('base64');
|
||||
}
|
||||
|
||||
async function timedPreview(request: APIRequestContext, fileUrl: string) {
|
||||
const started = Date.now();
|
||||
const resp = await request.get(`/onlinePreview?url=${encodeURIComponent(b64(fileUrl))}`);
|
||||
const elapsed = Date.now() - started;
|
||||
return { resp, elapsed };
|
||||
}
|
||||
|
||||
test.beforeAll(async () => {
|
||||
const api = await playwrightRequest.newContext();
|
||||
const required = ['sample.txt', 'sample.docx', 'sample.xlsx'];
|
||||
try {
|
||||
for (const name of required) {
|
||||
const resp = await api.get(`${fixtureBase}/${name}`);
|
||||
expect(resp.ok(), `fixture missing or unavailable: ${name}`).toBeTruthy();
|
||||
}
|
||||
} finally {
|
||||
await api.dispose();
|
||||
}
|
||||
});
|
||||
|
||||
test('perf: txt preview response under threshold', async ({ request }) => {
|
||||
const { resp, elapsed } = await timedPreview(request, `${fixtureBase}/sample.txt`);
|
||||
expect(resp.status()).toBe(200);
|
||||
expect(elapsed).toBeLessThan(maxMs);
|
||||
});
|
||||
|
||||
test('perf: docx preview response under threshold', async ({ request }) => {
|
||||
const { resp, elapsed } = await timedPreview(request, `${fixtureBase}/sample.docx`);
|
||||
expect(resp.status()).toBe(200);
|
||||
expect(elapsed).toBeLessThan(maxMs);
|
||||
});
|
||||
|
||||
test('perf: xlsx preview response under threshold', async ({ request }) => {
|
||||
const { resp, elapsed } = await timedPreview(request, `${fixtureBase}/sample.xlsx`);
|
||||
expect(resp.status()).toBe(200);
|
||||
expect(elapsed).toBeLessThan(maxMs);
|
||||
});
|
||||
@@ -0,0 +1,174 @@
|
||||
import { test, expect, request as playwrightRequest } from '@playwright/test';
|
||||
|
||||
const fixtureBase = process.env.FIXTURE_BASE_URL || 'http://127.0.0.1:18080';
|
||||
|
||||
function b64(v: string): string {
|
||||
return Buffer.from(v).toString('base64');
|
||||
}
|
||||
|
||||
async function openPreview(request: any, fileUrl: string) {
|
||||
const encoded = encodeURIComponent(b64(fileUrl));
|
||||
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 () => {
|
||||
const api = await playwrightRequest.newContext();
|
||||
const required = [
|
||||
'sample.txt',
|
||||
'sample.md',
|
||||
'sample.json',
|
||||
'sample.xml',
|
||||
'sample.csv',
|
||||
'sample.html',
|
||||
'sample.png',
|
||||
'sample.pdf',
|
||||
'sample.docx',
|
||||
'sample.xlsx',
|
||||
'sample.pptx',
|
||||
'sample.zip',
|
||||
'sample.tar',
|
||||
'sample.tgz',
|
||||
'sample.7z',
|
||||
'sample.rar',
|
||||
'sample.mp4',
|
||||
'text.dxf',
|
||||
];
|
||||
|
||||
try {
|
||||
for (const name of required) {
|
||||
const resp = await api.get(`${fixtureBase}/${name}`);
|
||||
expect(resp.ok(), `fixture missing or unavailable: ${name}`).toBeTruthy();
|
||||
}
|
||||
} finally {
|
||||
await api.dispose();
|
||||
}
|
||||
});
|
||||
|
||||
test('01 home/index reachable', async ({ request }) => {
|
||||
const resp = await request.get('/');
|
||||
expect(resp.status()).toBeLessThan(500);
|
||||
});
|
||||
|
||||
test('02 txt preview', async ({ request }) => {
|
||||
const body = await openPreviewBody(request, `${fixtureBase}/sample.txt`);
|
||||
expectAnyContains(body, ['普通文本预览', 'sample.txt'], 'txt preview');
|
||||
});
|
||||
|
||||
test('03 markdown preview', async ({ request }) => {
|
||||
const body = await openPreviewBody(request, `${fixtureBase}/sample.md`);
|
||||
expectAnyContains(body, ['Markdown', 'sample.md', 'markdown'], 'markdown preview');
|
||||
});
|
||||
|
||||
test('04 json preview', async ({ request }) => {
|
||||
const body = await openPreviewBody(request, `${fixtureBase}/sample.json`);
|
||||
expectAnyContains(body, ['JSON', 'sample.json', 'json'], 'json preview');
|
||||
});
|
||||
|
||||
test('05 xml preview', async ({ request }) => {
|
||||
const body = await openPreviewBody(request, `${fixtureBase}/sample.xml`);
|
||||
expectAnyContains(body, ['XML', 'sample.xml', 'xml'], 'xml preview');
|
||||
});
|
||||
|
||||
test('06 csv preview', async ({ request }) => {
|
||||
const body = await openPreviewBody(request, `${fixtureBase}/sample.csv`);
|
||||
expectAnyContains(body, ['CSV', 'sample.csv', 'csv'], 'csv preview');
|
||||
});
|
||||
|
||||
test('07 html preview', async ({ request }) => {
|
||||
const body = await openPreviewBody(request, `${fixtureBase}/sample.html`);
|
||||
expectAnyContains(body, ['HTML', 'sample.html', 'html'], 'html preview');
|
||||
});
|
||||
|
||||
test('08 png preview', async ({ request }) => {
|
||||
const body = await openPreviewBody(request, `${fixtureBase}/sample.png`);
|
||||
expectAnyContains(body, ['图片预览', 'sample.png', '<img'], 'png preview');
|
||||
});
|
||||
|
||||
test('09 pdf preview', async ({ request }) => {
|
||||
const body = await openPreviewBody(request, `${fixtureBase}/sample.pdf`, true);
|
||||
expectAnyContains(body, ['图片预览', 'sample.pdf', 'pdf'], 'pdf preview');
|
||||
});
|
||||
|
||||
test('10 docx preview', async ({ request }) => {
|
||||
const body = await openPreviewBody(request, `${fixtureBase}/sample.docx`, true);
|
||||
expectAnyContains(body, ['图片预览', 'sample.docx', 'office'], 'docx preview');
|
||||
});
|
||||
|
||||
test('11 xlsx preview', async ({ request }) => {
|
||||
const body = await openPreviewBody(request, `${fixtureBase}/sample.xlsx`, true);
|
||||
expectAnyContains(body, ['sample.xlsx预览', 'xlsx', 'office'], 'xlsx preview');
|
||||
});
|
||||
|
||||
test('12 pptx preview', async ({ request }) => {
|
||||
const body = await openPreviewBody(request, `${fixtureBase}/sample.pptx`, true);
|
||||
expectAnyContains(body, ['ppt', 'sample.pptx', 'office'], 'pptx preview');
|
||||
});
|
||||
|
||||
test('13 zip preview', async ({ request }) => {
|
||||
const body = await openPreviewBody(request, `${fixtureBase}/sample.zip`);
|
||||
expectAnyContains(body, ['压缩包预览', 'sample.zip', 'inner.txt'], 'zip preview');
|
||||
});
|
||||
|
||||
test('14 tar preview', async ({ request }) => {
|
||||
const body = await openPreviewBody(request, `${fixtureBase}/sample.tar`);
|
||||
expectAnyContains(body, ['压缩包预览', 'sample.tar', 'inner.txt'], 'tar preview');
|
||||
});
|
||||
|
||||
test('15 tgz preview', async ({ request }) => {
|
||||
const body = await openPreviewBody(request, `${fixtureBase}/sample.tgz`);
|
||||
expectAnyContains(body, ['压缩包预览', 'sample.tgz', 'inner.txt', '系统暂不支持在线预览'], 'tgz preview');
|
||||
});
|
||||
|
||||
test('16 7z preview', async ({ request }) => {
|
||||
const body = await openPreviewBody(request, `${fixtureBase}/sample.7z`);
|
||||
expectAnyContains(body, ['压缩包预览', 'sample.7z', 'inner.txt'], '7z preview');
|
||||
});
|
||||
|
||||
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 body = await resp.text();
|
||||
expect(body).toContain('不受信任');
|
||||
});
|
||||
|
||||
test('21 security: block 10.x host in getCorsFile', async ({ request }) => {
|
||||
const encoded = b64('http://10.1.2.3/a.pdf');
|
||||
const resp = await request.get(`/getCorsFile?urlPath=${encoded}`);
|
||||
const body = await resp.text();
|
||||
expect(body).toContain('不受信任');
|
||||
});
|
||||
Reference in New Issue
Block a user