Skip to content

Commit 5a6df8d

Browse files
author
Mohammod Al Amin Ashik
committed
ci: add test results reporting and coverage for all test types
- Add EnricoMi/publish-unit-test-result-action for unified test reporting - Add Codecov integration for TypeScript coverage - Configure JUnit XML output for Rust (nextest), TypeScript (vitest), and E2E (wdio) - Add test-report and coverage-report jobs to CI workflow - Add e2e-report job to e2e-desktop workflow for desktop E2E results - Fix gnome-keyring unlock for Linux E2E tests (pipe password properly) - Upload test artifacts (screenshots, videos, reports) on all runs
1 parent c2a2047 commit 5a6df8d

6 files changed

Lines changed: 205 additions & 6 deletions

File tree

.github/workflows/ci.yml

Lines changed: 89 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,13 @@ concurrency:
1111
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.sha }}
1212
cancel-in-progress: ${{ github.event_name == 'pull_request' }}
1313

14+
# Permissions needed for test reporting and PR comments
15+
permissions:
16+
contents: read
17+
actions: read
18+
checks: write
19+
pull-requests: write
20+
1421
env:
1522
CARGO_TERM_COLOR: always
1623
RUST_BACKTRACE: 1
@@ -77,8 +84,25 @@ jobs:
7784
- run: pnpm install --frozen-lockfile
7885
- run: pnpm typecheck
7986
- run: pnpm lint
80-
- name: TypeScript tests
81-
run: pnpm test:ts
87+
88+
- name: TypeScript tests with coverage
89+
run: pnpm exec vitest run -c tests/ts/vitest.config.ts --coverage
90+
91+
- name: Upload TS test results
92+
uses: actions/upload-artifact@v4
93+
if: always()
94+
with:
95+
name: test-results-typescript
96+
path: tests/ts/test-results/
97+
retention-days: 7
98+
99+
- name: Upload TS coverage
100+
uses: actions/upload-artifact@v4
101+
if: always()
102+
with:
103+
name: coverage-typescript
104+
path: tests/ts/coverage/
105+
retention-days: 7
82106

83107
# ─────────────────────────────────────────────────────────────
84108
# Rust Tests (cross-platform matrix)
@@ -124,10 +148,19 @@ jobs:
124148
- name: Doc tests
125149
run: cargo test --workspace --doc
126150

127-
# Run integration tests
151+
# Run integration tests (outputs JUnit XML)
128152
- name: Integration tests
129153
run: cargo nextest run -p tests --profile ci
130154

155+
# Upload test results for reporting
156+
- name: Upload test results
157+
uses: actions/upload-artifact@v4
158+
if: always()
159+
with:
160+
name: test-results-${{ matrix.os }}
161+
path: target/nextest/ci/junit.xml
162+
retention-days: 7
163+
131164
# ─────────────────────────────────────────────────────────────
132165
# Build Verification (ensures app compiles on all platforms)
133166
# ─────────────────────────────────────────────────────────────
@@ -175,6 +208,59 @@ jobs:
175208
PKG_CONFIG_PATH: /usr/lib/x86_64-linux-gnu/pkgconfig:/usr/lib/pkgconfig:/usr/share/pkgconfig
176209
TAURI_SIGNING_PRIVATE_KEY: ${{ secrets.TAURI_SIGNING_PRIVATE_KEY }}
177210

211+
# ─────────────────────────────────────────────────────────────
212+
# Test Results Report (aggregates all test results)
213+
# ─────────────────────────────────────────────────────────────
214+
test-report:
215+
needs: [rust-test, ts-check]
216+
if: always()
217+
runs-on: ubuntu-latest
218+
steps:
219+
- name: Download all test results
220+
uses: actions/download-artifact@v4
221+
with:
222+
pattern: test-results-*
223+
path: test-results
224+
merge-multiple: true
225+
226+
- name: Publish Test Results
227+
uses: EnricoMi/publish-unit-test-result-action@v2
228+
if: always()
229+
with:
230+
files: |
231+
test-results/**/*.xml
232+
check_name: 'Test Results'
233+
comment_title: 'Test Results'
234+
comment_mode: always
235+
236+
# ─────────────────────────────────────────────────────────────
237+
# Coverage Report (uploads to Codecov)
238+
# ─────────────────────────────────────────────────────────────
239+
coverage-report:
240+
needs: [ts-check]
241+
if: always() && needs.ts-check.result == 'success'
242+
runs-on: ubuntu-latest
243+
steps:
244+
- uses: actions/checkout@v4
245+
246+
- name: Download coverage artifacts
247+
uses: actions/download-artifact@v4
248+
with:
249+
pattern: coverage-*
250+
path: coverage
251+
merge-multiple: true
252+
253+
- name: Upload to Codecov
254+
uses: codecov/codecov-action@v5
255+
with:
256+
files: coverage/lcov.info
257+
flags: typescript
258+
name: mcpmux-ts-coverage
259+
fail_ci_if_error: false
260+
verbose: true
261+
env:
262+
CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}
263+
178264
# ─────────────────────────────────────────────────────────────
179265
# E2E Tests (Web-only Playwright for UI smoke tests)
180266
# Skip with [skip e2e] in commit message for faster PR iteration
@@ -221,9 +307,6 @@ jobs:
221307
# ─────────────────────────────────────────────────────────────
222308
e2e-trigger-check:
223309
runs-on: ubuntu-latest
224-
permissions:
225-
pull-requests: read
226-
contents: read
227310
outputs:
228311
run_e2e: ${{ steps.check.outputs.should_run }}
229312
steps:

