test: add vitest unit tests, playwright E2E tests, and Forgejo Actions CI #4

Merged
addison merged 22 commits from dev-bot/notebook:feat/testing into main 2026-05-30 12:43:51 -04:00
Collaborator

Adds a full automated test suite with CI.

Vitest Unit Tests (41 tests)

  • Extracted buildRepoTree, matchesSearch, and splitPath from the Svelte component into repo-browser.ts so they can be unit tested
  • Tests cover: path splitting, tree construction (nested folders, sorting, file vs folder), search matching (substring, tokenized, subsequence), and all 6 file operation functions (createFile, createDirectory, renameFile, renameDirectory, deleteFile, deleteDirectory) using mocked FileSystemDirectoryHandle
  • Run with: npm run test:unit

Playwright E2E Tests (17 tests)

Uses page.addInitScript to inject a mock FileSystemDirectoryHandle that intercepts window.showDirectoryPicker — no real filesystem or browser permission prompt needed.

Also stubs indexedDB so the mock handles (which can't be structured-cloned) don't break persistence.

app.test.ts (12 tests):

  • Page load, title, editor visible
  • Open folder → folder name in sidebar, file tree appears
  • Folder/file nodes in tree, selecting a file loads content
  • Folder expand/collapse
  • Search filtering and clear
  • Sidebar collapse/expand

file-ops.test.ts (5 tests):

  • Create new file (inline input → Enter → appears in tree)
  • Create new folder (inline input, Escape to cancel)
  • Rename file via context menu
  • Delete file via context menu (with window.confirm mock)
  • Cancel rename with Escape

Run with: npm run test:e2e

Forgejo Actions CI (.forgejo/workflows/ci.yml)

Two jobs on PR and push to main:

  • unit: npm cisvelte-checkvitest run
  • e2e: npm ci → install Chromium → npm run buildplaywright test

Failed E2E runs upload the Playwright HTML report as an artifact.

Adds a full automated test suite with CI. ## Vitest Unit Tests (41 tests) - Extracted `buildRepoTree`, `matchesSearch`, and `splitPath` from the Svelte component into `repo-browser.ts` so they can be unit tested - Tests cover: path splitting, tree construction (nested folders, sorting, file vs folder), search matching (substring, tokenized, subsequence), and all 6 file operation functions (`createFile`, `createDirectory`, `renameFile`, `renameDirectory`, `deleteFile`, `deleteDirectory`) using mocked `FileSystemDirectoryHandle` - Run with: `npm run test:unit` ## Playwright E2E Tests (17 tests) Uses `page.addInitScript` to inject a mock `FileSystemDirectoryHandle` that intercepts `window.showDirectoryPicker` — no real filesystem or browser permission prompt needed. Also stubs `indexedDB` so the mock handles (which can't be structured-cloned) don't break persistence. **app.test.ts** (12 tests): - Page load, title, editor visible - Open folder → folder name in sidebar, file tree appears - Folder/file nodes in tree, selecting a file loads content - Folder expand/collapse - Search filtering and clear - Sidebar collapse/expand **file-ops.test.ts** (5 tests): - Create new file (inline input → Enter → appears in tree) - Create new folder (inline input, Escape to cancel) - Rename file via context menu - Delete file via context menu (with `window.confirm` mock) - Cancel rename with Escape Run with: `npm run test:e2e` ## Forgejo Actions CI (`.forgejo/workflows/ci.yml`) Two jobs on PR and push to main: - **unit**: `npm ci` → `svelte-check` → `vitest run` - **e2e**: `npm ci` → install Chromium → `npm run build` → `playwright test` Failed E2E runs upload the Playwright HTML report as an artifact.
- Replace oversized 64px header with slim 48px app bar
- Implement full-viewport app shell (header + sidebar + editor, no page scroll)
- Sidebar: 240px fixed width, collapses to 44px rail with smooth CSS transition
- Sidebar shows repo name or 'Local draft' icon, file tree with search, footer count
- Rail mode: › toggle button + vertical 'DRAFT' hint text
- Remove always-visible notice bar; errors shown inline in header only
- Editor area: no card chrome, max-width 760px centered canvas (iA Writer style)
- Status bar: slim 28px bottom bar with save status + file path
- Local draft state: centered doc icon + label + hint, '+ Open folder' CTA
- Keep all TypeScript logic 100% intact (repo browser, autosave, etc.)
- Update app.css: html/body fill viewport with overflow:hidden for proper shell

Co-authored-by: Shelley <shelley@exe.dev>
Co-authored-by: Shelley <shelley@exe.dev>
Co-authored-by: Shelley <shelley@exe.dev>
Co-authored-by: Shelley <shelley@exe.dev>
Co-authored-by: Shelley <shelley@exe.dev>
Co-authored-by: Shelley <shelley@exe.dev>
Co-authored-by: Shelley <shelley@exe.dev>
Co-authored-by: Shelley <shelley@exe.dev>
Co-authored-by: Shelley <shelley@exe.dev>
Co-authored-by: Shelley <shelley@exe.dev>
Co-authored-by: Shelley <shelley@exe.dev>
Co-authored-by: Shelley <shelley@exe.dev>
fix(e2e): disable server reuse and set global timeout to prevent stale-server failures
All checks were successful
CI / Unit tests (pull_request) Successful in 27s
CI / E2E tests (pull_request) Successful in 56s
d6b98219cc
Co-authored-by: Shelley <shelley@exe.dev>
chore: merge main into feat/testing, resolve conflicts keeping testing-branch improvements
All checks were successful
CI / Unit tests (pull_request) Successful in 34s
CI / E2E tests (pull_request) Successful in 53s
437bdac7ce
Co-authored-by: Shelley <shelley@exe.dev>
Sign in to join this conversation.
No reviewers
No labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
kwila/notebook!4
No description provided.