Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,13 @@ lerna-debug.log*

node_modules
dist
playwright-report
test-results
dist-ssr
*.local

# Environment variables
.auth
.env
.env.local
.env.*.local
Expand Down
43 changes: 43 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,49 @@ output in `dist/` — deploy to any static host.

---

## // browser testing + screenshots

Playwright is configured for local browser checks and screenshot capture.

First-time setup:

```sh
npm install
npx playwright install chromium
# Linux only, if browser system dependencies are missing:
# npx playwright install --with-deps chromium
```

Run the e2e smoke test:

```sh
npm run test:e2e
```

Useful variants:

```sh
npm run test:e2e:headed # run with a visible Chromium window
npm run test:e2e:ui # open Playwright's interactive UI
npm run test:e2e:screenshots # concise screenshot-focused run
```

By default Playwright starts Vite on `http://127.0.0.1:8081` with safe local Supabase placeholders, which is enough for unauthenticated shell screenshots. Override with:

```sh
PLAYWRIGHT_PORT=5173 npm run test:e2e
PLAYWRIGHT_BASE_URL=http://127.0.0.1:5173 npm run test:e2e
```

Artifacts:
- HTML report: `playwright-report/`
- test output, screenshots, traces, and videos: `test-results/e2e/`
- the smoke test writes `auth-shell.png` under its per-test output directory.

For authenticated visual checks, create a Playwright storage state locally and pass it via env (for example `PLAYWRIGHT_AUTH_STORAGE=.auth/user.json`). Do not commit auth state or Supabase secrets. The Quoterm edit-paper Save/Sync feedback anchoring test is scaffolded in `tests/e2e/app-smoke.spec.ts` and should be completed with stable test vault/item fixture IDs.

---

## // structure

```
Expand Down
64 changes: 64 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

7 changes: 6 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,11 @@
"preview": "vite preview",
"deploy": "bun run build && gh-pages -d dist",
"test": "vitest run",
"test:watch": "vitest"
"test:watch": "vitest",
"test:e2e": "playwright test",
"test:e2e:headed": "playwright test --headed",
"test:e2e:ui": "playwright test --ui",
"test:e2e:screenshots": "playwright test --project=chromium --reporter=list"
},
"dependencies": {
"@hookform/resolvers": "^3.10.0",
Expand Down Expand Up @@ -86,6 +90,7 @@
},
"devDependencies": {
"@eslint/js": "^9.32.0",
"@playwright/test": "^1.61.1",
"@tailwindcss/typography": "^0.5.19",
"@testing-library/jest-dom": "^6.9.1",
"@testing-library/react": "^16.3.2",
Expand Down
41 changes: 41 additions & 0 deletions playwright.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import { defineConfig, devices } from '@playwright/test';

const PORT = Number(process.env.PLAYWRIGHT_PORT ?? 8081);
const BASE_URL = process.env.PLAYWRIGHT_BASE_URL ?? `http://127.0.0.1:${PORT}`;

export default defineConfig({
testDir: './tests/e2e',
fullyParallel: true,
forbidOnly: !!process.env.CI,
retries: process.env.CI ? 2 : 0,
workers: process.env.CI ? 1 : undefined,
reporter: [['html', { open: 'never' }], ['list']],
use: {
baseURL: BASE_URL,
trace: 'on-first-retry',
screenshot: 'only-on-failure',
video: 'retain-on-failure',
storageState: process.env.PLAYWRIGHT_AUTH_STORAGE,
},
outputDir: 'test-results/e2e',
webServer: process.env.PLAYWRIGHT_BASE_URL
? undefined
: {
command: `npm run dev -- --host 127.0.0.1 --port ${PORT} --strictPort`,
url: BASE_URL,
reuseExistingServer: !process.env.CI,
timeout: 120_000,
env: {
// Safe local placeholders are enough for unauthenticated shell/screenshot tests.
VITE_SUPABASE_URL: process.env.VITE_SUPABASE_URL ?? 'https://example.supabase.co',
VITE_SUPABASE_PUBLISHABLE_KEY:
process.env.VITE_SUPABASE_PUBLISHABLE_KEY ?? 'local-playwright-placeholder',
},
},
projects: [
{
name: 'chromium',
use: { ...devices['Desktop Chrome'] },
},
],
});
23 changes: 23 additions & 0 deletions tests/e2e/app-smoke.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import { test, expect } from '@playwright/test';

test('renders the unauthenticated app shell and captures a screenshot', async ({ page }, testInfo) => {
await page.goto('/');

await expect(page.getByRole('heading', { name: /refhub\.io/i })).toBeVisible();
await expect(page.getByRole('button', { name: /continue_with_google/i })).toBeVisible();
await expect(page.getByRole('button', { name: /continue_with_github/i })).toBeVisible();

await page.screenshot({
path: testInfo.outputPath('auth-shell.png'),
fullPage: true,
});
});

test.describe('Quoterm feedback anchoring scaffold', () => {
test.skip('edit-paper Save/Sync feedback visual check requires authenticated fixture data', async () => {
// Follow-up for PR #139: set PLAYWRIGHT_AUTH_STORAGE and add stable
// PLAYWRIGHT_TEST_VAULT_ID / item fixture data before exercising the edit-paper
// Save/Sync feedback anchoring interaction. The local setup now supports the
// browser, storageState, and screenshot capture needed for that test.
});
});
1 change: 1 addition & 0 deletions vite.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ export default defineConfig(({ mode }) => ({
environment: "jsdom",
setupFiles: "./src/test/setup.ts",
css: true,
exclude: ["tests/e2e/**", "node_modules/**", "dist/**"],
},
build: {
rollupOptions: {
Expand Down