* fix(issue): prevent crash from orphan issueProviderId (#7135)
The Jira image-headers effect in task-detail-panel subscribed to
selectIssueProviderById without an error handler, so a task with an
issueProviderId pointing at a deleted provider (e.g. after sync
convergence where taskIdsToUnlink didn't cover all local tasks)
propagated the selector throw to Zone.js as a crash dialog. Wrap the
inner selector observable in catchError that logs and falls back to
of(null); the downstream jiraCfg?.isEnabled guard handles the fallback.
Also drop IssueLog.log(issueProviderKey, issueProvider) from the
throwing variant of the selector: providers may carry credentials
(host, token, apiKey) and IssueLog history is exportable.
* fix(focus-mode): sync tray countdown with in-app timer during breaks
Tray title was rebuilt from a cached currentFocusSessionTime that only
refreshed when CURRENT_TASK_UPDATED fired. addTimeSpent is gated on an
active current task, so during focus-mode breaks or task-less focus
sessions the cache froze while the in-app timer kept ticking.
Add the tick action to taskChangeElectron$ so the cache refreshes every
second whenever the focus timer is running.
Fixes#7278
* fix(ci): restore GitHub Actions SHA pins undone by 0e9218bd68
Commit 0e9218bd68 silently reverted PR #7212 (github-actions-minor group
bump) along with its stated sync/client-id work. This restores the 15
workflow files to their pre-revert state.
Actions restored to newer pinned SHAs:
- actions/upload-artifact v7.0.0 -> v7.0.1
- step-security/harden-runner v2.16.1 -> v2.17.0
- softprops/action-gh-release v2.6.1 -> v3.0.0
- signpath/github-action-submit-signing-request v2.0 -> v2.1
- anthropics/claude-code-action v1.0.89 -> v1.0.93
- docker/build-push-action v7.0.0 -> v7.1.0
- easingthemes/ssh-deploy v5.1.1 -> v6.0.3
* fix: restore i18n, UI, and docs work undone by 0e9218bd68
Commit 0e9218bd68 silently reverted the following work alongside its stated
sync/client-id changes. Files where later master commits (fec7b25f23, etc.)
already re-applied the reverted work are intentionally left untouched.
Restored:
- #7232 docs/long-term-plans/location-based-reminders.md (513 lines)
- #7199 Romanian i18n phase 3 (ro.json + ro-md.json, ~1168 lines)
- #7049 Polish translation improvements
- #7143 planner component styling (4 scss files)
- #7211 add-task-bar preserve time estimate when typing title
- #7208 task.reducer roll-up estimates for added subtasks
- #6767 focus-mode pomodoro reset button
- #7205 plugin-dev github-issue-provider TOKEN description
- #7231 mobile-bottom-nav FAB fix
- a4fe03272 iOS keyboard accessory bar (global-theme + dialog-fullscreen-markdown)
- 309670db3 ShortSyntaxEffects undefined guard
- 667a7986f Dropbox PKCE auth comment/behavior
* fix(electron): restore electron + e2e work undone by 0e9218bd68
Commit 0e9218bd68 silently reverted the following electron/e2e work.
Files already re-fixed by later master commits are left as-is:
- e2e/tests/sync/supersync-archive-conflict.spec.ts (de33234976 + 191d129ff3)
Restored:
- e8a3e156eb fix(electron): Linux autostart IDB backing-store recovery
(re-adds electron/clear-stale-idb-locks.ts + start-app.ts wiring)
- 5ce78a5b63 fix(electron): macOS Cmd+Q / Dock > Quit hang
(setIsQuiting + before-quit delegate to close-handler)
- 46e0fa2d01 fix(sync): FILE_SYNC_LIST_FILES IPC contract
(electronAPI.d.ts + local-file-sync + preload + ipc-events)
- ea1ef16307 fix(android): session-only SAF permissions on OEM devices
- 8865dc0a50 test(e2e): supersync parallel-worker stampede guard
(SUPERSYNC_SERVER_HEALTHY env-var fallback + goto retry loop)
- af7c7687e2 test(e2e): block WS-triggered downloads in non-WS specs
- 265b44db5d test(e2e): premature waitForURL on daily-summary
(this is literally the fix the bad commit's message claimed to add)
Conflict resolutions:
- e2e/utils/supersync-helpers.ts: kept the refined getDoneTaskElement
checks from d64014d086 (later than c558bcab5e) while restoring the
goto retry loop from 8865dc0a50.
- electron/start-app.ts: unioned imports (setIsQuiting +
clearStaleLevelDbLocks from theirs, fs from ours).
* fix(sync): restore sync-core work undone by 0e9218bd68
Commit 0e9218bd68 silently reverted parts of several sync fixes. Most
sync-core reverts have already been re-addressed differently on master
by later commits (1f5184f6e7, 05cd875dd6, 09f5ced2c9, 7df43358ab,
d9158d6adb, 32dbc95ed9, 8c3b08e016, f89fe1ebc3) — those files are
intentionally left untouched to avoid reverting master's newer work.
This PR restores only the pieces that are genuinely still missing:
- e8a3e156eb fix(electron): IDB backing-store autoreload (in-app piece)
operation-log-hydrator.service.ts + .spec.ts (the electron/clear-
stale-idb-locks.ts piece was restored in the prior commit)
Plus three low-risk documentation/cleanup restorations:
- operation-sync.util.ts — add "Nextcloud" to isFileBasedProvider JSDoc
- dropbox.ts — restore improved _getRedirectUri JSDoc (667a7986fb)
- dialog-get-and-enter-auth-code.component.ts — restore isNativePlatform
comment explaining why manual code entry flow is used (667a7986fb)
- file-adapter.interface.ts — remove stray "// NEW" comment (46e0fa2d01)
Intentionally NOT restored (master's newer work covers or supersedes):
- sync-trigger.service.ts / sync.effects.ts (05cd875dd6)
- sync-wrapper.service.ts (1f5184f6e7)
- sync-errors.ts (1f5184f6e7 re-added LegacySyncFormatDetectedError)
- file-based-sync-adapter.service.ts + spec (1f5184f6e7 + d9158d6adb)
- file-based-sync.types.ts (1f5184f6e7)
- operation-log.const.ts (32dbc95ed9 bumped IDB_OPEN_RETRIES to 5)
- dialog-sync-initial-cfg.component.ts (f89fe1ebc3)
- Separate JsonParseError and SyncDataCorruptedError handlers in sync wrapper
- Handle corrupted remote data gracefully instead of throwing
- Add getOrGenerateClientId() as unified entry point, eliminating dual injection
of ClientIdService + CLIENT_ID_PROVIDER in snapshot-upload, file-based-encryption,
and sync-hydration services
- Use crypto.getRandomValues() instead of Math.random() for client ID generation
- Warn user when stored client ID is invalid and must be regenerated
- Fix flaky e2e supersync tests (premature waitForURL match on daily-summary URL)
Two sources of flakiness when running the full supersync suite:
1. Health check stampede: with many workers starting simultaneously,
all workers called isServerHealthy() concurrently (up to 24 HTTP
requests at once). This overloaded the server, causing false
negatives — workers got serverHealthyCache=false and skipped all
their tests (up to 192/198 tests). Fix: run the health check once
in globalSetup before workers are forked and store the result in
process.env.SUPERSYNC_SERVER_HEALTHY; workers read the env var
instead of making HTTP requests.
2. ERR_CONNECTION_REFUSED in createSimulatedClient: each supersync
test creates 2-3 browser contexts. Under parallel load the Angular
dev server temporarily refuses connections. Fix: retry page.goto('/')
up to 3 times with 1-2s backoff on ERR_CONNECTION_REFUSED.
Set localStorage flags (onboarding preset, hints, tour, example tasks)
via addInitScript before app boots, preventing onboarding overlays and
example tasks from interfering with e2e tests. Also switch archive
import/subtask specs to use the shared test fixture for proper isolation.
Remove the full welcome tour (Welcome, AddTask, DeleteTask, Projects,
Sync, IssueProviders, ProductivityHelper, FinalCongrats, StartTourAgain)
and keep only the KeyboardNav tour, triggered from the Help menu.
- Delete ShepherdComponent (auto-start on load)
- Strip shepherd-steps.const.ts to KeyboardNav steps only
- Simplify ShepherdService with _initPromise guard and fresh tour on re-open
- Remove 3 tour menu items from Help menu, keep keyboard tour
- Remove waitForEl/waitForElObs$ helpers (unused by KeyboardNav)
- Delete e2e/utils/tour-helpers.ts and all tour dismissal calls
- Clean up stale tour comments across e2e tests
- Fix pre-existing build error: add isFinishDayEnabled to AppFeaturesConfig
type, defaults, form toggle, component signal, and translations
Make MAT_DATE_FORMATS dateInput reactive via getter properties so locale
changes take effect without app reload. Always log uncaught page errors
in E2E tests while keeping verbose console output behind E2E_VERBOSE.
Add eslint-disable comment for interface-required `any` in CustomDateAdapter.
Add response listener to track and report 404 errors in E2E tests.
This is a temporary diagnostic to identify which resources are
returning 404s in CI environment (1,146 occurrences reported).
Logs summary of unique 404 URLs with occurrence counts after each test.
Will be removed once root cause is identified and fixed.
Optimize WebDAV E2E test startup by caching health checks at the
worker level instead of checking in each test file's beforeAll hook.
Changes:
- Create webdav.fixture.ts with worker-level health check caching
- Update 12 WebDAV test files to use new fixture
- Remove redundant beforeAll health check blocks
Impact:
- Reduces health check overhead from ~8s to ~2s when WebDAV unavailable
- Saves ~6 seconds on PR/build CI runs (combined with existing SuperSync optimization)
- Tests automatically skip when WebDAV server is not reachable
Add E2E tests covering the scenario where two clients both migrate from
the old Super Productivity format (pre-operation-log) and then sync.
Tests include:
- Both clients migrated with different data (keep local/remote resolution)
- Both clients migrated with same entity IDs (ID collision handling)
- Archive data preservation after migration + sync (WebDAV only)
New files:
- legacy-migration-helpers.ts: Helper functions for seeding legacy DB
- 4 JSON fixtures for legacy data scenarios
- webdav-legacy-migration-sync.spec.ts: 4 WebDAV tests
- supersync-legacy-migration-sync.spec.ts: 3 SuperSync tests (1 skipped)
Add comprehensive E2E test that verifies legacy data (pre-operation-log
format) migrates correctly when the app starts. The test:
- Seeds legacy 'pf' IndexedDB database with test data before app loads
- Verifies backup file is downloaded during migration
- Validates all data migrates correctly including:
- Tasks with subtasks (parent-child relationships)
- Projects and tags
- Sync provider settings (WebDAV/SuperSync configs)
- Archive data (archiveYoung and archiveOld)
- Time tracking data and notes
Includes comprehensive fixture file with realistic legacy state format.
When importing a backup file locally, archive data (archiveYoung and
archiveOld) was not being persisted to IndexedDB. This caused archived
tasks to be lost after page reload.
Root cause: ArchiveOperationHandler._handleLoadAllData() returns early
for local imports (isRemote=false), expecting the archive to be written
by the backup import flow - but this code never existed.
Fix: Add _writeArchivesToIndexedDB() to BackupService.importCompleteBackup()
that explicitly writes archive data to IndexedDB after dispatching the
loadAllData action.
- Add ArchiveDbAdapter injection to BackupService
- Add _writeArchivesToIndexedDB() private method
- Update misleading comment in ArchiveOperationHandler
- Add unit tests for archive persistence (7 tests)
- Add E2E tests for archive import persistence (3 tests)
- Add test fixture with archive data
Move health check into testRunId fixture so all supersync tests
automatically skip when the server isn't running. Previously, tests
would fail with ECONNREFUSED and count toward the 5-failure limit,
interrupting the entire test run.
SuperSync tests create 2-3 browser contexts per test. Running with
12 workers resulted in 24-36 simultaneous connections overwhelming
the Angular dev server, causing ERR_CONNECTION_REFUSED errors.
Changes:
- Add --workers=3 to e2e:supersync and e2e:supersync:file scripts
- Add documentation to supersync.fixture.ts explaining the issue
SuperSync page object improvements:
- Add networkidle wait before interacting with sync dialog
- Add explicit mat-dialog-container wait before form interaction
- Add toBeAttached() assertions for element stability
- Use toPass() with progressive backoff for dropdown interactions
- Dismiss existing dropdown overlays before retrying
- Add blur() calls in password change dialog for Angular validation
- Add try-catch for fresh client dialog race condition
Task detail tests:
- Add blur() after time input fill to ensure Angular registers
the change before clicking Save
These changes fix intermittent failures when running E2E tests
with multiple workers in parallel.
- Add all page objects to fixtures (plannerPage, syncPage, tagPage, notePage, sideNavPage)
- Create assertion helpers (expectTaskCount, expectTaskVisible, etc.)
- Enhance CLAUDE.md with patterns, import paths, and all fixtures
- Add const assertion to selectors for better TypeScript support
- Fix plugin toggle flakiness by using helper functions with proper
state verification (enablePluginWithVerification, disablePluginWithVerification)
- Fix WebDAV sync tests by handling loading screen in waitForAppReady
and waitForTaskList (app shows loading while syncing/importing)
- Remove unreliable/empty test files: webdav-sync-recurring,
webdav-sync-reminders, webdav-sync-time-tracking
- Remove networkidle waits from work-view.page.ts, project.page.ts
- Remove unnecessary waitForTimeout calls in work-view.page.ts
- Remove add-task input wait from test fixture
These waits were either redundant (Angular stability checks already
handle them) or ineffective (networkidle doesn't work well with
Angular apps). Expected improvement: 20-40% faster test runs.
Add comprehensive improvements to make e2e test development faster and easier:
1. **New Page Objects** - Reduce code duplication and improve maintainability:
- task.page.ts: Task operations (get, mark done, edit, subtasks, etc.)
- settings.page.ts: Settings navigation and plugin management
- dialog.page.ts: Dialog interactions (save, close, date editing, etc.)
- All page objects integrated into test.fixture.ts for easy access
2. **Centralized Selectors** - Single source of truth:
- Expanded constants/selectors.ts with 50+ selectors
- Organized by category (Navigation, Tasks, Dialogs, Settings, etc.)
- Makes selector updates easier when UI changes
3. **Comprehensive Documentation** - Complete e2e/README.md guide:
- Page object usage examples
- Common test patterns
- Best practices and anti-patterns
- Troubleshooting guide
- Step-by-step instructions for writing new tests
These improvements provide a better foundation for AI-assisted test development
and make it faster to add new e2e tests.
Add E2E and integration tests documenting a bug where tasks with
subtasks are lost when:
1. Importing legacy data (pre-operation logs)
2. Archiving via "Finish Day"
3. Exporting again
The archiveYoung ends up empty in the export. Tests will pass
once the bug is fixed.
Files added:
- e2e/fixtures/legacy-archive-subtasks-backup.json
- e2e/tests/import-export/legacy-archive-subtasks.spec.ts
- integration/legacy-archive-subtasks.integration.spec.ts
Increased timeouts and added stability improvements for SuperSync E2E tests to address flakiness and resolve 'Sync already in progress' errors.
- Increased default 'waitForTask' timeout from 45s to 60s in 'supersync-helpers.ts'.
- Increased auto-sync detection timeout in 'SuperSyncPage' from 3s to 5s.
- Added a 1s delay in 'SuperSyncPage.triggerSync' to mitigate race conditions.
Also includes other related E2E and SuperSync server fixes:
- Updated 'test-backup.json' with new config properties.
- Improved error handling in 'import.page.ts' for file dispatch events.
- Added reload and app readiness waits in 'supersync.spec.ts' for time tracking tests.
- Enabled WAL journal mode in 'super-sync-server/src/db.ts' for better database performance.
- Implemented data cleanup for existing test users in 'super-sync-server/src/test-routes.ts' to ensure clean test states.
These changes collectively resolve intermittent failures across the E2E test suite.
- Add 'pree2e' script to build plugins before tests
- Add explicit checks for plugin management initialization
- Improve stability in issue-provider-panel tests
- Ensure baseURL is passed to test context
- Update plugin lockfiles
- Remove all Nightwatch E2E test files and configuration
- Remove chromedriver and nightwatch dependencies from package.json
- Update E2E commands to use Playwright directly without :playwright suffix
- Simplify E2E command structure for better developer experience
- Add @super-productivity/plugin-api package with TypeScript definitions
- Define core plugin interfaces, types, and manifest structure
- Add plugin hooks system for event-driven architecture
- Create plugin API type definitions and constants
- Add documentation and development guidelines