A full-stack e-commerce bookstore application built with Next.js, MongoDB, and comprehensive end-to-end testing using Playwright.
- User Authentication: Secure login/registration with NextAuth.js
- Book Browsing: Search and filter through available books
- Shopping Cart: Add/remove items, update quantities
- Checkout Process: Multi-step checkout with shipping and payment
- Order Management: View order history and details
- Admin Dashboard: CRUD operations for books and order management
- Server-Side Rendering with Next.js
- RESTful API endpoints
- Responsive Design with SCSS modules
- Session Management with cookies
- Database Integration with MongoDB & Mongoose
- Form Validation with React Hook Form
- Notification System with custom provider
- Component-Based Architecture
- Prerequisites
- Installation
- Environment Setup
- Running the Application
- Testing
- Project Structure
- API Endpoints
- Database Schema
- Deployment
- Contributing
- License
Before you begin, ensure you have the following installed:
- Node.js (v20 or higher)
- npm or yarn
- MongoDB (local installation or MongoDB Atlas account)
- Git
- Clone the repository
git clone https://github.com/yourusername/book-store.git
cd book-store- Install dependencies
npm install- Install Playwright browsers
npx playwright installCreate a .env file in the root directory with the following variables:
MONGODB_URI=mongodb+srv://username:password@cluster.mongodb.net/bookstore
NEXTAUTH_SECRET=your-secret-key-here
NEXTAUTH_URL=http://localhost:3000
NODE_ENV=development
BASE_URL=http://localhost:3000The application requires initial data to function properly. You can:
- Manually create data through the admin dashboard
- Use a seed script (create
pages/api/seed.js- see Database Schema section) - Import sample data directly into MongoDB
Create an admin user in MongoDB:
// In MongoDB shell or Compass
db.users.insertOne({
name: "Admin User",
email: "admin@example.com",
password: "$2a$10$hashed_password_here", // Use bcrypt to hash "admin123"
isAdmin: true,
createdAt: new Date(),
updatedAt: new Date()
})npm run devThe application will be available at http://localhost:3000
# Build the application
npm run build
# Start production server
npm run start# Build and run with Docker Compose
docker-compose up
# Run tests in Docker
docker-compose run testsThis project includes a comprehensive end-to-end testing suite using Playwright with 50+ test cases covering all major functionality.
tests/
βββ auth.spec.ts # Authentication tests (10 tests)
βββ books.spec.ts # Book browsing tests (10 tests)
βββ cart.spec.ts # Shopping cart tests (11 tests)
βββ checkout.spec.ts # Checkout flow tests (17 tests)
βββ dashboard.spec.ts # Admin dashboard tests (11 tests)
βββ pages/ # Page Object Models
β βββ BasePage.ts # Base class with common methods
β βββ LoginPage.ts # Login page object
β βββ RegisterPage.ts # Registration page object
β βββ BooksPage.ts # Books page object
β βββ CartPage.ts # Cart page object
β βββ CheckoutPage.ts # Checkout page object
β βββ AdminPage.ts # Admin dashboard object
βββ playwright.config.ts # Playwright configuration
Tests are organized with tags for selective execution:
@smoke: Critical path tests (quick validation)@functional: Feature-specific tests@regression: Full regression suite@security: Security-related tests
npm test
# or
npm run test:e2e# Authentication tests
npm run test:auth
# Book browsing tests
npm run test:books
# Shopping cart tests
npm run test:cart
# Checkout flow tests
npm run test:checkout
# Admin dashboard tests
npm run test:admin# Run only smoke tests
npm run test:smoke
# Run functional tests
npm run test:functional
# Run regression tests
npm run test:regression# Chromium only
npm run test:chromium
# Mobile browsers
npm run test:mobile# Run tests in headed mode (see browser)
npm run test:headed
# Run tests in UI mode (interactive)
npm run test:ui
# Debug mode (step through tests)
npm run test:debug
# Generate tests using codegen
npm run codegenAfter running tests, view the HTML report:
npm run reportReports are generated in the playwright-report/ directory with:
- Screenshots of failures
- Video recordings of failed tests
- Detailed test execution logs
- Performance metrics
- β User registration with valid data
- β Password mismatch validation
- β Email format validation
- β Password length validation
- β User login with valid credentials
- β Invalid credentials handling
- β Empty field validation
- β Navigation between pages
- β Password masking
- β Session persistence
- β Display books list
- β Search functionality
- β No results handling
- β Clear search filter
- β Add single book to cart
- β Add multiple books to cart
- β View book details
- β Book information accuracy
- β Responsive design
- β Add to cart notification
- β View cart with items
- β View empty cart
- β Update quantity (increase/decrease)
- β Calculate total price
- β Proceed to checkout
- β Cart persistence across tabs
- β Remove items from cart
- β Display item information
- β Quantity button functionality
- β Item link navigation
- β Fill shipping address form
- β Shipping validation errors
- β Persist shipping data
- β Select payment methods (PayPal, Stripe, Cash on Delivery)
- β Navigation between checkout steps
- β Display order summary
- β Edit shipping/payment from review
- β Complete order placement
- β Price calculations
- β End-to-end checkout flows
- β Access dashboard as admin
- β Access control for non-admin users
- β View dashboard statistics
- β Add new book with validation
- β Edit existing book
- β Delete book with confirmation
- β Navigate between tabs
- β View all orders
- β Book form validation
- β Cancel form operations
The project uses the Page Object Model (POM) pattern for maintainable test code:
Common methods inherited by all page objects:
- Navigation helpers
- Element interaction methods
- Wait utilities
- Screenshot capture
- URL verification
import { LoginPage } from './pages/LoginPage';
import { BooksPage } from './pages/BooksPage';
test('User can browse and add books to cart', async ({ page }) => {
const loginPage = new LoginPage(page);
const booksPage = new BooksPage(page);
// Login
await loginPage.goto();
await loginPage.login('test@example.com', 'password123');
// Browse books
await booksPage.goto();
await booksPage.searchBooks('Harry Potter');
// Add to cart
await booksPage.addFirstBookToCart();
// Verify
const cartCount = await booksPage.getCartCount();
expect(cartCount).toBeGreaterThan(0);
});- Use descriptive test names with test case IDs:
test('TC-AUTH-001: User registration with valid data @smoke', async ({ page }) => {
// Test implementation
});- Follow AAA pattern (Arrange, Act, Assert):
test('Add book to cart', async ({ page }) => {
// Arrange
const booksPage = new BooksPage(page);
await booksPage.goto();
// Act
await booksPage.addFirstBookToCart();
// Assert
const cartCount = await booksPage.getCartCount();
expect(cartCount).toBe(1);
});- Use data-testid selectors for reliability:
// Good
await page.locator('[data-testid="add-to-cart"]').click();
// Avoid
await page.locator('.book_button').click();- Clean up after tests when necessary:
test.afterEach(async ({ page }) => {
// Clear cart, logout, etc.
});name: E2E Tests
on: [push, pull_request]
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions/setup-node@v3
with:
node-version: '18'
- name: Install dependencies
run: npm ci
- name: Install Playwright
run: npx playwright install --with-deps
- name: Run tests
run: npm test
- name: Upload test results
if: always()
uses: actions/upload-artifact@v3
with:
name: playwright-report
path: playwright-report/book-store/
βββ components/ # React components
β βββ Banner.js
β βββ CheckoutProgress.js
β βββ ConfirmModal.js
β βββ DropdownMenu.js
β βββ Header.js
β βββ Layout.js
β βββ Notice.js
β βββ Notification.js
β βββ NotificationProvider.js
β βββ ProductItem.js
βββ models/ # MongoDB models
β βββ Order.js
β βββ Product.js
β βββ User.js
βββ pages/ # Next.js pages
β βββ api/ # API routes
β β βββ admin/ # Admin endpoints
β β βββ auth/ # Authentication
β β βββ orders/ # Order management
β β βββ product/ # Product endpoints
β βββ books/ # Book pages
β βββ order/ # Order pages
β βββ cart.js
β βββ dashboard.js # Admin dashboard
β βββ login.js
β βββ payment.js
β βββ placeorder.js
β βββ profile.js
β βββ register.js
β βββ shipping.js
β βββ _app.js
βββ tests/ # E2E tests
β βββ pages/ # Page Object Models
β βββ auth.spec.ts
β βββ books.spec.ts
β βββ cart.spec.ts
β βββ checkout.spec.ts
β βββ dashboard.spec.ts
βββ utils/ # Utility functions
β βββ db.js # Database connection
β βββ Store.js # Global state management
βββ styles/ # SCSS styles
βββ public/ # Static assets
βββ .env # Environment variables
βββ .gitignore
βββ package.json
βββ playwright.config.ts
βββ README.md
POST /api/auth/signup- Register new userPOST /api/auth/[...nextauth]- NextAuth.js endpointsPOST /api/auth/update- Update user profile
GET /api/products- Get all productsGET /api/product/[id]- Get product by ID
POST /api/orders- Create new orderGET /api/orders/[id]- Get order by IDGET /api/orders/history- Get user's order history
GET /api/admin/products- Get all products (admin)POST /api/admin/products- Create new productGET /api/admin/products/[id]- Get product detailsPUT /api/admin/products/[id]- Update productDELETE /api/admin/products/[id]- Delete productGET /api/admin/orders- Get all orders (admin)
- Push to GitHub
git push origin main- Import in Vercel
- Go to vercel.com
- Import your GitHub repository
- Add environment variables
- Deploy
- Fork the repository
- Create your feature branch (
git checkout -b feature/AmazingFeature) - Commit your changes (
git commit -m 'feat: Add some AmazingFeature') - Push to the branch (
git push origin feature/AmazingFeature) - Open a Pull Request
- Write tests for new features
- Maintain code style consistency
- Update documentation as needed
- Ensure all tests pass before submitting PR
- Add appropriate test tags (@smoke, @functional, @regression)
This project is licensed under the MIT License - see the LICENSE file for details.
Furqan Ahmad
- Website: furqanahmad.me
- GitHub: @furqanahmad03
- Next.js team for the amazing framework
- Playwright team for the testing framework
- MongoDB for the database
- All contributors and users
For support, email hfurqan.se@gmail.com or open an issue in the GitHub repository.
The application is optimized for:
- First Contentful Paint: < 1.5s
- Time to Interactive: < 3.0s
- Largest Contentful Paint: < 2.5s
- Cumulative Layout Shift: < 0.1
- Next.js 16.0
- React 19.2
- SCSS Modules
- React Hook Form
- Context API for state management
- Next.js API Routes
- NextAuth.js for authentication
- MongoDB with Mongoose
- bcryptjs for password hashing
- Playwright 1.57
- Page Object Model pattern
- TypeScript for type safety
- Docker & Docker Compose
- GitHub Actions (CI/CD ready)
- Vercel deployment
Happy coding! π
If you find this project helpful, please consider giving it a β on GitHub!