diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 10a6a53..41182a1 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -35,3 +35,35 @@ jobs: # Fails when a new critical (or more than the accepted number of high) # production dependency finding appears. See docs/SECURITY_AUDIT.md. - run: pnpm audit:gate + + unit-tests: + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v4 + + - uses: actions/setup-node@v4 + with: + node-version: 22 + + - name: Enable corepack (installs pnpm from packageManager field) + run: | + corepack enable + corepack prepare pnpm@10.28.2 --activate + pnpm --version + + - run: pnpm install --frozen-lockfile + - name: Run unit tests + run: pnpm test:unit --reporter=default --reporter=junit --outputFile.junit=reports/unit/junit.xml + env: + CI: true + + # Keeps the machine-readable report out of the repository and attaches + # it to the run so a failing assertion can be inspected after the fact. + - name: Upload unit test report + if: always() + uses: actions/upload-artifact@v4 + with: + name: unit-test-report + path: reports/unit/ + if-no-files-found: ignore diff --git a/.gitignore b/.gitignore index 73b0c77..dd804a0 100644 --- a/.gitignore +++ b/.gitignore @@ -14,3 +14,6 @@ package-lock.json playwright-report/ test-results/ public/mockServiceWorker.js + +# Unit test reports +reports/ diff --git a/src/workers/stellar-scanner.worker.test.ts b/src/workers/stellar-scanner.worker.test.ts index 30cdc5e..186dcc3 100644 --- a/src/workers/stellar-scanner.worker.test.ts +++ b/src/workers/stellar-scanner.worker.test.ts @@ -341,6 +341,8 @@ describe('stellar-scanner worker message contract', () => { expect(requestedStartLedgers).toEqual([250]); }); + // The 1,000-event page is CPU-bound and only exceeds the default 5s budget + // when the whole suite runs in parallel, so this test gets an explicit timeout. it('paginates past the 1,000-event page cap and reports progress for every page', async () => { await import('./stellar-scanner.worker'); const requests: Record[] = []; @@ -391,7 +393,7 @@ describe('stellar-scanner worker message contract', () => { expect(terminal.type).toBe('SUCCESS'); expect(terminal.results).toHaveLength(1); expect((terminal.results as any)[0].stealthAddress).toBe(generated.stealthAddress); - }); + }, 30_000); it('keeps the committed cursor when a later page fails so the rescan resumes there', async () => { await import('./stellar-scanner.worker');