.github/workflows/e2e-desktop.yml

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,3 +88,43 @@ jobs:
8888
- name: Run desktop E2E tests (Windows)
8989
if: matrix.os == 'windows-latest'
9090
run: pnpm test:e2e
91+
92+
# Upload test results and artifacts
93+
- name: Upload E2E test results
94+
uses: actions/upload-artifact@v4
95+
if: always()
96+
with:
97+
name: e2e-desktop-results-${{ matrix.os }}
98+
path: |
99+
tests/e2e/reports/
100+
tests/e2e/screenshots/
101+
tests/e2e/videos/
102+
retention-days: 7
103+
104+
# Publish aggregated E2E test results
105+
e2e-report:
106+
needs: [e2e-desktop]
107+
if: always()
108+
runs-on: ubuntu-latest
109+
permissions:
110+
contents: read
111+
actions: read
112+
checks: write
113+
pull-requests: write
114+
steps:
115+
- name: Download all E2E test results
116+
uses: actions/download-artifact@v4
117+
with:
118+
pattern: e2e-desktop-results-*
119+
path: test-results
120+
merge-multiple: true
121+
122+
- name: Publish E2E Test Results
123+
uses: EnricoMi/publish-unit-test-result-action@v2
124+
if: always()
125+
with:
126+
files: |
127+
test-results/**/*.xml
128+
check_name: 'E2E Desktop Test Results'
129+
comment_title: 'E2E Desktop Test Results'
130+
comment_mode: always

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@
4444
"@vitejs/plugin-react": "^4.6.0",
4545
"@vitest/coverage-v8": "^3.0.0",
4646
"@wdio/cli": "^9.0.0",
47+
"@wdio/junit-reporter": "^9.0.0",
4748
"@wdio/local-runner": "^9.0.0",
4849
"@wdio/mocha-framework": "^9.0.0",
4950
"@wdio/spec-reporter": "^9.0.0",

pnpm-lock.yaml

Lines changed: 63 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

tests/e2e/wdio.conf.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -223,6 +223,12 @@ export const config: Options.Testrunner = {
223223
framework: 'mocha',
224224
reporters: [
225225
'spec',
226+
['junit', {
227+
outputDir: './tests/e2e/reports/',
228+
outputFileFormat: function(options) {
229+
return `wdio-junit-${options.cid}.xml`;
230+
},
231+
}],
226232
[video, {
227233
saveAllVideos: process.env.SAVE_ALL_VIDEOS === 'true', // Save all videos when env var is set
228234
videoSlowdownMultiplier: 1, // Normal speed
@@ -250,8 +256,10 @@ export const config: Options.Testrunner = {
250256
// Create output directories (gitignored; needed for CI and fresh clones)
251257
const screenshotsDir = path.resolve('./tests/e2e/screenshots');
252258
const videosDir = path.resolve('./tests/e2e/videos');
259+
const reportsDir = path.resolve('./tests/e2e/reports');
253260
fs.mkdirSync(screenshotsDir, { recursive: true });
254261
fs.mkdirSync(videosDir, { recursive: true });
262+
fs.mkdirSync(reportsDir, { recursive: true });
255263

256264
// Verify tauri-driver is installed
257265
const hasTauriDriver = checkTauriDriver();

tests/ts/vitest.config.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,10 @@ export default defineConfig({
1111
include: ['**/*.test.{ts,tsx}'],
1212
exclude: ['**/node_modules/**'],
1313
root: __dirname,
14+
reporters: ['default', 'junit'],
15+
outputFile: {
16+
junit: './test-results/vitest-junit.xml',
17+
},
1418
coverage: {
1519
provider: 'v8',
1620
reporter: ['text', 'html', 'lcov'],

0 commit comments

Comments
 (0)