diff --git a/docker-compose.override.yml b/docker-compose.override.yml index 0751abe901..25ac547f5d 100644 --- a/docker-compose.override.yml +++ b/docker-compose.override.yml @@ -1,5 +1,4 @@ services: - # Local services are available on their ports, but also available on: # http://api.localhost.tiangolo.com: backend # http://dashboard.localhost.tiangolo.com: frontend @@ -67,16 +66,16 @@ services: - run - --reload - "app/main.py" - develop: - watch: - - path: ./backend - action: sync - target: /app - ignore: - - ./backend/.venv - - .venv - - path: ./backend/pyproject.toml - action: rebuild + # develop: + # watch: + # - path: ./backend + # action: sync + # target: /app + # ignore: + # - ./backend/.venv + # - .venv + # - path: ./backend/pyproject.toml + # action: rebuild # TODO: remove once coverage is done locally volumes: - ./backend/htmlcov:/app/htmlcov diff --git a/frontend/tests/dashboard.spec.ts b/frontend/tests/dashboard.spec.ts new file mode 100644 index 0000000000..6cc1f20826 --- /dev/null +++ b/frontend/tests/dashboard.spec.ts @@ -0,0 +1,84 @@ +import { expect, test } from "@playwright/test"; +import { randomEmail, randomPassword } from "./utils/random"; +import { signUpNewUser, logInUser, logOutUser } from "./utils/user"; + +test.describe("Dashboard page", () => { + test("is visible after login", async ({ page }) => { + const email = randomEmail(); + const password = randomPassword(); + + // Sign up a new user + await signUpNewUser(page, "Playwright Dashboard Test", email, password); + + // Log in with the new user + await logInUser(page, email, password); + + // Navigate to dashboard (root path) + await page.goto("/"); + // Debug: take screenshot if fails + try { + await expect( + page.getByText("Welcome back, nice to see you again!") + ).toBeVisible({ timeout: 10000 }); + } catch (e) { + await page.screenshot({ + path: "dashboard-visible-after-login-fail.png", + fullPage: true, + }); + throw e; + } + // Check for greeting (user's name or email) + await expect(page.getByText(/^Hi, /)).toBeVisible({ timeout: 10000 }); + // Check for at least one button (UI loaded) + const buttons = await page.getByRole("button").all(); + expect(buttons.length).toBeGreaterThan(0); + }); + + test("redirects to login when not authenticated", async ({ page }) => { + await page.goto("/"); + // Wait for redirect to /login + await page.waitForURL("/login", { timeout: 10000 }); + // Debug: take screenshot if fails + try { + await expect(page.getByPlaceholder("Email")).toBeVisible({ + timeout: 10000, + }); + await expect( + page.getByPlaceholder("Password", { exact: true }) + ).toBeVisible({ timeout: 10000 }); + } catch (e) { + await page.screenshot({ + path: "dashboard-redirect-login-fail.png", + fullPage: true, + }); + throw e; + } + }); + + test("user can log out from dashboard", async ({ page }) => { + const email = randomEmail(); + const password = randomPassword(); + + // Sign up and log in + await signUpNewUser(page, "Playwright Logout Test", email, password); + await logInUser(page, email, password); + + // Log out + await logOutUser(page); + // Debug: take screenshot if fails + try { + await expect(page.getByPlaceholder("Email")).toBeVisible({ + timeout: 10000, + }); + await expect( + page.getByPlaceholder("Password", { exact: true }) + ).toBeVisible({ timeout: 10000 }); + } catch (e) { + await page.screenshot({ + path: "dashboard-logout-login-fail.png", + fullPage: true, + }); + throw e; + } + }); +}); diff --git a/scripts/generate-client.sh b/scripts/generate-client.sh old mode 100644 new mode 100755