diff --git a/.github/workflows/test-frontend.yml b/.github/workflows/test-frontend.yml new file mode 100644 index 00000000..91a4dda8 --- /dev/null +++ b/.github/workflows/test-frontend.yml @@ -0,0 +1,27 @@ +name: Playwright Tests +on: + push: + branches: [ main ] + pull_request: + branches: [ main ] +jobs: + test: + timeout-minutes: 60 + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + - uses: actions/setup-node@v3 + with: + node-version: 18 + - name: Install dependencies + run: yarn + - name: Install Playwright Browsers + run: yarn playwright install --with-deps + - name: Run Playwright tests + run: yarn playwright test + - uses: actions/upload-artifact@v3 + if: always() + with: + name: playwright-report + path: playwright-report/ + retention-days: 30 diff --git a/frontend/.gitignore b/frontend/.gitignore index 14cd5a9c..5b0c88b2 100644 --- a/frontend/.gitignore +++ b/frontend/.gitignore @@ -37,3 +37,6 @@ next-env.d.ts .vscode/ .idea/ +/test-results/ +/playwright-report/ +/playwright/.cache/ diff --git a/frontend/mockdata/mockConsultants.ts b/frontend/mockdata/mockConsultants.ts new file mode 100644 index 00000000..0158c604 --- /dev/null +++ b/frontend/mockdata/mockConsultants.ts @@ -0,0 +1,10 @@ +import { Variant } from "@/types"; + +export const MockConsultants: Variant[] = [{ + id: 'id', + name: 'Test Consultant', + email: 'test@company.io', + competences: ['Frontend'], + department: 'My Department', + bookings: [{year: 2023, weekNumber: 10, bookedHours: 10}] +}] \ No newline at end of file diff --git a/frontend/package.json b/frontend/package.json index 2fb5f58a..58be589b 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -4,6 +4,7 @@ "private": true, "scripts": { "dev": "next dev", + "start-test": "NEXT_PUBLIC_NO_AUTH=true next dev", "build": "next build", "start": "next start", "lint": "next lint" @@ -31,6 +32,7 @@ "typescript": "5.2.2" }, "devDependencies": { + "@playwright/test": "^1.38.1", "eslint-config-prettier": "^9.0.0", "prettier": "3.0.3" } diff --git a/frontend/playwright.config.ts b/frontend/playwright.config.ts new file mode 100644 index 00000000..e49b24d4 --- /dev/null +++ b/frontend/playwright.config.ts @@ -0,0 +1,77 @@ +import { defineConfig, devices } from '@playwright/test'; + +/** + * Read environment variables from file. + * https://github.com/motdotla/dotenv + */ +// require('dotenv').config(); + +/** + * See https://playwright.dev/docs/test-configuration. + */ +export default defineConfig({ + testDir: './tests', + /* Run tests in files in parallel */ + fullyParallel: true, + /* Fail the build on CI if you accidentally left test.only in the source code. */ + forbidOnly: !!process.env.CI, + /* Retry on CI only */ + retries: process.env.CI ? 2 : 0, + /* Opt out of parallel tests on CI. */ + workers: process.env.CI ? 1 : undefined, + /* Reporter to use. See https://playwright.dev/docs/test-reporters */ + reporter: 'html', + /* Shared settings for all the projects below. See https://playwright.dev/docs/api/class-testoptions. */ + use: { + /* Base URL to use in actions like `await page.goto('/')`. */ + baseURL: 'http://127.0.0.1:3000', + + /* Collect trace when retrying the failed test. See https://playwright.dev/docs/trace-viewer */ + trace: 'on-first-retry', + }, + + /* Configure projects for major browsers */ + projects: [ + { + name: 'chromium', + use: { ...devices['Desktop Chrome'] }, + }, + + { + name: 'firefox', + use: { ...devices['Desktop Firefox'] }, + }, + + { + name: 'webkit', + use: { ...devices['Desktop Safari'] }, + }, + + /* Test against mobile viewports. */ + // { + // name: 'Mobile Chrome', + // use: { ...devices['Pixel 5'] }, + // }, + // { + // name: 'Mobile Safari', + // use: { ...devices['iPhone 12'] }, + // }, + + /* Test against branded browsers. */ + // { + // name: 'Microsoft Edge', + // use: { ...devices['Desktop Edge'], channel: 'msedge' }, + // }, + // { + // name: 'Google Chrome', + // use: { ...devices['Desktop Chrome'], channel: 'chrome' }, + // }, + ], + + /* Run your local dev server before starting the tests */ + webServer: { + command: 'yarn dev', + url: 'http://127.0.0.1:3000', + reuseExistingServer: !process.env.CI, + }, +}); diff --git a/frontend/src/utils/ApiUtils.ts b/frontend/src/auth/fetchWithToken.ts similarity index 73% rename from frontend/src/utils/ApiUtils.ts rename to frontend/src/auth/fetchWithToken.ts index afcab0d9..e78e0804 100644 --- a/frontend/src/utils/ApiUtils.ts +++ b/frontend/src/auth/fetchWithToken.ts @@ -1,7 +1,12 @@ -import { msalInstance } from "@/utils/msalInstance"; +import { msalInstance } from "@/auth/msalInstance"; import { loginRequest } from "@/authConfig"; +import { MockConsultants } from "../../mockdata/mockConsultants"; export async function fetchWithToken(path: string) { + if(process.env.NEXT_PUBLIC_NO_AUTH){ + return mockedCall(path); + } + const account = msalInstance.getActiveAccount(); if (!account) { throw Error( @@ -34,9 +39,15 @@ export async function fetchWithToken(path: string) { try { const response = await fetch(path, options); - const res = await response.json(); - return res; + return await response.json(); } catch (error) { console.error(error); } } + +function mockedCall(path: string){ + if(path.includes('/variants')){ + return MockConsultants; + } +} + diff --git a/frontend/src/utils/msalInstance.ts b/frontend/src/auth/msalInstance.ts similarity index 100% rename from frontend/src/utils/msalInstance.ts rename to frontend/src/auth/msalInstance.ts diff --git a/frontend/src/components/AppProviders.tsx b/frontend/src/components/AppProviders.tsx index cfee9b12..a0837014 100644 --- a/frontend/src/components/AppProviders.tsx +++ b/frontend/src/components/AppProviders.tsx @@ -3,7 +3,7 @@ import { EventType } from "@azure/msal-browser"; import { MsalProvider } from "@azure/msal-react"; import { CssBaseline } from "@mui/material"; import { QueryClient, QueryClientProvider } from "react-query"; -import { msalInstance } from "../utils/msalInstance"; +import { msalInstance } from "@/auth/msalInstance"; import PageLayout from "./PageLayout"; import ThemeRegistry from "./ThemeRegistry/ThemeRegistry"; diff --git a/frontend/src/components/PageLayout.tsx b/frontend/src/components/PageLayout.tsx index caef3e99..8065696b 100644 --- a/frontend/src/components/PageLayout.tsx +++ b/frontend/src/components/PageLayout.tsx @@ -3,9 +3,10 @@ import { AuthenticatedTemplate, UnauthenticatedTemplate, } from "@azure/msal-react"; -import { Box, Container, Grid } from "@mui/material"; +import { Box } from "@mui/material"; import VibesAppBar from "./VibesNavBar"; import SignInSignOutButton from "./vibes-buttons/SignInSignOutButton"; +import React from "react"; export default function PageLayout({ children, @@ -15,9 +16,9 @@ export default function PageLayout({ return (