Files
textbee/web/playwright.config.ts
isra el 0ea85c05e0 feat: clean up app chrome, rebuild footer and fix sidebar overlap
Top bar (app-header):
- Removed the Contribute button. It stays reachable from the footer.
- Removed the theme selector; it moves to the sidebar footer.
- Removed the mobile sheet for signed-in users: it duplicated the bottom tab
  bar for navigation and the avatar menu for identity. Signed-out visitors
  keep it, since auth pages have no tab bar.
The header is now brand on the left, account on the right.

Footer:
- Rebuilt as a slim single bar. A logged-in user is already converted, so the
  app does not need the marketing site's multi-column link farm. It borrows
  that footer's visual language (muted surface, muted-to-foreground hovers,
  green status pill) so the two still read as one product.
- Fixed the "cut by the side nav" bug. The footer was rendered in
  (app)/layout.tsx as a sibling of <main>, so it spanned the full viewport
  while the dashboard's fixed sidebar painted over its left 240px, and the
  fixed mobile tab bar covered its bottom edge. It is now rendered per
  section, inside each content column, with the dashboard copy padded clear
  of the tab bar.

Theme control:
- Moved to the sidebar footer and restyled from a dropdown into a three-way
  Light/Dark/System segmented control, which now has room to show all three
  states at once.

Sidebar icon:
- Dashboard uses LayoutDashboard instead of Home, matching the icon the
  avatar menu already uses for the same destination.

E2e harness, two real fixes found while verifying:
- The suite ran against `next dev`, which compiles routes on demand, so
  parallel workers hitting cold routes timed out at random. Switched to a
  production build; the suite went from 1.3m to ~31s.
- The survey modal (a Math.random() coin flip) and the update-app prompt
  (whenever a mocked device reports an old version) could open over any page.
  A Radix dialog marks the rest of the page aria-hidden while open, so every
  getByRole query found nothing and a different test failed each run. Both are
  now suppressed deterministically in the session helper.
Full suite: 16/16 on four consecutive runs.

New chrome.spec.ts guards the footer geometry against both the sidebar and
the mobile tab bar, asserts the top bar stays reduced, and asserts the
sidebar theme control actually toggles the dark class.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-18 20:21:54 +03:00

49 lines
1.8 KiB
TypeScript

import { defineConfig, devices } from '@playwright/test'
// E2e runs the real Next app but every backend call is intercepted with mocked
// fixtures (see e2e/mock-api.ts). No real backend is ever contacted. The dev
// server is started with a fixed test secret so we can mint a valid NextAuth
// session cookie in tests.
export const TEST_AUTH_SECRET = 'e2e-test-secret-do-not-use-in-prod'
const PORT = 3100
export const BASE_URL = `http://localhost:${PORT}`
export default defineConfig({
testDir: './e2e',
fullyParallel: true,
forbidOnly: !!process.env.CI,
retries: process.env.CI ? 2 : 0,
workers: process.env.CI ? 1 : undefined,
reporter: process.env.CI ? 'github' : 'list',
// Headroom for pages that server-redirect, hydrate, then settle several
// intercepted API calls while workers share one server.
expect: { timeout: 10_000 },
use: {
baseURL: BASE_URL,
trace: 'on-first-retry',
},
projects: [
{ name: 'chromium', use: { ...devices['Desktop Chrome'] } },
],
webServer: {
// Production build, not `next dev`. The dev server compiles routes on
// demand, so parallel workers hitting cold routes paid a multi-second
// first-compile cost and timed out at random. Which tests failed varied
// run to run. `next start` serves prebuilt routes, so the suite is
// deterministic.
command: 'pnpm build && pnpm start',
url: BASE_URL,
reuseExistingServer: !process.env.CI,
timeout: 240_000,
env: {
PORT: String(PORT),
NEXTAUTH_URL: BASE_URL,
NEXTAUTH_SECRET: TEST_AUTH_SECRET,
// Point the app at a backend host that only exists to be intercepted.
NEXT_PUBLIC_API_BASE_URL: 'http://localhost:3999/api/v1',
NEXT_PUBLIC_GOOGLE_CLIENT_ID: 'e2e-google-client-id',
NEXT_PUBLIC_TURNSTILE_SITE_KEY: '1x00000000000000000000AA',
},
},
})