Conversation
…sts for SDK workflows, and coverage support - Added unit tests for `auto-capture` and `capture-runtime` modules to validate core functionality. - Introduced integration tests for live SDK workflows using the real backend for enrollment, verification, and API validation. - Created helper methods for mock camera and video processing in `sharpness` tests. - Added `@vitest/coverage-v8` and configured `test:coverage` script for test coverage reporting. - Included integration test configurations in `vitest.integration.config.ts`.
- Introduced `face-c.jpg` for testing verification with a non-matching face. - Updated integration tests to validate both match and no-match scenarios comprehensively. - Revised `README.md` to clarify fixture file purposes and replace guidance.
There was a problem hiding this comment.
Pull request overview
Adds a dedicated integration-test suite for exercising the live SimFace backend, while tightening unit-test execution by enabling coverage thresholds in CI.
Changes:
- Introduces a separate Vitest config + npm script for live-backend integration tests (
src/integration/**). - Enables v8 coverage reporting with thresholds for the main test run, and updates CI to run coverage by default.
- Adds/extends unit tests around capture runtime utilities, auto-capture messaging, face detection, and sharpness scoring.
Reviewed changes
Copilot reviewed 11 out of 15 changed files in this pull request and generated 6 comments.
Show a summary per file
| File | Description |
|---|---|
vitest.integration.config.ts |
New Vitest config for node-based, non-concurrent integration tests. |
vite.config.ts |
Excludes integration tests from unit runs and configures coverage thresholds. |
src/shared/capture-runtime.test.ts |
New unit tests for capture-runtime utilities (camera access, frame capture, blob helpers). |
src/shared/auto-capture.test.ts |
New unit tests for auto-capture countdown/completion messaging. |
src/services/sharpness.test.ts |
Expands tests to cover computeSharpnessScore behavior. |
src/services/face-detection.test.ts |
Adds coverage for image-mode assessFaceQuality and refines mocks. |
src/integration/sdk-workflow.integration.test.ts |
New live-backend workflow integration test (validate/enroll/verify). |
src/integration/fixtures/README.md |
Documents fixture purpose and replacement guidance. |
src/index.test.ts |
Adds tests for enroll/verify edge cases (cancel, alreadyEnrolled, API key failure). |
package.json |
Adds test:integration, test:coverage, and @vitest/coverage-v8. |
package-lock.json |
Locks new coverage dependency and Vitest-related version updates. |
.github/workflows/test.yml |
Runs unit tests with coverage and adds a gated live-backend integration test job. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| // Unique client ID per run to avoid collisions across parallel CI jobs | ||
| const CLIENT_ID = `ci-test-${Date.now()}-${Math.random().toString(36).slice(2, 8)}`; | ||
|
|
||
| function loadFixture(name: string): Blob { | ||
| const buffer = readFileSync(resolve(__dirname, 'fixtures', name)); | ||
| return new Blob([buffer], { type: 'image/jpeg' }); | ||
| } | ||
|
|
||
| describe.skipIf(!hasCredentials)('SDK integration (live backend)', () => { | ||
| let client: SimFaceAPIClient; | ||
| let faceA: Blob; |
There was a problem hiding this comment.
These integration tests share state via CLIENT_ID and rely on earlier it(...) blocks having run successfully (enroll before verify). This is brittle (e.g., --sequence.shuffle or a mid-suite failure causes cascading failures); consider combining into a single end-to-end test or marking the suite explicitly sequential (e.g. describe.sequential) and using beforeAll/afterAll to manage setup/cleanup.
| }); | ||
| return ctx; | ||
| } | ||
|
|
There was a problem hiding this comment.
This test file installs several global/prototype spies/mocks (e.g. HTMLCanvasElement.prototype.getContext / toBlob, navigator.mediaDevices, etc.) but never restores them, which can leak state into other tests and cause flaky failures. Capture originals and restore in afterEach (or use vi.restoreAllMocks() plus restoring overwritten globals).
| afterEach(() => { | |
| vi.restoreAllMocks(); | |
| }); |
| it('rejects when FileReader errors', async () => { | ||
| const OriginalFileReader = globalThis.FileReader; | ||
|
|
||
| globalThis.FileReader = class MockFileReader { | ||
| onload: ((this: FileReader, ev: ProgressEvent<FileReader>) => unknown) | null = null; | ||
| onerror: ((this: FileReader, ev: ProgressEvent<FileReader>) => unknown) | null = null; | ||
| result: string | ArrayBuffer | null = null; | ||
|
|
||
| readAsDataURL() { | ||
| // Simulate async error | ||
| queueMicrotask(() => this.onerror?.(new ProgressEvent('error') as ProgressEvent<FileReader>)); | ||
| } | ||
| } as unknown as typeof FileReader; | ||
|
|
||
| await expect(blobToDataURL(new Blob(['x']))).rejects.toThrow('Failed to read image'); | ||
|
|
||
| globalThis.FileReader = OriginalFileReader; | ||
| }); |
There was a problem hiding this comment.
globalThis.FileReader is reassigned and only restored at the end of the test body; if the assertion fails/throws early, the original won’t be restored and later tests may break. Restore via try/finally or move the restoration to an afterEach hook.
| it('resolves with an HTMLImageElement on success', async () => { | ||
| const revokeStub = vi.fn(); | ||
| globalThis.URL.createObjectURL = vi.fn().mockReturnValue('blob:fake-url'); | ||
| globalThis.URL.revokeObjectURL = revokeStub; | ||
|
|
There was a problem hiding this comment.
These tests overwrite URL.createObjectURL / URL.revokeObjectURL but don’t restore the originals in afterEach, so later tests may see the mocked implementations. Save originals and restore them alongside globalThis.Image in the existing afterEach.
- Moved `REFERENCE_VARIANCE` to `capture-config.ts` for centralized configuration. - Updated integration tests to use `vitest.integration.config.ts` and enforced sequential execution for live backend tests. - Added `afterEach` hooks to restore global mocks in `capture-runtime.test.ts`. - Refactored `blobToDataURL` and `blobToImage` tests for clearer cleanup logic.
No description provided.