Add comprehensive frontend testing setup with Jest, React Testing Library, and GitHub Actions automation#92
Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
Co-authored-by: vidaluca77-cloud <226796821+vidaluca77-cloud@users.noreply.github.com>
…rary, and GitHub Actions Co-authored-by: vidaluca77-cloud <226796821+vidaluca77-cloud@users.noreply.github.com>
… setup Co-authored-by: vidaluca77-cloud <226796821+vidaluca77-cloud@users.noreply.github.com>
There was a problem hiding this comment.
Pull Request Overview
This PR implements a comprehensive frontend testing infrastructure for the La Vida Luca App, establishing automated testing across all React components and critical user flows. The setup includes Jest with React Testing Library for component testing, integration tests for complete user journeys, and GitHub Actions automation for continuous testing.
Key changes:
- Added complete testing stack with Jest, React Testing Library, and JSDOM environment
- Implemented 61 total tests across 4 component test files and 3 integration test files
- Established GitHub Actions CI/CD pipeline with 6 specialized testing jobs including accessibility, security, and performance testing
Reviewed Changes
Copilot reviewed 13 out of 15 changed files in this pull request and generated 3 comments.
Show a summary per file
| File | Description |
|---|---|
| tests/integration/*.test.tsx | Three comprehensive integration test suites covering user onboarding, contact submission, and activity browsing flows |
| src/app/tests/*.test.tsx | Four component test suites providing unit test coverage for home page, contact form, catalogue, and layout components |
| package.json | Added testing dependencies including React Testing Library, Jest environment, and Babel presets |
| .github/workflows/frontend-tests.yml | Comprehensive CI/CD pipeline with multi-node testing, accessibility checks, security scanning, and performance monitoring |
| jest.setup.js | Enhanced test setup with additional mocks for Next.js navigation, fetch API, and browser APIs |
| babel.config.js | Babel configuration for JSX/TypeScript transpilation in test environment |
| lighthouserc.json | Lighthouse CI configuration for accessibility and performance testing |
| TESTING.md | Comprehensive documentation covering test structure, execution, and best practices |
Tip: Customize your code reviews with copilot-instructions.md. Create the file or learn how to get started.
|
|
||
| // Reset for next profile | ||
| rerender(<App />); | ||
| } |
There was a problem hiding this comment.
Using rerender(<App />) inside a loop for testing different profiles is inefficient and may cause memory leaks. Consider creating separate test cases for each profile or properly cleaning up the DOM between iterations.
| } | |
| const profiles = [ | |
| { | |
| name: 'Agricultural Enthusiast', | |
| skills: ['elevage', 'soins_animaux', 'sol'], | |
| availability: ['weekend', 'vacances'], | |
| location: 'Normandie', | |
| preferences: ['Agriculture', 'Environnement'] | |
| }, | |
| { | |
| name: 'Creative Artisan', | |
| skills: ['creativite', 'precision', 'bois'], | |
| availability: ['apres-midi', 'semaine'], | |
| location: 'Bretagne', | |
| preferences: ['Artisanat', 'Transformation'] | |
| }, | |
| { | |
| name: 'Social Animator', | |
| skills: ['pedagogie', 'accueil', 'expression'], | |
| availability: ['matin', 'weekend'], | |
| location: 'Île-de-France', | |
| preferences: ['Animation'] | |
| } | |
| ]; | |
| it.each(profiles)('navigates through onboarding for profile: %s', async (profile) => { | |
| const user = userEvent.setup(); | |
| render(<App />); | |
| // Start onboarding | |
| const proposeButton = screen.getByText('Proposer mon aide'); | |
| await user.click(proposeButton); | |
| await waitFor(() => { | |
| expect(screen.getByText('Comment souhaitez-vous participer ?')).toBeInTheDocument(); | |
| }); | |
| // Select skills for this profile | |
| for (const skill of profile.skills) { | |
| const skillButton = screen.getByText(skill); | |
| await user.click(skillButton); | |
| } | |
| await user.click(screen.getByText('Suivant')); | |
| // Select availability | |
| await waitFor(() => { | |
| expect(screen.getByText('Vos disponibilités')).toBeInTheDocument(); | |
| }); | |
| for (const avail of profile.availability) { | |
| const availButton = screen.getByText(avail); | |
| await user.click(availButton); | |
| } | |
| await user.click(screen.getByText('Suivant')); | |
| // Enter location | |
| await waitFor(() => { | |
| expect(screen.getByText('Votre région')).toBeInTheDocument(); | |
| }); | |
| const locationInput = screen.getByPlaceholderText(/Ex: Ile-de-France/i); | |
| await user.type(locationInput, profile.location); | |
| await user.click(screen.getByText('Suivant')); | |
| // Select preferences | |
| await waitFor(() => { | |
| expect(screen.getByText('Vos préférences')).toBeInTheDocument(); | |
| }); | |
| for (const pref of profile.preferences) { | |
| const prefButton = screen.getByText(pref); | |
| await user.click(prefButton); | |
| } | |
| await user.click(screen.getByText('Voir mes propositions')); | |
| // Verify suggestions page | |
| await waitFor(() => { | |
| expect(screen.getByText('Vos propositions personnalisées')).toBeInTheDocument(); | |
| }); | |
| // Verify personalized suggestions are shown | |
| const suggestionCards = screen.getAllByText(/Voir le guide & m'inscrire/); | |
| expect(suggestionCards.length).toBeGreaterThan(0); |
| if: github.event_name == 'pull_request' | ||
| env: | ||
| DEFAULT_BRANCH: main | ||
| GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} No newline at end of file |
There was a problem hiding this comment.
The github/super-linter action is being used for bundle size commenting, but this action is primarily for code linting, not bundle analysis. Consider using a dedicated bundle analysis action like 'github/bundle-analyzer-action' or removing this step if bundle size analysis is handled elsewhere.
| GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| uses: github/bundle-analyzer-action@v3 | |
| if: github.event_name == 'pull_request' | |
| with: | |
| github_token: ${{ secrets.GITHUB_TOKEN }} | |
| stats_path: ./dist/stats.json |
| }); | ||
|
|
||
| const { rerender } = render(<Contact />); | ||
|
|
There was a problem hiding this comment.
Using rerender inside a loop for testing multiple form submissions is inefficient and can cause state pollution. Consider using separate test cases or properly unmounting components between iterations.
| mockFetch.mockClear(); | |
| mockFetch.mockResolvedValueOnce({ | |
| ok: true, | |
| json: () => Promise.resolve({ success: true }) | |
| }); | |
| // Create a new userEvent instance for each iteration | |
| const user = userEvent.setup(); | |
| render(<Contact />); |
This PR implements a complete frontend testing infrastructure for the La Vida Luca App, addressing the need for comprehensive test coverage across all React components and critical user flows.
🧪 Testing Infrastructure Added
Core Testing Stack
Component Test Coverage (44 tests)
Integration Testing (17 tests)
🚀 GitHub Actions Automation
Implemented a comprehensive CI/CD pipeline with 6 specialized jobs:
📊 Test Results & Coverage
🔧 Configuration Highlights
Jest Configuration
Mocking Strategy
📚 Documentation
Added comprehensive
TESTING.mddocumentation covering:🎯 Critical User Paths Tested
This testing setup provides a solid foundation for maintaining code quality and preventing regressions as the application evolves, with automated testing on every pull request and comprehensive coverage of all user-facing functionality.
💡 You can make Copilot smarter by setting up custom instructions, customizing its development environment and configuring Model Context Protocol (MCP) servers. Learn more Copilot coding agent tips in the docs.