diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index de2b8c80..4493d77a 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -59,6 +59,10 @@ jobs:
NODE_ENV: test
JWT_SECRET: testsecret12345678901234567890123
+ - name: Run frontend coverage
+ run: npm run coverage
+ working-directory: FRONTEND
+
e2e-tests:
name: Playwright E2E Tests
runs-on: ubuntu-latest
diff --git a/.gitignore b/.gitignore
index d7de12f3..7b4a6acd 100644
--- a/.gitignore
+++ b/.gitignore
@@ -24,3 +24,4 @@ dist-ssr
*.njsproj
*.sln
*.sw?
+coverage/
diff --git a/.husky/pre-push b/.husky/pre-push
new file mode 100755
index 00000000..0de1b0a4
--- /dev/null
+++ b/.husky/pre-push
@@ -0,0 +1,4 @@
+#!/usr/bin/env sh
+
+echo "Running frontend tests..."
+npm run test --prefix FRONTEND -- --run || exit 1
\ No newline at end of file
diff --git a/FRONTEND/package.json b/FRONTEND/package.json
index 58c38ea8..958739f9 100644
--- a/FRONTEND/package.json
+++ b/FRONTEND/package.json
@@ -8,7 +8,8 @@
"build": "vite build",
"lint": "eslint .",
"preview": "vite preview",
- "test": "vitest"
+ "test": "vitest",
+ "coverage": "vitest run --coverage"
},
"dependencies": {
"@chakra-ui/icons": "^2.0.17",
diff --git a/FRONTEND/src/components/ui/QuickViewModal.jsx b/FRONTEND/src/components/ui/QuickViewModal.jsx
index 9a91a638..1c75d6c7 100644
--- a/FRONTEND/src/components/ui/QuickViewModal.jsx
+++ b/FRONTEND/src/components/ui/QuickViewModal.jsx
@@ -17,7 +17,7 @@ import { Link } from "react-router-dom";
import { useCartStore } from "../../store/cart";
import { useCurrencyStore } from "../../store/currency";
import { formatPrice } from "../../utils/currency";
-
+import React from "react";
const QuickViewModal = ({ isOpen, onClose, product }) => {
const { addToCart } = useCartStore();
const { currency, rates } = useCurrencyStore();
@@ -51,7 +51,9 @@ const QuickViewModal = ({ isOpen, onClose, product }) => {
{formatPrice(product.price, currency, rates)}
- {product.category && {product.category}}
+ {product.category && (
+ {product.category}
+ )}
{product.brand && (
diff --git a/FRONTEND/src/components/ui/ScrollToTop.jsx b/FRONTEND/src/components/ui/ScrollToTop.jsx
index cb2eed3d..d6c97853 100644
--- a/FRONTEND/src/components/ui/ScrollToTop.jsx
+++ b/FRONTEND/src/components/ui/ScrollToTop.jsx
@@ -1,4 +1,4 @@
-import { useEffect, useState } from "react";
+import React, { useEffect, useState } from "react";
import { IconButton, useColorModeValue } from "@chakra-ui/react";
import { LuArrowUp } from "react-icons/lu";
diff --git a/FRONTEND/src/components/ui/tests/ProductCard.test.jsx b/FRONTEND/src/components/ui/tests/ProductCard.test.jsx
index 802c0967..c91f502d 100644
--- a/FRONTEND/src/components/ui/tests/ProductCard.test.jsx
+++ b/FRONTEND/src/components/ui/tests/ProductCard.test.jsx
@@ -1,3 +1,4 @@
+import React from "react";
import { render, screen } from "@testing-library/react";
import userEvent from "@testing-library/user-event";
import { describe, it, expect, vi } from "vitest";
@@ -34,8 +35,7 @@ vi.mock("../../../store/cart", () => ({
}));
vi.mock("../QuickAddModal", () => ({
- default: ({ isOpen }) =>
- isOpen ? Quick Add Modal
: null,
+ default: ({ isOpen }) => (isOpen ? Quick Add Modal
: null),
}));
vi.mock("@chakra-ui/react", async () => {
@@ -86,22 +86,18 @@ describe("ProductCard", () => {
expect(screen.getByText("Quick Add Modal")).toBeInTheDocument();
});
- it("disables Add to Cart button when product is out of stock", () => {
- render(
-
- );
-
- const addToCartButton = screen.getByRole("button", {
- name: `Add ${mockProduct.name} to cart`,
- });
-
- expect(addToCartButton).toBeDisabled();
- expect(addToCartButton).toHaveTextContent("Out of Stock");
+ it("disables Add to Cart button when product is out of stock", () => {
+ render(
+
+ );
+
+ const addToCartButton = screen.getByRole("button", {
+ name: `Add ${mockProduct.name} to cart`,
});
it("applies correct layout properties and transition styles to the card container", () => {
@@ -114,3 +110,4 @@ describe("ProductCard", () => {
expect(computedStyle.transition).toBe("all 0.2s ease-in-out");
});
});
+});
diff --git a/FRONTEND/vitest.config.js b/FRONTEND/vitest.config.js
new file mode 100644
index 00000000..03938019
--- /dev/null
+++ b/FRONTEND/vitest.config.js
@@ -0,0 +1,13 @@
+import { defineConfig } from "vitest/config";
+
+export default defineConfig({
+ test: {
+ environment: "jsdom",
+ globals: true,
+ setupFiles: "./src/setupTests.js",
+ coverage: {
+ provider: "v8",
+ reporter: ["text", "html"],
+ },
+ },
+});
diff --git a/package.json b/package.json
index 8fe7c469..b1f29ade 100644
--- a/package.json
+++ b/package.json
@@ -6,7 +6,8 @@
"build": "npm install && npm install --prefix FRONTEND && npm run build --prefix FRONTEND",
"start": "cross-env NODE_ENV=production node BACKEND/server.js",
"test:e2e": "npx playwright test",
- "test:e2e:ui": "npx playwright test --ui"
+ "test:e2e:ui": "npx playwright test --ui",
+ "prepare": "husky"
},
"type": "module",
"keywords": [],