Files
gitea-mirror/tests/e2e/01-health.spec.ts
Xyndra 2e00a610cb Add E2E testing (#201)
* feat: add E2E testing infrastructure with fake GitHub, Playwright, and CI workflow

- Add fake GitHub API server (tests/e2e/fake-github-server.ts) with
  management API for seeding test data
- Add Playwright E2E test suite covering full mirror workflow:
  service health checks, user registration, config, sync, verify
- Add Docker Compose for E2E Gitea instance
- Add orchestrator script (run-e2e.sh) with cleanup
- Add GitHub Actions workflow (e2e-tests.yml) with Gitea service container
- Make GITHUB_API_URL configurable via env var for testing
- Add npm scripts: test:e2e, test:e2e:ci, test:e2e:keep, test:e2e:cleanup

* feat: add real git repos + backup config testing to E2E suite

- Create programmatic test git repos (create-test-repos.ts) with real
  commits, branches (main, develop, feature/*), and tags (v1.0.0, v1.1.0)
- Add git-server container to docker-compose serving bare repos via
  dumb HTTP protocol so Gitea can actually clone them
- Update fake GitHub server to emit reachable clone_url fields pointing
  to the git-server container (configurable via GIT_SERVER_URL env var)
- Add management endpoint POST /___mgmt/set-clone-url for runtime config
- Update E2E spec with real mirroring verification:
  * Verify repos appear in Gitea with actual content
  * Check branches, tags, commits, file content
  * Verify 4/4 repos mirrored successfully
- Add backup configuration test suite:
  * Enable/disable backupBeforeSync config
  * Toggle blockSyncOnBackupFailure
  * Trigger re-sync with backup enabled and verify activities
  * Verify config persistence across changes
- Update CI workflow to use docker compose (not service containers)
  matching the local run-e2e.sh approach
- Update cleanup.sh for git-repos directory and git-server port
- All 22 tests passing with real git content verification

* refactor: split E2E tests into focused files + add force-push tests

Split the monolithic e2e.spec.ts (1335 lines) into 5 focused spec files
and a shared helpers module:

  helpers.ts                 — constants, GiteaAPI, auth, saveConfig, utilities
  01-health.spec.ts          — service health checks (4 tests)
  02-mirror-workflow.spec.ts — full first-mirror journey (8 tests)
  03-backup.spec.ts          — backup config toggling (6 tests)
  04-force-push.spec.ts      — force-push simulation & backup verification (9 tests)
  05-sync-verification.spec.ts — dynamic repos, content integrity, reset (5 tests)

The force-push tests are the critical addition:
  F0: Record original state (commit SHAs, file content)
  F1: Rewrite source repo history (simulate force-push)
  F2: Sync to Gitea WITHOUT backup
  F3: Verify data loss — LICENSE file gone, README overwritten
  F4: Restore source, re-mirror to clean state
  F5: Enable backup, force-push again, sync through app
  F6: Verify Gitea reflects the force-push
  F7: Verify backup system was invoked (snapshot activities logged)
  F8: Restore source repo for subsequent tests

Also added to helpers.ts:
  - GiteaAPI.getBranch(), .getCommit(), .triggerMirrorSync()
  - getRepositoryIds(), triggerMirrorJobs(), triggerSyncRepo()

All 32 tests passing.

* Try to fix actions

* Try to fix the other action

* Add debug info to check why e2e action is failing

* More debug info

* Even more debug info

* E2E fix attempt #1

* E2E fix attempt #2

* more debug again

* E2E fix attempt #3

* E2E fix attempt #4

* Remove a bunch of debug info

* Hopefully fix backup bug

* Force backups to succeed
2026-03-01 07:35:13 +05:30

78 lines
2.4 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/**
* 01 Service health checks.
*
* Quick smoke tests that confirm every service required by the E2E suite is
* reachable before the heavier workflow tests run.
*/
import { test, expect } from "@playwright/test";
import {
APP_URL,
GITEA_URL,
FAKE_GITHUB_URL,
GIT_SERVER_URL,
waitFor,
} from "./helpers";
test.describe("E2E: Service health checks", () => {
test("Fake GitHub API is running", async ({ request }) => {
const resp = await request.get(`${FAKE_GITHUB_URL}/___mgmt/health`);
expect(resp.ok()).toBeTruthy();
const data = await resp.json();
expect(data.status).toBe("ok");
expect(data.repos).toBeGreaterThan(0);
console.log(
`[Health] Fake GitHub: ${data.repos} repos, ${data.orgs} orgs, clone base: ${data.gitCloneBaseUrl ?? "default"}`,
);
});
test("Git HTTP server is running (serves test repos)", async ({
request,
}) => {
const resp = await request.get(`${GIT_SERVER_URL}/manifest.json`, {
failOnStatusCode: false,
});
expect(resp.ok(), "Git server should serve manifest.json").toBeTruthy();
const manifest = await resp.json();
expect(manifest.repos).toBeDefined();
expect(manifest.repos.length).toBeGreaterThan(0);
console.log(`[Health] Git server: serving ${manifest.repos.length} repos`);
for (const r of manifest.repos) {
console.log(`[Health] • ${r.owner}/${r.name}${r.description}`);
}
});
test("Gitea instance is running", async ({ request }) => {
await waitFor(
async () => {
const resp = await request.get(`${GITEA_URL}/api/v1/version`, {
failOnStatusCode: false,
});
return resp.ok();
},
{ timeout: 30_000, interval: 2_000, label: "Gitea healthy" },
);
const resp = await request.get(`${GITEA_URL}/api/v1/version`);
const data = await resp.json();
console.log(`[Health] Gitea version: ${data.version}`);
expect(data.version).toBeTruthy();
});
test("gitea-mirror app is running", async ({ request }) => {
await waitFor(
async () => {
const resp = await request.get(`${APP_URL}/`, {
failOnStatusCode: false,
});
return resp.status() < 500;
},
{ timeout: 60_000, interval: 2_000, label: "App healthy" },
);
const resp = await request.get(`${APP_URL}/`, {
failOnStatusCode: false,
});
console.log(`[Health] App status: ${resp.status()}`);
expect(resp.status()).toBeLessThan(500);
});
});