Add try-catch wrapper around ICAL.helpers.updateTimezones() to prevent
crash when Office 365 calendars have malformed timezone data that causes
"Cannot read properties of null (reading 'parent')" error.
When updateTimezones fails, the code now falls back to using the raw
component without timezone updates, allowing calendar events to still
be imported.
Remove early validation that throws when startDate is undefined.
The existing getEffectiveRepeatStartDate() utility already provides
a fallback to '1970-01-01', allowing legacy data without startDate
to work correctly.
Alpine's busybox triggers fail under QEMU emulation on arm/v7,
causing the Docker Hub workflow to fail. 32-bit ARM is rarely
used today, so removing it simplifies the build.
- Use CSS env(titlebar-area-width) for dynamic DPI-aware spacing
- Increase fallback width from 96px to 140px to prevent button overlap
- Add theme-aware semi-transparent background to window controls
Remove translation keys that are no longer used after removing
the legacy pomodoro feature:
- F.FOCUS_MODE.POMODORO_BACK, POMODORO_DISABLE, POMODORO_INFO
- F.POMODORO.* (keep only BREAK_IS_DONE)
- GCF.POMODORO.* (keep only duration-related settings)
- Remove standalone legacy pomodoro feature (entire directory)
- Simplify PomodoroConfig to only duration settings
- Add dialog-pomodoro-settings component for focus mode
- Show gear icon in focus mode when Pomodoro mode is selected
- Remove pomodoro from global settings form
- Update play-button component to remove pomodoro controls
- Update take-a-break service to remove pomodoro reset
- Update task-electron effects to remove pomodoro references
In 'should sync task done state' test, Client A needs to reload after
syncing to see the changes from Client B. Without reload, the UI
still shows the old 'isDone' state even though sync completed.
- Navigate to project after creation (createProject doesn't auto-navigate)
- Expand Projects group and wait for project to appear before navigating
- Wait for URL to change to /project/ route after clicking project
- Use more specific page-title selector to avoid matching old view titles
- Increase timeout for title assertion
- Add waitForStatePersistence utility for sync tests to replace hardcoded delays
- Fix nav-list vs nav-list-tree selector inconsistencies across test files
- Replace waitForTimeout calls with proper element waits and Angular stability checks
- Update selectors.ts constants to use correct nav-list-tree component selector
- Override @conventional-changelog/git-client to ^2.5.1 to fix CVE-2025-59433
- Update glob (via nested deps) to ^11.1.0 to fix CVE-2025-64756
- Update node-forge to ^1.3.3 to fix CVE-2025-12816 & CVE-2025-66030
Implemented navigateToProjectByName in ProjectPage to resolve 'TypeError: navigateToProjectByName is not a function' in webdav-sync-expansion.spec.ts. This method now includes robust logic for expanding the 'Projects' group and multiple fallback strategies for locating project buttons.
Added 1-second delays before triggerSync() calls in webdav-sync-expansion.spec.ts (after marking a task undone) and webdav-sync-full.spec.ts (after task deletion). This mitigates race conditions, allowing local state changes to persist before synchronization, thus reducing test flakiness.
All WebDAV E2E tests are now passing consistently.
- Update WebDAV base URL to use 127.0.0.1 instead of localhost in E2E sync tests. This resolves ECONNREFUSED errors in CI environments where localhost might resolve to IPv6 (::1) while the WebDAV server binds to IPv4.
- Increase various UI interaction timeouts in ProjectPage to improve stability and prevent flakiness in CI environments.
- Isolate WebDAV sync tests with unique folders per test to prevent cross-test interference.
- Fix 'should sync task attachments' by correcting the attachment link selector, updating text expectation, and using force click to bypass UI interception.
- Fix 'should sync task done state' by adding hover action for the done button and correcting the 'isDone' class assertion.
Friday (Jan 10) is in the previous ISO week compared to Wednesday (Jan 15),
so getNewestPossibleDueDate's diffInWeeks check returns -1 and breaks the
loop early. This correctly falls back to task.dueDay.
In contrast, Monday (Jan 13) is in the same ISO week as Wednesday (Jan 15),
so diffInWeeks = 0 and Monday is found correctly.
The tests incorrectly expected fallback behavior when the repeat pattern
doesn't match today. getNewestPossibleDueDate actually returns the most
recent valid occurrence (even if in the past), not null.
Updated tests:
- WEEKLY on Monday: expects Jan 13 (last Monday before Jan 15)
- WEEKLY on Friday: expects Jan 10 (last Friday before Jan 15)
- MONTHLY on 20th: expects Dec 20 (last 20th before Jan 15)
Add a new test suite that uses jasmine.clock().mockDate() to freeze time
at a known date (Wednesday, January 15, 2025). This ensures tests are:
- Deterministic: Same results regardless of when tests run
- Reliable: No flaky tests due to day-of-week dependencies
- Comprehensive: Can test specific scenarios like "Wednesday creating Friday task"
Test scenarios added:
- WEEKLY patterns: Wednesday (matches), Friday (fallback), Monday (fallback)
- MONTHLY patterns: 15th (matches), 20th (fallback)
- DAILY patterns: Every day, every 2 days
- Edge cases: Future startDate (fallback)
- Add test for WEEKLY pattern when today is NOT the selected day
(verifies fallback to task.dueDay)
- Add test for invalid repeatEvery value (0)
(verifies try-catch catches error and falls back gracefully)
- Add test for YEARLY repeat pattern
- Guard against undefined startDate before calling getNewestPossibleDueDate
to prevent throwing errors when startDate is missing from the config
- Wrap the calculation in try-catch for additional safety
- Add comprehensive tests for fallback behavior:
- Fallback to task.dueDay when startDate is undefined
- Fallback to task.dueWithTime when both startDate and dueDay are undefined
- Fallback to Date.now() when no dates are available
- MONTHLY repeat pattern handling
This addresses the PR review feedback about missing validation for the
optional startDate field.
Use getNewestPossibleDueDate() to calculate the correct target day for
scheduling instead of blindly using startDate which always defaults to
today. This ensures that when creating a repeating task, the task is
scheduled for the next valid occurrence matching the repeat pattern,
not just today's date.
For example, if today is Wednesday and you set a task to repeat every
Friday, the task will now be scheduled for Friday instead of Wednesday.
Wait for toggle to be visible after expanding the App Features section
and add a small delay before clicking to ensure the toggle is fully
interactive after the expansion animation.
Tests were failing when run between 23:01 and 23:59 because adding 1 hour
to Date.now() pushed timestamps into the next day, causing isToday() to
return false and dueWithTime to be cleared unexpectedly.
When scheduling tasks via drag-and-drop in the Schedule module, the
reminder was always set to "when it starts" regardless of the user's
configured default reminder setting. Now reads from globalConfig.reminder
.defaultTaskRemindOption instead of hardcoding TaskReminderOptionId.AtStart.
Quick settings now only control the repeat pattern (cycle, frequency,
weekdays), not the start date. Previously, selecting any quick setting
would reset the startDate to today, ignoring user-configured dates.
Wait for data to be loaded before reading start page config in
DefaultStartPageGuard. Previously, the guard would read the default
config value before user settings were loaded from storage.