diff --git a/.github/workflows/docker-e2e-tests.yml b/.github/workflows/docker-e2e-tests.yml index 1041dc7..e378fa1 100644 --- a/.github/workflows/docker-e2e-tests.yml +++ b/.github/workflows/docker-e2e-tests.yml @@ -238,10 +238,11 @@ jobs: retention-days: 7 # ============================================ - # Job 4: Translation tests (optional, needs API keys) + # Job 4: Translation tests (使用免費翻譯服務) + # 使用 Google/Bing 免費翻譯,不需要付費 API 金鑰 # ============================================ translation-tests: - name: Translation Tests + name: Translation Tests (Free Services) runs-on: ubuntu-24.04 needs: build-test-image if: ${{ github.event.inputs.run_translation_tests == 'true' || github.event_name == 'push' }} @@ -262,21 +263,16 @@ jobs: run: docker pull ${{ needs.build-test-image.outputs.image }} - name: Run translation tests - env: - OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }} - GOOGLE_API_KEY: ${{ secrets.GOOGLE_API_KEY }} - DEEPL_API_KEY: ${{ secrets.DEEPL_API_KEY }} run: | - echo "🌍 Running translation tests..." + echo "🌍 Running translation tests (using free services: Google/Bing)..." docker run --rm \ --name convertx-translation-test \ -v "${{ github.workspace }}/tests:/app/tests" \ -v "${{ github.workspace }}/translation-results:/app/translation-results" \ - -e OPENAI_API_KEY="${OPENAI_API_KEY}" \ - -e GOOGLE_API_KEY="${GOOGLE_API_KEY}" \ - -e DEEPL_API_KEY="${DEEPL_API_KEY}" \ -e CI=true \ + -e PDFMATHTRANSLATE_SERVICE=google \ + -e BABELDOC_SERVICE=google \ --entrypoint /bin/bash \ ${{ needs.build-test-image.outputs.image }} \ -c " @@ -284,7 +280,7 @@ jobs: cd /app bun install --frozen-lockfile || bun install - echo '🌍 Running translation tests...' + echo '🌍 Running translation tests with free services...' bun test tests/e2e/translation.e2e.test.ts --timeout 600000 || true mkdir -p /app/translation-results diff --git a/CHANGELOG.md b/CHANGELOG.md index 0462156..0926dfc 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,21 @@ # Changelog +## [0.1.13](https://github.com/pi-docket/ConvertX-CN/releases/tag/v0.1.13) (2026-01-23) + +工作流程優化與測試修復版本。 + +### 📦 CI/CD + +- **翻譯測試優化**:改用免費翻譯服務(Google/Bing),移除付費 API 金鑰依賴 +- **自動化測試**:翻譯測試現在會在 push 時自動執行 + +### 🧪 Testing + +- **Inkscape 測試修復**:更新測試以配合 xvfb-run 包裝器 +- **format-matrix 測試修復**:修復超時參數中的 `sampled` 未定義錯誤 + +--- + ## [0.1.12](https://github.com/pi-docket/ConvertX-CN/releases/tag/v0.1.12) (2026-01-23) 測試與品質強化版本,大幅提升 CI/CD 可靠性與測試覆蓋率。 diff --git a/package.json b/package.json index a5a466d..2310323 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "convertx-frontend", - "version": "0.1.12", + "version": "0.1.13", "scripts": { "dev": "bun run --watch src/index.tsx", "hot": "bun run --hot src/index.tsx", diff --git a/tests/converters/inkscape.test.ts b/tests/converters/inkscape.test.ts index 330dd34..109001d 100644 --- a/tests/converters/inkscape.test.ts +++ b/tests/converters/inkscape.test.ts @@ -4,10 +4,10 @@ import type { ExecFileException } from "node:child_process"; import { ExecFileFn } from "../../src/converters/types"; // Inkscape 測試 -// 使用 Inkscape 1.0+ 的 headless-safe 命令列語法: -// inkscape input.png --export-type=svg --export-filename=output.svg +// 使用 xvfb-run 包裝 Inkscape 命令,確保在無 DISPLAY 環境下也能運作 +// xvfb-run -a --server-args="-screen 0 1024x768x24" inkscape input.svg --export-type=png --export-filename=output.png -test("convert uses correct headless-safe arguments", async () => { +test("convert uses correct xvfb-run wrapped arguments", async () => { let capturedCmd = ""; let capturedArgs: string[] = []; @@ -23,8 +23,15 @@ test("convert uses correct headless-safe arguments", async () => { await convert("input.svg", "svg", "png", "output.png", undefined, mockExecFile); - expect(capturedCmd).toBe("inkscape"); - expect(capturedArgs).toEqual(["input.svg", "--export-type=png", "--export-filename=output.png"]); + expect(capturedCmd).toBe("xvfb-run"); + expect(capturedArgs).toEqual([ + "-a", + "--server-args=-screen 0 1024x768x24", + "inkscape", + "input.svg", + "--export-type=png", + "--export-filename=output.png", + ]); }); test("convert resolves when inkscape succeeds", async () => { @@ -33,7 +40,7 @@ test("convert resolves when inkscape succeeds", async () => { _args: string[], callback: (err: ExecFileException | null, stdout: string, stderr: string) => void, ) => { - if (cmd === "inkscape") { + if (cmd === "xvfb-run") { callback(null, "Conversion complete", ""); } }; @@ -48,7 +55,7 @@ test("convert rejects when inkscape fails", async () => { _args: string[], callback: (err: ExecFileException | null, stdout: string, stderr: string) => void, ) => { - if (cmd === "inkscape") { + if (cmd === "xvfb-run") { callback(new Error("inkscape failed"), "", ""); } }; @@ -72,7 +79,7 @@ test("convert logs stdout when present", async () => { _args: string[], callback: (err: ExecFileException | null, stdout: string, stderr: string) => void, ) => { - if (cmd === "inkscape") { + if (cmd === "xvfb-run") { callback(null, "Fake stdout", ""); } }; @@ -97,7 +104,7 @@ test("convert logs stderr when present (non-fatal warning)", async () => { _args: string[], callback: (err: ExecFileException | null, stdout: string, stderr: string) => void, ) => { - if (cmd === "inkscape") { + if (cmd === "xvfb-run") { // Inkscape 經常輸出警告到 stderr,但轉換仍成功 callback(null, "", "Some warning message"); } diff --git a/tests/e2e/format-matrix.e2e.test.ts b/tests/e2e/format-matrix.e2e.test.ts index 72c3b7a..f130f78 100644 --- a/tests/e2e/format-matrix.e2e.test.ts +++ b/tests/e2e/format-matrix.e2e.test.ts @@ -537,7 +537,7 @@ describe("📊 格式轉換矩陣 Format Conversion Matrix", () => { } } }, - TIMEOUT * sampled.length, + TIMEOUT * MAX_TESTS_PER_CONVERTER, ); }); } @@ -634,7 +634,7 @@ describe("📊 格式轉換矩陣 Format Conversion Matrix", () => { } } }, - TIMEOUT * sampled.length, + TIMEOUT * MAX_TESTS_PER_CONVERTER, ); }); } @@ -714,7 +714,7 @@ describe("📊 格式轉換矩陣 Format Conversion Matrix", () => { } } }, - TIMEOUT * sampled.length, + TIMEOUT * MAX_TESTS_PER_CONVERTER, ); }); }