feat: 新增 OCRmyPDF 轉換引擎 (v0.1.14)
## 新功能 - OCRmyPDF 轉換引擎:將掃描版 PDF 轉換為可搜尋 PDF - 支援 7 種語言:en, zh-TW, zh, ja, ko, de, fr - 與 PDFMathTranslate 風格一致的 UI 格式 (pdf-<lang>) - 自動偵測頁面方向並旋轉 - 自動校正傾斜 - 跳過已有文字層的頁面 - 詳細的 5 階段處理進度輸出 ## 建置 - Dockerfile:安裝 ocrmypdf 與 Tesseract OCR 語言包 ## 文件 - 更新 OCR 功能文件 - 文件目錄結構改為中文名稱 ## 測試 - 修復 BabelDOC 和 PDFMathTranslate 測試的 OCR mock - 所有 345 個測試通過
This commit is contained in:
parent
f24eec070c
commit
a06df23b1d
53 changed files with 1427 additions and 675 deletions
148
docs/測試/CI-CD.md
Normal file
148
docs/測試/CI-CD.md
Normal file
|
|
@ -0,0 +1,148 @@
|
|||
# CI/CD
|
||||
|
||||
本文件說明 ConvertX-CN 的持續整合與持續部署設定。
|
||||
|
||||
---
|
||||
|
||||
## GitHub Actions
|
||||
|
||||
### 測試工作流
|
||||
|
||||
每次 Push 和 Pull Request 自動執行:
|
||||
|
||||
```yaml
|
||||
# .github/workflows/test.yml
|
||||
name: Test
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [main]
|
||||
pull_request:
|
||||
branches: [main]
|
||||
|
||||
jobs:
|
||||
test:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: Setup Bun
|
||||
uses: oven-sh/setup-bun@v1
|
||||
|
||||
- name: Install dependencies
|
||||
run: bun install
|
||||
|
||||
- name: Run lint
|
||||
run: bun run lint
|
||||
|
||||
- name: Run tests
|
||||
run: bun run test
|
||||
```
|
||||
|
||||
### Docker 建構工作流
|
||||
|
||||
標籤推送時自動建構並發布 Docker 映像:
|
||||
|
||||
```yaml
|
||||
# .github/workflows/docker.yml
|
||||
name: Docker Build
|
||||
|
||||
on:
|
||||
push:
|
||||
tags:
|
||||
- "v*"
|
||||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: Login to Docker Hub
|
||||
uses: docker/login-action@v3
|
||||
with:
|
||||
username: ${{ secrets.DOCKER_USERNAME }}
|
||||
password: ${{ secrets.DOCKER_TOKEN }}
|
||||
|
||||
- name: Build and push
|
||||
uses: docker/build-push-action@v5
|
||||
with:
|
||||
push: true
|
||||
tags: |
|
||||
convertx/convertx-cn:latest
|
||||
convertx/convertx-cn:${{ github.ref_name }}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 工作流程
|
||||
|
||||
### 開發流程
|
||||
|
||||
```
|
||||
1. 開發者提交 PR
|
||||
↓
|
||||
2. 自動執行測試
|
||||
↓
|
||||
3. 通過 Review
|
||||
↓
|
||||
4. 合併到 main
|
||||
```
|
||||
|
||||
### 發布流程
|
||||
|
||||
```
|
||||
1. 建立版本標籤 (v0.1.x)
|
||||
↓
|
||||
2. 自動建構 Docker 映像
|
||||
↓
|
||||
3. 推送到 Docker Hub
|
||||
↓
|
||||
4. 更新 latest 標籤
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 環境變數
|
||||
|
||||
### 測試環境
|
||||
|
||||
| 變數 | 說明 |
|
||||
| ---------- | ----------- |
|
||||
| `CI` | CI 環境標記 |
|
||||
| `NODE_ENV` | `test` |
|
||||
|
||||
### Docker 建構
|
||||
|
||||
| 變數 | 說明 |
|
||||
| ----------------- | ---------------- |
|
||||
| `DOCKER_USERNAME` | Docker Hub 帳號 |
|
||||
| `DOCKER_TOKEN` | Docker Hub Token |
|
||||
|
||||
---
|
||||
|
||||
## 本地模擬 CI
|
||||
|
||||
### 執行完整檢查
|
||||
|
||||
```bash
|
||||
# 模擬 CI 流程
|
||||
bun run lint
|
||||
bun run typecheck
|
||||
bun run test
|
||||
bun run build
|
||||
```
|
||||
|
||||
### 建構 Docker 映像
|
||||
|
||||
```bash
|
||||
docker build -t convertx-cn-test .
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 相關文件
|
||||
|
||||
- [測試策略](測試策略.md)
|
||||
- [E2E 測試](E2E測試.md)
|
||||
- [貢獻指南](../開發指南/貢獻指南.md)
|
||||
181
docs/測試/E2E測試.md
Normal file
181
docs/測試/E2E測試.md
Normal file
|
|
@ -0,0 +1,181 @@
|
|||
# E2E 測試
|
||||
|
||||
本文件說明如何執行與撰寫 ConvertX-CN 的端對端測試。
|
||||
|
||||
---
|
||||
|
||||
## 概述
|
||||
|
||||
E2E 測試模擬真實使用者操作,驗證完整的使用流程。
|
||||
|
||||
### 測試範圍
|
||||
|
||||
- ✅ 檔案上傳
|
||||
- ✅ 格式轉換
|
||||
- ✅ 檔案下載
|
||||
- ✅ 使用者認證
|
||||
- ✅ 歷史記錄
|
||||
|
||||
---
|
||||
|
||||
## 執行測試
|
||||
|
||||
### 前置條件
|
||||
|
||||
1. 啟動 ConvertX-CN 服務
|
||||
2. 確保 Docker 可用
|
||||
|
||||
### 執行命令
|
||||
|
||||
```bash
|
||||
# 執行所有 E2E 測試
|
||||
bun run test:e2e
|
||||
|
||||
# 使用腳本
|
||||
./scripts/run-e2e-tests.sh
|
||||
|
||||
# 指定測試檔案
|
||||
bun run test:e2e tests/e2e/upload.test.ts
|
||||
```
|
||||
|
||||
### 使用 Docker
|
||||
|
||||
```bash
|
||||
# 啟動測試環境
|
||||
docker compose -f compose.test.yml up -d
|
||||
|
||||
# 執行測試
|
||||
bun run test:e2e
|
||||
|
||||
# 清理
|
||||
docker compose -f compose.test.yml down
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 測試結構
|
||||
|
||||
```
|
||||
tests/e2e/
|
||||
├── upload.test.ts # 上傳測試
|
||||
├── convert.test.ts # 轉換測試
|
||||
├── download.test.ts # 下載測試
|
||||
├── auth.test.ts # 認證測試
|
||||
└── fixtures/ # 測試資料
|
||||
├── sample.docx
|
||||
├── sample.pdf
|
||||
└── sample.png
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 撰寫測試
|
||||
|
||||
### 基本範例
|
||||
|
||||
```typescript
|
||||
// tests/e2e/upload.test.ts
|
||||
import { test, expect } from "@playwright/test";
|
||||
|
||||
test.describe("File Upload", () => {
|
||||
test.beforeEach(async ({ page }) => {
|
||||
await page.goto("/");
|
||||
});
|
||||
|
||||
test("should upload a file", async ({ page }) => {
|
||||
// 選擇檔案
|
||||
const fileInput = page.locator('input[type="file"]');
|
||||
await fileInput.setInputFiles("tests/e2e/fixtures/sample.docx");
|
||||
|
||||
// 驗證檔案名稱顯示
|
||||
await expect(page.locator(".file-name")).toContainText("sample.docx");
|
||||
});
|
||||
});
|
||||
```
|
||||
|
||||
### 轉換測試
|
||||
|
||||
```typescript
|
||||
// tests/e2e/convert.test.ts
|
||||
test("should convert docx to pdf", async ({ page }) => {
|
||||
// 上傳檔案
|
||||
await page.setInputFiles('input[type="file"]', "tests/e2e/fixtures/sample.docx");
|
||||
|
||||
// 選擇目標格式
|
||||
await page.selectOption("#output-format", "pdf");
|
||||
|
||||
// 點擊轉換
|
||||
await page.click("#convert-button");
|
||||
|
||||
// 等待完成
|
||||
await expect(page.locator(".status")).toContainText("完成", { timeout: 60000 });
|
||||
});
|
||||
```
|
||||
|
||||
### 認證測試
|
||||
|
||||
```typescript
|
||||
// tests/e2e/auth.test.ts
|
||||
test("should login successfully", async ({ page }) => {
|
||||
await page.goto("/login");
|
||||
|
||||
await page.fill("#email", "test@example.com");
|
||||
await page.fill("#password", "password123");
|
||||
await page.click("#login-button");
|
||||
|
||||
await expect(page).toHaveURL("/");
|
||||
await expect(page.locator(".user-menu")).toBeVisible();
|
||||
});
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 設定
|
||||
|
||||
### Playwright 設定
|
||||
|
||||
```typescript
|
||||
// playwright.config.ts
|
||||
import { defineConfig } from "@playwright/test";
|
||||
|
||||
export default defineConfig({
|
||||
testDir: "./tests/e2e",
|
||||
timeout: 60000,
|
||||
use: {
|
||||
baseURL: "http://localhost:3000",
|
||||
screenshot: "only-on-failure",
|
||||
video: "retain-on-failure",
|
||||
},
|
||||
});
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 除錯
|
||||
|
||||
### 互動模式
|
||||
|
||||
```bash
|
||||
bun run test:e2e --debug
|
||||
```
|
||||
|
||||
### 檢視報告
|
||||
|
||||
```bash
|
||||
bun run test:e2e --reporter=html
|
||||
npx playwright show-report
|
||||
```
|
||||
|
||||
### 錄製測試
|
||||
|
||||
```bash
|
||||
npx playwright codegen http://localhost:3000
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 相關文件
|
||||
|
||||
- [測試策略](測試策略.md)
|
||||
- [CI/CD](CI-CD.md)
|
||||
- [本地開發](../開發指南/本地開發.md)
|
||||
211
docs/測試/測試策略.md
Normal file
211
docs/測試/測試策略.md
Normal file
|
|
@ -0,0 +1,211 @@
|
|||
# 測試策略
|
||||
|
||||
本文件說明 ConvertX-CN 的測試策略與方法。
|
||||
|
||||
---
|
||||
|
||||
## 測試類型
|
||||
|
||||
### 單元測試
|
||||
|
||||
測試獨立的函數與模組。
|
||||
|
||||
**涵蓋範圍:**
|
||||
|
||||
- 轉換器邏輯
|
||||
- 工具函數
|
||||
- 資料處理
|
||||
|
||||
### 整合測試
|
||||
|
||||
測試模組之間的協作。
|
||||
|
||||
**涵蓋範圍:**
|
||||
|
||||
- API 端點
|
||||
- 資料庫操作
|
||||
- 檔案處理
|
||||
|
||||
### E2E 測試
|
||||
|
||||
模擬使用者操作的完整流程測試。
|
||||
|
||||
**涵蓋範圍:**
|
||||
|
||||
- 上傳檔案
|
||||
- 轉換流程
|
||||
- 下載結果
|
||||
|
||||
---
|
||||
|
||||
## 執行測試
|
||||
|
||||
### 前端測試
|
||||
|
||||
```bash
|
||||
# 執行所有測試
|
||||
bun run test
|
||||
|
||||
# 監視模式
|
||||
bun run test:watch
|
||||
|
||||
# 覆蓋率報告
|
||||
bun run test:coverage
|
||||
```
|
||||
|
||||
### API Server 測試(Rust)
|
||||
|
||||
```bash
|
||||
cd api-server
|
||||
|
||||
# 執行所有測試
|
||||
cargo test
|
||||
|
||||
# 詳細輸出
|
||||
cargo test -- --nocapture
|
||||
```
|
||||
|
||||
### E2E 測試
|
||||
|
||||
```bash
|
||||
# 執行 E2E 測試
|
||||
bun run test:e2e
|
||||
|
||||
# 或使用腳本
|
||||
./scripts/run-e2e-tests.sh
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 測試結構
|
||||
|
||||
```
|
||||
tests/
|
||||
├── converters/ # 轉換器測試
|
||||
├── e2e/ # 端對端測試
|
||||
└── transfer/ # 傳輸模組測試
|
||||
|
||||
api-server/tests/
|
||||
├── api_tests.rs # REST API 測試
|
||||
├── graphql_tests.rs # GraphQL 測試
|
||||
└── integration_tests.rs # 整合測試
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 測試範例
|
||||
|
||||
### 前端單元測試
|
||||
|
||||
```typescript
|
||||
// tests/converters/ffmpeg.test.ts
|
||||
import { describe, it, expect } from "bun:test";
|
||||
import { ffmpegConverter } from "../../src/converters/ffmpeg";
|
||||
|
||||
describe("FFmpeg Converter", () => {
|
||||
it("should support mp4 input", () => {
|
||||
expect(ffmpegConverter.inputFormats).toContain("mp4");
|
||||
});
|
||||
|
||||
it("should support webm output", () => {
|
||||
expect(ffmpegConverter.outputFormats).toContain("webm");
|
||||
});
|
||||
});
|
||||
```
|
||||
|
||||
### API 整合測試
|
||||
|
||||
```rust
|
||||
// api-server/tests/api_tests.rs
|
||||
#[tokio::test]
|
||||
async fn test_health_endpoint() {
|
||||
let response = client.get("/health").send().await.unwrap();
|
||||
assert_eq!(response.status(), StatusCode::OK);
|
||||
}
|
||||
```
|
||||
|
||||
### E2E 測試
|
||||
|
||||
```typescript
|
||||
// tests/e2e/upload.test.ts
|
||||
import { test, expect } from "@playwright/test";
|
||||
|
||||
test("should upload and convert file", async ({ page }) => {
|
||||
await page.goto("/");
|
||||
|
||||
// 上傳檔案
|
||||
await page.setInputFiles("#file-input", "test.docx");
|
||||
|
||||
// 選擇格式
|
||||
await page.selectOption("#format", "pdf");
|
||||
|
||||
// 點擊轉換
|
||||
await page.click("#convert-button");
|
||||
|
||||
// 驗證結果
|
||||
await expect(page.locator(".download-link")).toBeVisible();
|
||||
});
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 測試資料
|
||||
|
||||
### 測試檔案
|
||||
|
||||
放置在 `tests/fixtures/` 目錄:
|
||||
|
||||
```
|
||||
tests/fixtures/
|
||||
├── documents/
|
||||
│ ├── sample.docx
|
||||
│ ├── sample.pdf
|
||||
│ └── sample.txt
|
||||
├── images/
|
||||
│ ├── sample.png
|
||||
│ └── sample.jpg
|
||||
└── audio/
|
||||
└── sample.mp3
|
||||
```
|
||||
|
||||
### Mock 資料
|
||||
|
||||
使用 Mock 避免依賴外部服務:
|
||||
|
||||
```typescript
|
||||
import { mock } from "bun:test";
|
||||
|
||||
const mockConverter = mock(() => ({
|
||||
convert: async () => "output.pdf",
|
||||
}));
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 持續整合
|
||||
|
||||
### GitHub Actions
|
||||
|
||||
```yaml
|
||||
# .github/workflows/test.yml
|
||||
name: Test
|
||||
|
||||
on: [push, pull_request]
|
||||
|
||||
jobs:
|
||||
test:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: oven-sh/setup-bun@v1
|
||||
- run: bun install
|
||||
- run: bun run test
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 相關文件
|
||||
|
||||
- [CI/CD](ci-cd.md)
|
||||
- [E2E 測試](e2e-tests.md)
|
||||
- [本地開發](../development/local-development.md)
|
||||
Loading…
Add table
Add a link
Reference in a new issue