Add comprehensive Claude Code tooling: - Agents: docs-researcher, docs-researcher-advanced for documentation research - Commands: dev:add-e2e-attrs, docs:library, docs:refresh-reference, quality:bundle-analyze, quality:coverage - Skills: 8 specialized skills including api-change-analyzer, architecture-enforcer, library-scaffolder, and more Update documentation: - Comprehensive CLAUDE.md overhaul with library reference system - Update testing guidelines in docs/guidelines/testing.md - Update READMEs for checkout, icons, scanner, and scroll-position libraries Remove outdated checkout-completion-flow-documentation.md Update .gitignore for Claude Code files
10 KiB
name, description
| name | description |
|---|---|
| test-migration-specialist | This skill should be used when migrating Angular libraries from Jest + Spectator to Vitest + Angular Testing Utilities. It handles test configuration updates, test file refactoring, mock pattern conversion, and validation. Use this skill when the user requests test framework migration, specifically for the 40 remaining Jest-based libraries in the ISA-Frontend monorepo. |
Test Migration Specialist
Overview
Automate the migration of Angular library tests from Jest + Spectator to Vitest + Angular Testing Utilities. This skill handles the complete migration workflow including configuration updates, test file refactoring, dependency management, and validation.
Current Migration Status: 40 libraries use Jest (65.6%), 21 libraries use Vitest (34.4%)
When to Use This Skill
Invoke this skill when:
- User requests test migration for a specific library
- User mentions "migrate tests" or "Jest to Vitest"
- User wants to update test framework for a library
- User references the 40 remaining libraries to migrate
Migration Workflow
Step 1: Pre-Migration Analysis
Before making any changes, analyze the current state:
-
Read Testing Guidelines
- Use
docs-researcheragent to readdocs/guidelines/testing.md - Understand migration patterns and best practices
- Note JUnit and Cobertura configuration requirements
- Use
-
Analyze Library Structure
- Read
libs/[path]/project.jsonto identify current test executor - Count test files using Glob:
**/*.spec.ts - Scan for Spectator usage patterns using Grep:
createComponentFactory|createServiceFactory|Spectator - Identify complex mocking scenarios (ng-mocks, jest.mock patterns)
- Read
-
Determine Library Depth
- Calculate directory levels from workspace root
- This affects relative paths in vite.config.mts (../../../ vs ../../../../)
Step 2: Update Test Configuration
Update the library's test configuration to use Vitest:
-
Update project.json Replace Jest executor with Vitest:
{ "test": { "executor": "@nx/vite:test", "options": { "configFile": "vite.config.mts" } } } -
Create vite.config.mts Create configuration with JUnit and Cobertura reporters:
/// <reference types='vitest' /> import { defineConfig } from 'vite'; import angular from '@analogjs/vite-plugin-angular'; import { nxViteTsPaths } from '@nx/vite/plugins/nx-tsconfig-paths.plugin'; import { nxCopyAssetsPlugin } from '@nx/vite/plugins/nx-copy-assets.plugin'; export default // @ts-expect-error - Vitest reporter tuple types have complex inference issues defineConfig(() => ({ root: __dirname, cacheDir: '../../../node_modules/.vite/libs/[path]', plugins: [angular(), nxViteTsPaths(), nxCopyAssetsPlugin(['*.md'])], test: { watch: false, globals: true, environment: 'jsdom', include: ['{src,tests}/**/*.{test,spec}.{js,mjs,cjs,ts,mts,cts,jsx,tsx}'], setupFiles: ['src/test-setup.ts'], reporters: [ 'default', ['junit', { outputFile: '../../../testresults/junit-[library-name].xml' }], ], coverage: { reportsDirectory: '../../../coverage/libs/[path]', provider: 'v8' as const, reporter: ['text', 'cobertura'], }, }, }));Critical: Adjust
../../../depth based on library location
Step 3: Migrate Test Files
For each .spec.ts file, perform these conversions:
-
Update Imports
// REMOVE import { createComponentFactory, Spectator } from '@ngneat/spectator/jest'; // ADD import { ComponentFixture, TestBed } from '@angular/core/testing'; import { describe, it, expect, beforeEach } from 'vitest'; -
Convert Component Tests
// OLD (Spectator) const createComponent = createComponentFactory({ component: MyComponent, imports: [CommonModule], mocks: [MyService] }); let spectator: Spectator<MyComponent>; beforeEach(() => spectator = createComponent()); it('should display title', () => { spectator.setInput('title', 'Test'); expect(spectator.query('h1')).toHaveText('Test'); }); // NEW (Angular Testing Utilities) describe('MyComponent', () => { let fixture: ComponentFixture<MyComponent>; let component: MyComponent; beforeEach(async () => { await TestBed.configureTestingModule({ imports: [MyComponent, CommonModule], providers: [{ provide: MyService, useValue: mockService }] }).compileComponents(); fixture = TestBed.createComponent(MyComponent); component = fixture.componentInstance; }); it('should display title', () => { component.title = 'Test'; fixture.detectChanges(); expect(fixture.nativeElement.querySelector('h1').textContent).toContain('Test'); }); }); -
Convert Service Tests
// OLD (Spectator) const createService = createServiceFactory({ service: MyService, mocks: [HttpClient] }); // NEW (Angular Testing Utilities) describe('MyService', () => { let service: MyService; let httpMock: HttpTestingController; beforeEach(() => { TestBed.configureTestingModule({ imports: [HttpClientTestingModule], providers: [MyService] }); service = TestBed.inject(MyService); httpMock = TestBed.inject(HttpTestingController); }); afterEach(() => { httpMock.verify(); }); }); -
Update Mock Patterns
- Replace
jest.fn()→vi.fn() - Replace
jest.spyOn()→vi.spyOn() - Replace
jest.mock()→vi.mock() - For complex mocks, use
ng-mockslibrary if needed
- Replace
-
Update Matchers
- Replace Spectator matchers (
toHaveText,toExist) with standard Jest/Vitest matchers - Use
expect().toBeTruthy(),expect().toContain(), etc.
- Replace Spectator matchers (
Step 4: Verify E2E Attributes
Check component templates for E2E testing attributes:
-
Scan Templates Use Grep to find templates:
**/*.html -
Validate Attributes Ensure interactive elements have:
data-what: Semantic description (e.g., "submit-button")data-which: Unique identifier (e.g., "form-primary")- Dynamic
data-*for list items:[attr.data-item-id]="item.id"
-
Add Missing Attributes If missing, add them to components. See
dev:add-e2e-attrscommand or use that skill.
Step 5: Run Tests and Validate
Execute tests to verify migration:
-
Run Tests
npx nx test [library-name] --skip-nx-cache -
Run with Coverage
npx nx test [library-name] --coverage.enabled=true --skip-nx-cache -
Verify Output Files Check that CI/CD integration files are created:
- JUnit XML:
testresults/junit-[library-name].xml - Cobertura XML:
coverage/libs/[path]/cobertura-coverage.xml
- JUnit XML:
-
Address Failures If tests fail:
- Review test conversion (common issues: missing fixture.detectChanges(), incorrect selectors)
- Check mock configurations
- Verify imports are correct
- Ensure async tests use proper patterns
Step 6: Clean Up
Remove legacy configurations:
-
Remove Jest Files
- Delete
jest.config.tsorjest.config.jsif present - Remove Jest-specific setup files
- Delete
-
Update Dependencies
- Note if Spectator can be removed (check if other libs still use it)
- Note if Jest can be removed (check if other libs still use it)
- Don't actually remove from package.json unless all libs migrated
-
Update Documentation Update library README.md with new test commands:
## Testing This library uses Vitest + Angular Testing Utilities. ```bash # Run tests npx nx test [library-name] --skip-nx-cache # Run with coverage npx nx test [library-name] --coverage.enabled=true --skip-nx-cache
Step 7: Generate Migration Report
Provide comprehensive migration summary:
Test Migration Complete
=======================
Library: [library-name]
Framework: Jest + Spectator → Vitest + Angular Testing Utilities
📊 Migration Statistics
-----------------------
Test files migrated: XX
Component tests: XX
Service tests: XX
Total test cases: XX
✅ Test Results
---------------
Passing: XX/XX (100%)
Coverage: XX%
📝 Configuration
----------------
- project.json: ✅ Updated to @nx/vite:test
- vite.config.mts: ✅ Created with JUnit + Cobertura
- E2E attributes: ✅ Validated
📁 CI/CD Integration
--------------------
- JUnit XML: ✅ testresults/junit-[name].xml
- Cobertura XML: ✅ coverage/libs/[path]/cobertura-coverage.xml
🧹 Cleanup
----------
- Jest config removed: ✅
- README updated: ✅
💡 Next Steps
-------------
1. Verify tests in CI/CD pipeline
2. Monitor for any edge cases
3. Consider migrating related libraries
📚 Remaining Libraries
----------------------
Jest libraries remaining: XX/40
Progress: XX% complete
Error Handling
Common Migration Issues
Issue 1: Tests fail after migration
- Check
fixture.detectChanges()is called after setting inputs - Verify async tests use
async/awaitproperly - Check component imports are correct (standalone components)
Issue 2: Mocks not working
- Verify
vi.fn()syntax is correct - Check providers array in TestBed configuration
- For complex mocks, consider using
ng-mocks
Issue 3: Coverage files not generated
- Verify path depth in vite.config.mts matches library location
- Check reporters array includes
'cobertura' - Ensure
provider: 'v8'is set
Issue 4: Type errors in vite.config.mts
- Add
// @ts-expect-errorcomment beforedefineConfig() - This is expected due to Vitest reporter type complexity
References
Use docs-researcher agent to access:
docs/guidelines/testing.md- Comprehensive migration guide with examplesCLAUDE.md- Testing Framework section for project conventions
Key Documentation Sections:
- Vitest Configuration with JUnit and Cobertura
- Angular Testing Utilities examples
- Migration patterns and best practices
- E2E attribute requirements