diff --git a/.env.example b/.env.example
index 2c5cbbf..904c38c 100644
--- a/.env.example
+++ b/.env.example
@@ -1,2 +1,3 @@
DATABASE_URL=postgresql://postgres:postgres@localhost:5432/postgres
-EMAIL=example@example.com
\ No newline at end of file
+EMAIL=example@example.com
+PORT=3000
\ No newline at end of file
diff --git a/.gitignore b/.gitignore
index b9f8d23..ef4ac47 100644
--- a/.gitignore
+++ b/.gitignore
@@ -35,4 +35,7 @@ yarn-error.log*
*.tsbuildinfo
next-env.d.ts
-.env
\ No newline at end of file
+.env
+
+# tests
+/test-results/*
\ No newline at end of file
diff --git a/.husky/pre-commit b/.husky/pre-commit
index a2389f0..53c34be 100755
--- a/.husky/pre-commit
+++ b/.husky/pre-commit
@@ -1,8 +1,9 @@
#!/usr/bin/env sh
. "$(dirname -- "$0")/_/husky.sh"
-yarn audit
+#yarn audit
yarn format
yarn lint
yarn typecheck
+yarn test
yarn build
\ No newline at end of file
diff --git a/.vscode/settings.json b/.vscode/settings.json
new file mode 100644
index 0000000..d7cb347
--- /dev/null
+++ b/.vscode/settings.json
@@ -0,0 +1,3 @@
+{
+ "WillLuke.nextjs.hasPrompted": true
+}
diff --git a/app/components/Analytics/Analytics.tsx b/app/components/Analytics/Analytics.tsx
new file mode 100644
index 0000000..e2bd3d5
--- /dev/null
+++ b/app/components/Analytics/Analytics.tsx
@@ -0,0 +1,7 @@
+import { Paper } from '@mui/material';
+
+export function Analytics() {
+ return (
+ To do
+ );
+}
diff --git a/app/page.spec.ts b/app/page.spec.ts
new file mode 100644
index 0000000..c823a7b
--- /dev/null
+++ b/app/page.spec.ts
@@ -0,0 +1,37 @@
+import { expect, test } from '@playwright/test';
+import 'dotenv/config';
+
+test.describe('Home component tests', () => {
+ test.beforeEach(async ({ page }) => {
+ await page.goto(`http://localhost:${process.env.PORT}/`);
+ });
+
+ test('should display Dashboard content by default', async ({ page }) => {
+ await expect(page.locator('text=Dashboard')).toBeVisible();
+ });
+
+ test('should switch to Dashboard content when Dashboard tab is clicked', async ({
+ page
+ }) => {
+ await page.click('text=Analytics');
+ await page.click('text=Dashboard');
+
+ await expect(page.locator('text=Dashboard')).toBeVisible();
+ });
+
+ test('should switch to Analytics content when Analytics tab is clicked', async ({
+ page
+ }) => {
+ await page.click('text=Analytics');
+
+ await expect(page.locator('text=Analytics')).toBeVisible();
+ });
+
+ test('should switch to Settings content when Settings tab is clicked', async ({
+ page
+ }) => {
+ await page.click('text=Settings');
+
+ await expect(page.locator('text=Settings')).toBeVisible();
+ });
+});
diff --git a/app/page.tsx b/app/page.tsx
index f0be2b5..8d054d2 100644
--- a/app/page.tsx
+++ b/app/page.tsx
@@ -1,20 +1,13 @@
'use client';
import { TabContext, TabList, TabPanel } from '@mui/lab';
-import { Paper, Tab } from '@mui/material';
+import { Tab } from '@mui/material';
import { Suspense, useState } from 'react';
import { ProfileContextProvider } from '../contexts/ProfileContextProvider';
+import { Analytics } from './components/Analytics/Analytics';
import Dashboard from './components/Dashboard/Dashboard';
import Settings from './components/Settings/Settings';
-function Analytics() {
- return (
-
- Analytics
-
- );
-}
-
enum TabValue {
DASHBOARD = 'DASHBOARD',
ANALYTICS = 'ANALYTICS',
diff --git a/package.json b/package.json
index 89777d8..5e00625 100644
--- a/package.json
+++ b/package.json
@@ -10,6 +10,7 @@
"format": "prettier --config .prettierrc 'app/' --write",
"audit": "npm audit",
"typecheck": "tsc --noEmit",
+ "test": "playwright test",
"prepare": "husky install",
"migrate": "npx prisma migrate dev",
"generate": "npx prisma generate",
@@ -20,8 +21,10 @@
"@emotion/styled": "^11.11.0",
"@mui/lab": "^5.0.0-alpha.170",
"@mui/material": "^5.15.6",
+ "@playwright/test": "^1.45.1",
"@prisma/client": "5.8.1",
"@vercel/analytics": "^1.1.2",
+ "dotenv": "^16.4.5",
"nanoid": "^5.0.4",
"next": "^14.2.3",
"react": "^18",
diff --git a/yarn.lock b/yarn.lock
index 63ff8ce..6a93d97 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -907,6 +907,17 @@ __metadata:
languageName: node
linkType: hard
+"@playwright/test@npm:^1.45.1":
+ version: 1.45.1
+ resolution: "@playwright/test@npm:1.45.1"
+ dependencies:
+ playwright: "npm:1.45.1"
+ bin:
+ playwright: cli.js
+ checksum: ba214addee06e846041b819b8bcc2b04dae1beb36d05cd0942bb0fc7f9742002c881e2058b75aba37a8baef9a3aaff66e818b20b8013e9020d2cc28ff0c655d7
+ languageName: node
+ linkType: hard
+
"@popperjs/core@npm:^2.11.8":
version: 2.11.8
resolution: "@popperjs/core@npm:2.11.8"
@@ -1692,6 +1703,7 @@ __metadata:
"@emotion/styled": "npm:^11.11.0"
"@mui/lab": "npm:^5.0.0-alpha.170"
"@mui/material": "npm:^5.15.6"
+ "@playwright/test": "npm:^1.45.1"
"@prisma/client": "npm:5.8.1"
"@types/node": "npm:^20"
"@types/react": "npm:^18"
@@ -1699,6 +1711,7 @@ __metadata:
"@typescript-eslint/eslint-plugin": "npm:^6.19.1"
"@vercel/analytics": "npm:^1.1.2"
autoprefixer: "npm:^10.0.1"
+ dotenv: "npm:^16.4.5"
eslint: "npm:^8"
eslint-config-next: "npm:14.1.0"
eslint-config-prettier: "npm:^9.1.0"
@@ -2230,6 +2243,13 @@ __metadata:
languageName: node
linkType: hard
+"dotenv@npm:^16.4.5":
+ version: 16.4.5
+ resolution: "dotenv@npm:16.4.5"
+ checksum: 48d92870076832af0418b13acd6e5a5a3e83bb00df690d9812e94b24aff62b88ade955ac99a05501305b8dc8f1b0ee7638b18493deb6fe93d680e5220936292f
+ languageName: node
+ linkType: hard
+
"eastasianwidth@npm:^0.2.0":
version: 0.2.0
resolution: "eastasianwidth@npm:0.2.0"
@@ -2904,6 +2924,16 @@ __metadata:
languageName: node
linkType: hard
+"fsevents@npm:2.3.2":
+ version: 2.3.2
+ resolution: "fsevents@npm:2.3.2"
+ dependencies:
+ node-gyp: "npm:latest"
+ checksum: be78a3efa3e181cda3cf7a4637cb527bcebb0bd0ea0440105a3bb45b86f9245b307dc10a2507e8f4498a7d4ec349d1910f4d73e4d4495b16103106e07eee735b
+ conditions: os=darwin
+ languageName: node
+ linkType: hard
+
"fsevents@npm:~2.3.2":
version: 2.3.3
resolution: "fsevents@npm:2.3.3"
@@ -2914,6 +2944,15 @@ __metadata:
languageName: node
linkType: hard
+"fsevents@patch:fsevents@npm%3A2.3.2#optional!builtin":
+ version: 2.3.2
+ resolution: "fsevents@patch:fsevents@npm%3A2.3.2#optional!builtin::version=2.3.2&hash=df0bf1"
+ dependencies:
+ node-gyp: "npm:latest"
+ conditions: os=darwin
+ languageName: node
+ linkType: hard
+
"fsevents@patch:fsevents@npm%3A~2.3.2#optional!builtin":
version: 2.3.3
resolution: "fsevents@patch:fsevents@npm%3A2.3.3#optional!builtin::version=2.3.3&hash=df0bf1"
@@ -4811,6 +4850,30 @@ __metadata:
languageName: node
linkType: hard
+"playwright-core@npm:1.45.1":
+ version: 1.45.1
+ resolution: "playwright-core@npm:1.45.1"
+ bin:
+ playwright-core: cli.js
+ checksum: 607ad31ce1e85e2042107954eeed2cb7de5f387b42d9c8c19baa5c1ea4c2ea621bf233094ed86be45de625eeece33b280847ff641ff1bb9acaddee040e17bea1
+ languageName: node
+ linkType: hard
+
+"playwright@npm:1.45.1":
+ version: 1.45.1
+ resolution: "playwright@npm:1.45.1"
+ dependencies:
+ fsevents: "npm:2.3.2"
+ playwright-core: "npm:1.45.1"
+ dependenciesMeta:
+ fsevents:
+ optional: true
+ bin:
+ playwright: cli.js
+ checksum: 549e8621b120258ff53e93fcf3b2994a835aa084097ea533a9f4b53ff993308f3617cf00943c6975f88b66068890a6bf9d61b4ffdd73b7d8f45a5d284b6f284b
+ languageName: node
+ linkType: hard
+
"postcss-import@npm:^15.1.0":
version: 15.1.0
resolution: "postcss-import@npm:15.1.0"