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>
11 KiB
11 KiB
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
- parseTags (comma-split, empty, hierarchical)
- getChildren / getGroupCards
- getRecent / markRecent (add, front, dedup, cap at 10)
- getFavorites / toggleFavorite / isFavorite
- sortedCards all 5 modes (manual, newest, oldest, alpha, tag)
- effectiveDate priority (due_date > title date > created_at)
Board & Cards
- Card rendering (data-id, draggable, color bar)
- Split preview (open/close, empty state, card preview, active highlight)
- Card create appears, delete disappears, delete clears preview
- Todo progress bar segments
- Overdue danger border
- Done badge
- Due date pill
Toolbar
- All filter toggles with active class (done, termine, tagged)
- Superview toggle with active class
- Sort mode cycling
- Superview renders list items
Buckets
- Bucket bar renders tabs, all special buckets (all, current, journal, favorites, unsorted)
- Bucket click filters cards
- New bucket appears, deleted disappears
- Bucket context menu (rename, color, move-left disabled on first)
- Empty bucket: single delete option
- Bucket with cards: both delete options
- Favorites bucket shows only favorited cards
Filtering
- Single tag filter
- Multiple tags AND logic
- Hierarchical tag parent match
- Unsorted bucket excludes dated titles
- hideTermine excludes caldav cards
- hideTagged excludes tagged cards
- hideDone excludes #done cards
Context Menu
- Opens on right-click, closes on click
- All actions (open, edit, duplicate, due-date, save-md, push-relay, favorite, color, bucket, tags, delete)
- Color submenu presets
- Tag submenu with input
- Favorite toggle
- Color change via menu
- Bucket assignment via menu
- Viewport-aware positioning (opens upward when near bottom)
Search
- Opens with Ctrl+K and button
- Input focused on open
- Typing triggers results
- Tag-only filter (#tag)
- Tag + text combined
- Empty search shows recent
- Keyboard navigation
- ESC closes
Calendar
- Open/close
- Month title, navigation (prev, next, today)
- January→December year wrap
- December→January year wrap
- Day click
Datepicker
- Correct month for default value
- 42 day cells (6-week grid)
- Today highlight, selected highlight
- Monday start
- Month navigation, Dec→Jan year wrap
- Click day selects, double-click submits
RRULE
- FREQ=YEARLY persistence
- FREQ=WEEKLY;BYDAY=MO persistence
- COUNT persistence
- UNTIL persistence
Gallery
- Open/close, image count, select-none
Help
- F1 toggle, button open, content sections
Multi-Select
- Bar hidden by default, all action buttons
- Ctrl+click select/deselect
- Multiple cards, click-outside clear
Detail View
- Structure, controls, open via click, title, ESC, close
- Done toggle saves #done tag
- Edit opens editor with card data
- Zen mode button exists
- Backlinks section exists
- Split pane button exists
Editor
- Structure, save buttons, due date, done toggle
- Opens (add button, board right-click), closes (cancel, ESC)
- Title focused on open
- Color presets render and change color
- Preview pane and toggle
- Line numbers gutter and toggle
- Full save flow (title + body → save-close → card exists)
- Edit existing loads data, update persists
- Empty/whitespace title blocks save
- Ctrl+S saves card
- Tab moves title → body
- Toolbar: bold, italic, todo, heading, hr buttons
- Auto-continue bullet list on Enter
- Auto-continue todo list on Enter
- Empty bullet cleared on Enter
Snippets & Calculator
- All snippets: ?dat, ?time, ?now, ?week, ?todo, ?hr, ?h1, ?table, ?code
- Inline calculator: ?3+5→8, 34+56?→34+56=90, multiplication, division
Markdown
- Paragraphs, bold, italic, headings, code blocks
- External links with target=_blank
- Wiki links: resolve, broken, case-insensitive
- Gallery fenced block, empty gallery
- formatTodoItems, checked items
- stripMd
- Images/headings/lists/code/hr/todos/wiki-links after blank lines
- Multiple blank lines spacing, images between blank lines
Undo
- Color change revert
- Title, body, due_date revert from editor
- Delete → recreate with body, color
- Delete preserves parent_id
- Bucket assignment revert
- Multiple sequential undos (stack order)
- Empty stack no-op
API
- Cards: GET, GET/meta, POST, PATCH (returns card), DELETE (returns {ok})
- Tag extraction, due_date persistence, bucket assignment
- Buckets: GET, POST, PATCH (returns bucket), DELETE
- Auth status, relay settings, caldav settings, 404
- XSS in title, empty body, null due_date, nonexistent card
- Empty bucket name error, CSRF required, GET no CSRF
- Position create and update
Export/Import
- JSON ZIP endpoint (status, content-type, ZIP magic)
- Vault export endpoint
- Round-trip: card count preserved
- Round-trip: caldav_uid preserved
- Round-trip: tags and due_dates preserved
- parent_id correctly remapped on import
Relay
- Push without config → error
- Push without card_id → 400
- Poll without config → 0 pulled
Notifications
- Banner element, settings in localStorage
- Lookahead and time selects
Theme
- CSS custom properties (8 vars)
- localStorage persistence
- applyTheme function, themes object
- 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
- Import lost all CalDAV fields — caldav_uid, tags, due_date, parent_id, relay_uid not preserved on import → CalDAV sync created duplicates
- Import lost parent_id mapping — grouped cards lost their group after export→import (IDs changed)
- Undo delete lost parent_id — undo after deleting a grouped card didn't restore group membership
- Undo editor lost due_date — undo after editing didn't restore previous due_date
- _reloadAll didn't reload buckets — new/deleted buckets not reflected without manual page reload
- Blank lines broke images in markdown —
<br>\nbefore![img]()prevented rendering - Context menu clipped at viewport bottom — fixed position calculation, now opens upward
Adding Tests
- Create
yourfeature.test.jsinpublic/js/test/ - Import runner:
import { describe, it, expect, ... } from './runner.js' - Add import to
tests.js - 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).