Rurutia1027/Shortlink-Frontend
This repository focuses on refactoring the Shortlink frontend from Vue to React to achieve a clean front-end/back-end separation, while introducing a React componentβbased selector design to support automated end-to-end testing of frontend components.
Shortlink Frontend
A modern, production-ready short link management application built with React, Next.js, and TypeScript. This project provides a comprehensive solution for creating, managing, and analyzing short links with advanced analytics capabilities.
π Tech Stack
Core Framework
- Next.js 14 - React framework with App Router
- React 18 - UI library
- TypeScript - Type-safe development
UI & Styling
- Ant Design 5.x - Enterprise-class UI component library
- CSS Modules - Scoped CSS styling
- Tailwind CSS - Utility-first CSS framework
State Management
- Zustand - Lightweight state management
Form Management
- React Hook Form - Performant form library
- Zod - TypeScript-first schema validation
Data Visualization
- Recharts - Composable charting library for React
HTTP Client
- Axios - Promise-based HTTP client
Additional Libraries
- @dnd-kit - Drag and drop toolkit
- dayjs - Date manipulation library
- qrcode.react - QR code generation
Testing Stack
- Jest - JavaScript testing framework
- React Testing Library - React component testing utilities
- @testing-library/jest-dom - Custom Jest matchers
- @testing-library/user-event - User interaction simulation
- Playwright - End-to-end testing framework (planned)
Development Tools
- ESLint - Code linting
- TypeScript - Static type checking
π Project Overview
Shortlink Frontend is a full-featured web application for managing short links with the following capabilities:
Key Features
- Link Management: Create, edit, delete, and organize short links
- Batch Operations: Bulk create multiple short links at once
- Group Organization: Organize links into groups with drag-and-drop sorting
- Analytics Dashboard: Comprehensive analytics with charts and access logs
- QR Code Generation: Generate and download QR codes for short links
- Recycle Bin: Restore or permanently delete removed links
- User Management: Profile management and authentication
- Responsive Design: Works seamlessly on desktop and mobile devices
Project Status
- Overall Completion: ~95%
- Pages: 4/4 (100%)
- Components: 5/5 (100%)
- API Layer: Complete
- Infrastructure: Complete
π§ͺ Testing Strategy
This project follows a comprehensive testing strategy with multiple levels of testing to ensure code quality and reliability.
Testing Pyramid
/\
/ \ E2E Tests (Playwright)
/____\ - Full user flows
/ \ - Critical paths
/________\ - Few, slow, expensive
/ \
/ Unit Tests \ Jest + React Testing Library
/____________\ - Components
/ \ - Utilities
/ Integration \ - Multiple components together
/________________\
1. Unit Tests (Jest + React Testing Library)
Purpose: Test individual components and functions in isolation
Libraries:
- Jest - Test runner
- React Testing Library - Component testing
- @testing-library/jest-dom - DOM matchers
- @testing-library/user-event - User interaction simulation
Coverage:
- Component rendering
- Props handling
- User interactions (clicks, inputs)
- State changes
- Utility functions
- Custom hooks
Example:
// app/home/space/components/QRCode/QRCode.test.tsx
describe('QRCode Component', () => {
it('renders QR code modal when visible is true', () => {
render(<QRCode url="https://example.com" visible={true} onClose={mockOnClose} />)
expect(screen.getByTestId('modal-qrcode')).toBeInTheDocument()
})
})Target: 50-100 unit tests
2. Integration Tests (Jest + React Testing Library)
Purpose: Test multiple components working together
Coverage:
- Form submission flows
- Modal interactions
- Table with pagination
- Parent-child component communication
- Feature workflows
Example:
// Integration test example
describe('CreateLink Integration', () => {
it('creates link and updates table', async () => {
render(<MySpacePage />)
// Click create button
// Fill form
// Submit
// Verify table updated
})
})Target: 20-30 integration tests
3. End-to-End Tests (Playwright)
Purpose: Test complete user flows in a real browser
Libraries:
- Playwright - Modern E2E testing framework
Coverage:
- Critical user flows
- Login/Registration
- Create/Edit/Delete links
- Group management
- Analytics viewing
- Cross-browser testing
Example:
// E2E test example (Playwright)
test('should create a new short link', async ({ page }) => {
await page.goto('/home/space')
await page.click('[data-testid="button-create-link"]')
await page.fill('[data-testid="input-origin-url"]', 'https://example.com')
await page.fill('[data-testid="textarea-describe"]', 'Test link')
await page.click('[data-testid="button-submit"]')
await expect(page.locator('[data-testid="table-shortlinks-list"]')).toContainText('Test link')
})Target: 10-15 E2E tests
4. BDD Testing Support (Behavior-Driven Development)
Purpose: Write tests in natural language to describe behavior
Approach:
We support BDD-style test descriptions using descriptive test names and organized test suites that follow the Given-When-Then pattern.
Example:
describe('CreateLink Component', () => {
describe('Given the user wants to create a short link', () => {
describe('When the form is filled with valid data', () => {
it('Then it should submit successfully and show success message', async () => {
// Test implementation
})
})
describe('When the URL is invalid', () => {
it('Then it should show validation error', async () => {
// Test implementation
})
})
})
})BDD Tools (Future):
- Cucumber.js - BDD framework for JavaScript
- Gherkin - Natural language test specifications
π― Test Data IDs (E2E Automation Support)
Strategy: Embedded Test Data IDs
All interactive components include data-testid attributes for reliable E2E testing. This ensures stable selectors that won't break with UI changes.
Naming Convention
data-testid="[component-type]-[component-name]-[action/element]"
Examples
| Component | Test ID | Example |
|---|---|---|
| Button | button-[name]-[action] |
data-testid="button-create-link" |
| Input | input-[name]-field |
data-testid="input-origin-url" |
| Modal | modal-[name] |
data-testid="modal-create-link" |
| Table | table-[name]-list |
data-testid="table-shortlinks-list" |
| Form | form-[name] |
data-testid="form-create-link" |
Implementation Status
β
All components include data-testid attributes:
- QRCode component
- ChartsInfo component
- CreateLink component
- CreateLinks component
- EditLink component
- All modals
- All forms
- All buttons
Usage in Tests
// Playwright E2E test
test('should create a new link', async ({ page }) => {
await page.goto('/home/space')
// Use data-testid selectors
await page.click('[data-testid="button-create-link"]')
await page.waitForSelector('[data-testid="modal-create-link"]')
await page.fill('[data-testid="input-origin-url"]', 'https://example.com')
await page.fill('[data-testid="textarea-describe"]', 'Test Link')
await page.selectOption('[data-testid="select-group"]', 'group-id')
await page.click('[data-testid="button-submit"]')
// Verify success
await expect(page.locator('[data-testid="modal-create-link"]')).not.toBeVisible()
await expect(page.locator('[data-testid="table-shortlinks-list"]')).toContainText('Test Link')
})Benefits
- Stable Selectors: Don't break when CSS classes or structure changes
- Clear Intent: Test IDs describe what the element is, not how it looks
- E2E Ready: Playwright/Cypress can reliably find elements
- Maintainable: Easy to update tests when features change
π Project Structure
Shortlink-Frontend/
βββ app/ # Next.js App Router
β βββ (auth)/ # Auth routes
β β βββ login/ # Login page
β βββ home/ # Protected routes
β βββ space/ # Main short link management
β β βββ components/ # Page-specific components
β β β βββ QRCode/
β β β βββ ChartsInfo/
β β β βββ CreateLink/
β β β βββ CreateLinks/
β β β βββ EditLink/
β β βββ page.tsx
β β βββ space.module.css
β βββ account/ # User account settings
β βββ recycleBin/ # Recycle bin page
β
βββ src/
β βββ api/ # API layer
β β βββ client.ts # Axios instance
β β βββ types.ts # TypeScript interfaces
β β βββ modules/ # API functions
β β βββ user.ts
β β βββ group.ts
β β βββ smallLinkPage.ts
β βββ hooks/ # Custom React hooks
β β βββ useAuth.ts
β βββ lib/ # Utilities
β β βββ auth.ts
β β βββ utils.ts
β β βββ middleware-utils.ts
β βββ store/ # Zustand state
β βββ useStore.ts
β
βββ docs/ # Documentation
β βββ COMPONENT_DEVELOPMENT.md
β βββ COMPONENT_ORGANIZATION.md
β βββ TESTING_STRATEGY.md
β βββ TESTING_SETUP.md
β
βββ jest.config.js # Jest configuration
βββ jest.setup.js # Test setup
βββ tsconfig.json # TypeScript config
βββ package.json # Dependencies
π οΈ Getting Started
Prerequisites
- Node.js 18+
- npm or yarn
Installation
# Install dependencies
npm install
# Start development server
npm run dev
# Build for production
npm run build
# Start production server
npm startRunning Tests
# Run all tests
npm test
# Run tests in watch mode
npm test -- --watch
# Run tests with coverage
npm test -- --coverage
# Run E2E tests (when Playwright is set up)
npm run test:e2eπ Testing Metrics
Current Coverage
- Unit Tests: 1 test file, 5 test cases (QRCode component)
- Integration Tests: 0 (planned)
- E2E Tests: 0 (planned)
Target Coverage
- Components: 80%+ coverage
- Utilities: 90%+ coverage
- API modules: 70%+ coverage
- Critical paths: 100% coverage
π§ Configuration
Environment Variables
Create a .env.local file:
NEXT_PUBLIC_API_BASE_URL=http://localhost:8080API Configuration
The API client is configured in src/api/client.ts:
- Base URL can be set via
NEXT_PUBLIC_API_BASE_URL - Default:
/api/short-link/admin/v1 - Create link endpoint:
/api/shortlink/v1/links/create
π Development Guidelines
Component Development
- Page-specific components: Place in
app/[page]/components/ - Shared components: Place in
src/components/common/ - Always add
data-testid: For E2E automation - Follow naming conventions: Use PascalCase for components
- Include CSS Modules: For scoped styling
See docs/COMPONENT_DEVELOPMENT.md for detailed guidelines.
Testing Guidelines
- Unit tests: Co-locate with components (
.test.tsx) - Integration tests: Place in
__tests__/integration/ - E2E tests: Place in
__tests__/e2e/ore2e/ - Use
data-testid: Never use CSS classes for selectors - BDD-style descriptions: Use Given-When-Then pattern
See docs/TESTING_STRATEGY.md for detailed testing guidelines.
π Deployment
Build for Production
npm run buildEnvironment Setup
Set the following environment variables in your deployment environment:
NEXT_PUBLIC_API_BASE_URL=https://api.yourdomain.comπ Documentation
- Component Development Guide - How to create components
- Component Organization - Project structure guidelines
- Testing Strategy - Comprehensive testing approach
- Testing Setup - Testing configuration details
π― Roadmap
Completed β
- All pages converted (Login, Space, Account, RecycleBin)
- All components implemented (QRCode, ChartsInfo, CreateLink, CreateLinks, EditLink)
- API layer complete
- Authentication system
- State management (Zustand)
- Form validation (React Hook Form + Zod)
- Test data IDs embedded in all components
In Progress π
- Backend integration testing
- Additional unit tests
- Integration tests
- E2E tests setup (Playwright)
Planned π
- Playwright E2E test suite
- BDD framework integration (Cucumber.js)
- Performance optimization
- Accessibility improvements
- Error boundaries
- Loading states improvements
π€ Contributing
This project follows best practices for:
- Component organization (co-location pattern)
- Testing (unit, integration, E2E)
- Type safety (TypeScript)
- Code quality (ESLint)
π License
Private project
π Related Documentation
- Next.js Documentation
- React Documentation
- Ant Design Documentation
- Jest Documentation
- Playwright Documentation
Status: β Production-ready (pending backend integration)