Plugin loader + runner shortcut moves to Ctrl+Shift+Alt+T (the old Ctrl+Shift+T conflicts with the browser "reopen closed tab"). Loader now imports runner.js *without* the cache-busting query so it picks up the same module instance the test files register their suites into — previously the shortcut opened a fresh runner with an empty suites array and reported 0/0 passed. New / fixed coverage: - card-interactions: favorite toggle assertion is now case-insensitive (context menu was capitalized to "Unfavorite"/"Favorite" earlier); done-badge test guards against state.hideDone / hideTagged that would filter the test card off the board; new test for the always-on Mark done / Unmark done toggle on a card without due_date. - context-menu: copy-text action exists; copy-text strips fenced code blocks, image markdown and inline #tags. Mocks navigator.clipboard via Object.defineProperty so the assertion works without a focused / secure-context clipboard. - export: round-trip preserves a custom bucket color (covers the import handler regression that was wiping bucket colors on every test run). - theme: design preset selection persists in localStorage across settings open/close, refreshPresetSelect ignores unknown keys. afterEach restores both hyprcrd-design-active-preset and hyprcrd-design so a test run can't permanently swap the user's design. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
269 lines
11 KiB
Markdown
269 lines
11 KiB
Markdown
# hyprcrd GUI Test Coverage
|
|
|
|
Self-contained in-app test suite. No external dependencies.
|
|
|
|
## Activation
|
|
|
|
- **URL**: append `?test=1`
|
|
- **Keyboard**: `Ctrl+Shift+Alt+T`
|
|
- **Safety**: automatic backup before run, auto-restore after
|
|
- **Visibility**: panel hides during tests so you can watch interactions, shows results after
|
|
- **Sync paused**: background sync and autoSync disabled during tests
|
|
|
|
## Test Files (39 files, ~280 tests)
|
|
|
|
| File | Focus |
|
|
|---|---|
|
|
| `shell.test.js` | Header, footer, toolbar, file inputs |
|
|
| `settings.test.js` | All 7 tabs, open/close, account, behavior, CalDAV, relay, notifications |
|
|
| `board.test.js` | Card rendering, split preview, card lifecycle |
|
|
| `toolbar.test.js` | Filter toggles (done/termine/tagged), superview, sort modes |
|
|
| `buckets.test.js` | Bucket bar rendering, filtering, create/delete |
|
|
| `bucket-context.test.js` | Bucket right-click menu, rename, color, delete options, move-left disabled |
|
|
| `context-menu.test.js` | Card right-click, actions, submenus, close |
|
|
| `card-interactions.test.js` | Tags, due dates, done badges, overdue, favorites, color, bucket, grouping |
|
|
| `filtering.test.js` | Tag AND logic, hierarchical match, unsorted bucket, hide filters |
|
|
| `sorting.test.js` | All 5 sort modes, effectiveDate priority |
|
|
| `state-functions.test.js` | parseTags, getChildren, getGroupCards, recent, favorites, toggleFavorite |
|
|
| `favorites.test.js` | Favorites bucket filtering, todo progress bar, detail split pane |
|
|
| `search.test.js` | Open (Ctrl+K, button), input focus, typing, ESC |
|
|
| `search-logic.test.js` | Tag+text combo search, empty search recent, keyboard nav |
|
|
| `calendar.test.js` | Open, month title, navigation, today, close |
|
|
| `calendar-popup.test.js` | Day click, January/December year wrapping |
|
|
| `rrule.test.js` | RRULE persistence (yearly, weekly+BYDAY, COUNT, UNTIL) |
|
|
| `datepicker.test.js` | Rendering, 42-cell grid, today/selected highlight, Monday start, navigation, year wrap, click, double-click submit |
|
|
| `gallery.test.js` | Open, image count, select-none, close |
|
|
| `help.test.js` | F1 toggle, button, content sections |
|
|
| `multiselect.test.js` | Ctrl+click select/deselect, multiple, click-outside clear |
|
|
| `detail.test.js` | Structure, controls, open, title, ESC, close |
|
|
| `detail-interactions.test.js` | Done toggle, edit from detail, zen mode, backlinks |
|
|
| `editor.test.js` | Structure, open/close, card create |
|
|
| `editor-features.test.js` | Color picker, preview, line numbers, save flow, edit existing |
|
|
| `editor-save.test.js` | Empty title prevention, Ctrl+S, Tab title→body, update existing |
|
|
| `editor-toolbar.test.js` | Bold, italic, todo, heading, hr buttons, auto-continue list on Enter |
|
|
| `snippets.test.js` | All snippets (?dat, ?time, ?now, ?week, ?todo, ?hr, ?h1, ?table, ?code), inline calculator |
|
|
| `image-fullscreen.test.js` | Overlay structure, bindDetailImageFullscreen export |
|
|
| `markdown.test.js` | Basic rendering, wiki links (resolve, broken, case-insensitive), gallery block, todos, stripMd |
|
|
| `markdown-edge.test.js` | Images/headings/lists/code/hr/todos/links after blank lines, multi-paragraph spacing |
|
|
| `undo.test.js` | Color, title, body, due_date revert, delete+recreate, parent_id, bucket, multiple undos, empty stack |
|
|
| `api.test.js` | Cards CRUD, buckets CRUD, auth & misc endpoints |
|
|
| `api-edge.test.js` | XSS in title, empty body, null due_date, nonexistent card, empty bucket name, CSRF, positions |
|
|
| `export.test.js` | JSON ZIP, vault ZIP, round-trip integrity (card count, caldav_uid, tags, due_dates) |
|
|
| `relay.test.js` | Push/poll API (unconfigured state) |
|
|
| `notifications.test.js` | Banner element, localStorage, settings selects |
|
|
| `theme.test.js` | CSS vars, localStorage, applyTheme, themes object |
|
|
|
|
## Coverage Summary
|
|
|
|
### Data Layer
|
|
- [x] parseTags (comma-split, empty, hierarchical)
|
|
- [x] getChildren / getGroupCards
|
|
- [x] getRecent / markRecent (add, front, dedup, cap at 10)
|
|
- [x] getFavorites / toggleFavorite / isFavorite
|
|
- [x] sortedCards all 5 modes (manual, newest, oldest, alpha, tag)
|
|
- [x] effectiveDate priority (due_date > title date > created_at)
|
|
|
|
### Board & Cards
|
|
- [x] Card rendering (data-id, draggable, color bar)
|
|
- [x] Split preview (open/close, empty state, card preview, active highlight)
|
|
- [x] Card create appears, delete disappears, delete clears preview
|
|
- [x] Todo progress bar segments
|
|
- [x] Overdue danger border
|
|
- [x] Done badge
|
|
- [x] Due date pill
|
|
|
|
### Toolbar
|
|
- [x] All filter toggles with active class (done, termine, tagged)
|
|
- [x] Superview toggle with active class
|
|
- [x] Sort mode cycling
|
|
- [x] Superview renders list items
|
|
|
|
### Buckets
|
|
- [x] Bucket bar renders tabs, all special buckets (all, current, journal, favorites, unsorted)
|
|
- [x] Bucket click filters cards
|
|
- [x] New bucket appears, deleted disappears
|
|
- [x] Bucket context menu (rename, color, move-left disabled on first)
|
|
- [x] Empty bucket: single delete option
|
|
- [x] Bucket with cards: both delete options
|
|
- [x] Favorites bucket shows only favorited cards
|
|
|
|
### Filtering
|
|
- [x] Single tag filter
|
|
- [x] Multiple tags AND logic
|
|
- [x] Hierarchical tag parent match
|
|
- [x] Unsorted bucket excludes dated titles
|
|
- [x] hideTermine excludes caldav cards
|
|
- [x] hideTagged excludes tagged cards
|
|
- [x] hideDone excludes #done cards
|
|
|
|
### Context Menu
|
|
- [x] Opens on right-click, closes on click
|
|
- [x] All actions (open, edit, duplicate, due-date, save-md, push-relay, favorite, color, bucket, tags, delete)
|
|
- [x] Color submenu presets
|
|
- [x] Tag submenu with input
|
|
- [x] Favorite toggle
|
|
- [x] Color change via menu
|
|
- [x] Bucket assignment via menu
|
|
- [x] Viewport-aware positioning (opens upward when near bottom)
|
|
|
|
### Search
|
|
- [x] Opens with Ctrl+K and button
|
|
- [x] Input focused on open
|
|
- [x] Typing triggers results
|
|
- [x] Tag-only filter (#tag)
|
|
- [x] Tag + text combined
|
|
- [x] Empty search shows recent
|
|
- [x] Keyboard navigation
|
|
- [x] ESC closes
|
|
|
|
### Calendar
|
|
- [x] Open/close
|
|
- [x] Month title, navigation (prev, next, today)
|
|
- [x] January→December year wrap
|
|
- [x] December→January year wrap
|
|
- [x] Day click
|
|
|
|
### Datepicker
|
|
- [x] Correct month for default value
|
|
- [x] 42 day cells (6-week grid)
|
|
- [x] Today highlight, selected highlight
|
|
- [x] Monday start
|
|
- [x] Month navigation, Dec→Jan year wrap
|
|
- [x] Click day selects, double-click submits
|
|
|
|
### RRULE
|
|
- [x] FREQ=YEARLY persistence
|
|
- [x] FREQ=WEEKLY;BYDAY=MO persistence
|
|
- [x] COUNT persistence
|
|
- [x] UNTIL persistence
|
|
|
|
### Gallery
|
|
- [x] Open/close, image count, select-none
|
|
|
|
### Help
|
|
- [x] F1 toggle, button open, content sections
|
|
|
|
### Multi-Select
|
|
- [x] Bar hidden by default, all action buttons
|
|
- [x] Ctrl+click select/deselect
|
|
- [x] Multiple cards, click-outside clear
|
|
|
|
### Detail View
|
|
- [x] Structure, controls, open via click, title, ESC, close
|
|
- [x] Done toggle saves #done tag
|
|
- [x] Edit opens editor with card data
|
|
- [x] Zen mode button exists
|
|
- [x] Backlinks section exists
|
|
- [x] Split pane button exists
|
|
|
|
### Editor
|
|
- [x] Structure, save buttons, due date, done toggle
|
|
- [x] Opens (add button, board right-click), closes (cancel, ESC)
|
|
- [x] Title focused on open
|
|
- [x] Color presets render and change color
|
|
- [x] Preview pane and toggle
|
|
- [x] Line numbers gutter and toggle
|
|
- [x] Full save flow (title + body → save-close → card exists)
|
|
- [x] Edit existing loads data, update persists
|
|
- [x] Empty/whitespace title blocks save
|
|
- [x] Ctrl+S saves card
|
|
- [x] Tab moves title → body
|
|
- [x] Toolbar: bold, italic, todo, heading, hr buttons
|
|
- [x] Auto-continue bullet list on Enter
|
|
- [x] Auto-continue todo list on Enter
|
|
- [x] Empty bullet cleared on Enter
|
|
|
|
### Snippets & Calculator
|
|
- [x] All snippets: ?dat, ?time, ?now, ?week, ?todo, ?hr, ?h1, ?table, ?code
|
|
- [x] Inline calculator: ?3+5→8, 34+56?→34+56=90, multiplication, division
|
|
|
|
### Markdown
|
|
- [x] Paragraphs, bold, italic, headings, code blocks
|
|
- [x] External links with target=_blank
|
|
- [x] Wiki links: resolve, broken, case-insensitive
|
|
- [x] Gallery fenced block, empty gallery
|
|
- [x] formatTodoItems, checked items
|
|
- [x] stripMd
|
|
- [x] Images/headings/lists/code/hr/todos/wiki-links after blank lines
|
|
- [x] Multiple blank lines spacing, images between blank lines
|
|
|
|
### Undo
|
|
- [x] Color change revert
|
|
- [x] Title, body, due_date revert from editor
|
|
- [x] Delete → recreate with body, color
|
|
- [x] Delete preserves parent_id
|
|
- [x] Bucket assignment revert
|
|
- [x] Multiple sequential undos (stack order)
|
|
- [x] Empty stack no-op
|
|
|
|
### API
|
|
- [x] Cards: GET, GET/meta, POST, PATCH (returns card), DELETE (returns {ok})
|
|
- [x] Tag extraction, due_date persistence, bucket assignment
|
|
- [x] Buckets: GET, POST, PATCH (returns bucket), DELETE
|
|
- [x] Auth status, relay settings, caldav settings, 404
|
|
- [x] XSS in title, empty body, null due_date, nonexistent card
|
|
- [x] Empty bucket name error, CSRF required, GET no CSRF
|
|
- [x] Position create and update
|
|
|
|
### Export/Import
|
|
- [x] JSON ZIP endpoint (status, content-type, ZIP magic)
|
|
- [x] Vault export endpoint
|
|
- [x] Round-trip: card count preserved
|
|
- [x] Round-trip: caldav_uid preserved
|
|
- [x] Round-trip: tags and due_dates preserved
|
|
- [x] parent_id correctly remapped on import
|
|
|
|
### Relay
|
|
- [x] Push without config → error
|
|
- [x] Push without card_id → 400
|
|
- [x] Poll without config → 0 pulled
|
|
|
|
### Notifications
|
|
- [x] Banner element, settings in localStorage
|
|
- [x] Lookahead and time selects
|
|
|
|
### Theme
|
|
- [x] CSS custom properties (8 vars)
|
|
- [x] localStorage persistence
|
|
- [x] applyTheme function, themes object
|
|
- [x] Card layout CSS vars
|
|
|
|
## Not Yet Covered
|
|
|
|
- Drag and drop (card reorder, bucket reorder, search-to-board)
|
|
- Box-select rubber band visual
|
|
- CalDAV sync flow (requires server)
|
|
- Relay push/poll with configured relay (requires relay)
|
|
- File upload (paste, drag into editor)
|
|
- Image fullscreen zoom/pan interaction
|
|
- Zen mode resize handles drag
|
|
- Notification banner dismiss click
|
|
- Calendar hover card popups
|
|
- Calendar appointment/journal creation via double-click
|
|
- Editor divider drag resize
|
|
- Editor image resize handles
|
|
- Superview hover popup system
|
|
- Detail sidebar card navigation
|
|
- Detail image gallery prev/next navigation
|
|
|
|
## Bugs Found & Fixed by Tests
|
|
|
|
1. **Import lost all CalDAV fields** — caldav_uid, tags, due_date, parent_id, relay_uid not preserved on import → CalDAV sync created duplicates
|
|
2. **Import lost parent_id mapping** — grouped cards lost their group after export→import (IDs changed)
|
|
3. **Undo delete lost parent_id** — undo after deleting a grouped card didn't restore group membership
|
|
4. **Undo editor lost due_date** — undo after editing didn't restore previous due_date
|
|
5. **_reloadAll didn't reload buckets** — new/deleted buckets not reflected without manual page reload
|
|
6. **Blank lines broke images in markdown** — `<br>\n` before `![img]()` prevented rendering
|
|
7. **Context menu clipped at viewport bottom** — fixed position calculation, now opens upward
|
|
|
|
## Adding Tests
|
|
|
|
1. Create `yourfeature.test.js` in `public/js/test/`
|
|
2. Import runner: `import { describe, it, expect, ... } from './runner.js'`
|
|
3. Add import to `tests.js`
|
|
4. Update this file
|
|
|
|
Tests don't need manual cleanup — backup is auto-restored after every run.
|
|
Use `csrf()` for API calls. Use `closeAll()` in `afterEach` for UI state.
|
|
Sync is paused during test runs (`window._testRunning`).
|