TidGi-Desktop/features/defaultWiki.feature
lin onetwo 2a5eb349f2
Fix/misc bug (#686)
* refactor: replace time-window echo prevention with mtime+size and content checks

FileSystemWatcher: use recorded mtime+size (lastWriteStats) and saving-state
flag (titlesBeingSaved) to skip own-write echoes, plus content identity fallback.
Removes unreliable setTimeout-based exclude/scheduleFileInclusion.

ipcServerRoutes: replace TTL Map with synchronous Set (ipcPendingTitles),
attach changeCount as revision to change Observable.

ipc-syncadaptor: use lastSavedRevisions for revision-based echo prevention,
batch large syncs via requestIdleCallback.

Also: EditWorkspace controlled input fixes, port field local state, agent
framework config setConfig/persistConfig split, misc value ?? '' fixes.

* Enhance e2e screenshots and test logging

Improve end-to-end test reliability and diagnostics:

- Capture window screenshots for non-BrowserView steps: add captureWindowScreenshot and use it in AfterStep to capture the Electron BrowserWindow via webContents.capturePage() when appropriate; keep existing captureScreenshot for BrowserView steps. (features/supports/webContentsViewHelper.ts, features/stepDefinitions/application.ts)
- Prevent wiki restart race: wait for the wiki worker '[test-id-WIKI_WORKER_STARTED]' marker before restarting to avoid DoubleWikiInstanceError. (features/stepDefinitions/wiki.ts)
- Make git-related test markers more visible by switching logger.debug → logger.info for git init/commit/sync/checkout/revert and git-log rendering markers, ensuring e2e tests can reliably detect these events. (src/services/git/index.ts, src/windows/GitLog/useGitLogData.ts)
- Minor feature test tweak: wait for page to load in defaultWiki.feature before interacting with the editWorkspace window.

These changes reduce flaky screenshots and timing races in tests and improve test marker visibility for e2e detection.

* Enhance e2e screenshots and test logging

Improve end-to-end test reliability and diagnostics:

- Capture window screenshots for non-BrowserView steps: add captureWindowScreenshot and use it in AfterStep to capture the Electron BrowserWindow via webContents.capturePage() when appropriate; keep existing captureScreenshot for BrowserView steps. (features/supports/webContentsViewHelper.ts, features/stepDefinitions/application.ts)
- Prevent wiki restart race: wait for the wiki worker '[test-id-WIKI_WORKER_STARTED]' marker before restarting to avoid DoubleWikiInstanceError. (features/stepDefinitions/wiki.ts)
- Make git-related test markers more visible by switching logger.debug → logger.info for git init/commit/sync/checkout/revert and git-log rendering markers, ensuring e2e tests can reliably detect these events. (src/services/git/index.ts, src/windows/GitLog/useGitLogData.ts)
- Minor feature test tweak: wait for page to load in defaultWiki.feature before interacting with the editWorkspace window.

These changes reduce flaky screenshots and timing races in tests and improve test marker visibility for e2e detection.

* Use startTransition to update port on change

Import startTransition from React and update the port input handler to capture the raw value, update local display state, and defer parsing/setting the workspace port inside startTransition. The handler now parses an empty value as 0, validates the number (non-NaN and >= 0) before calling workspaceSetter, improving responsiveness by marking the workspace update as non-urgent. Also removed an obsolete inline comment.

* Improve E2E, view sync, and wiki IPC robustness

Multiple fixes and improvements across E2E tests, view management, wiki IPC, and workspace handling:

- Docs: add SHOW_E2E_WINDOW env var note to allow visible Electron windows during manual E2E runs.
- Features: simplify/adjust cross-window sync scenario and refine hibernation workspace selectors to avoid collisions with similarly named workspaces.
- E2E steps: make AI-request assertion resilient by polling (backOff); replace brittle DOM-driven tiddler creation with direct TiddlyWiki API calls in browserView step definitions for reliability; add small UI click pause and longer click timeout in ui steps.
- Timeouts: unify global timeout to 25s and derive Playwright short/log wait timeouts from it.
- WebContents helpers: prefer the last child wiki view (active one) when multiple views exist and update comments.
- WikiEmbedTabContent: wake workspace on mount and simplify cleanup to always clear custom bounds on unmount; handle errors.
- Chat UI: hide TabListDropdown in split view.
- Agent instances: default missing agentFrameworkID to 'basicPromptConcatHandler' for older definitions.
- View service: add activelyShownViews set to avoid hiding views that were explicitly shown via showView(); clear stale custom bounds when showing views; avoid moving views offscreen when actively shown; ensure cleanup removes active flag.
- IPC server routes: prefer URL-based workspace ID (resolve correct casing via workspace service) to handle cross-session routing; pass effective workspace ID to route handlers.
- Wiki service: add startup timeout to avoid indefinite hangs waiting for worker boot message.
- IPC sync adaptor: implement titlesBeingSaved/titlesBeingLoaded sets to prevent save-back and SSE echo issues; mark titles when saving/loading and suppress spurious saves.
- Wiki worker IPC routes: replace per-subscriber addEventListener with a shared Subject and single change listener to avoid missed events and cross-window sync bugs; forward subject events to subscribers and log readiness.
- Windows: keep windows hidden during tests by default but allow showing them when SHOW_E2E_WINDOW=1.
- Workspaces: compute next insert order so new wiki workspaces appear at the top of regular workspaces (shift others down).

Overall these changes reduce flakiness in tests, prevent cross-window echo and routing bugs, make view lifecycle handling safer, and improve developer ergonomics for debugging E2E runs.

* fix(e2e): bypass system proxy for git HTTP operations in sync test

Git clone/push/fetch to localhost was routed through the system proxy (port 1080),
which returned 502 Bad Gateway. Add -c http.proxy= to disable proxy for all
HTTP git commands in the sync test step definitions.

* fix: address CI lint errors and Copilot review comments

Lint fixes:
- useOptimisticField: rename *Ref/*Fn vars to *Reference/*Function (unicorn/prevent-abbreviations)
- wiki/index: rename args to arguments_ (unicorn/prevent-abbreviations)
- FileSystemWatcher: use specific type assertion for tiddler fields to avoid no-base-to-string warning
- webContentsViewHelper: rename loop var i to index
- interface.ts: merge duplicate imports from same module (dprint)
- ipc-syncadaptor: expand queueMicrotask callback (dprint)

Copilot review fixes:
- ipcServerRoutes: move subscription to outer scope so Observable teardown
  is returned synchronously from the constructor, preventing subscription leaks
  when observers are disposed before the async IIFE resolves
- useOptimisticField: capture localValue at focus time; on blur only commit
  when user actually changed the value (not when serverValue updated while focused)
- FileSystemWatcher.markSaveComplete: guard scheduleGitNotification behind
  non-empty absoluteFilePath to avoid spurious git notifications on error paths

* fix(e2e): handle corrupt settings.json in cleanup and use filechooser intercept for image upload

- tidgiMiniWindow cleanup: wrap readJson with try/catch so truncated/empty
  settings.json (race between app shutdown write and After hook read) is
  handled gracefully instead of throwing SyntaxError

- application.ts: add 'I prepare to select file ... for file chooser' step
  that registers a Playwright one-shot filechooser handler BEFORE the click
  that triggers fileInput.click(). This prevents the native OS dialog from
  appearing entirely (the chooser is resolved directly with the supplied file).

- talkWithAI.feature: replace two-step 'click then setInputFiles' with the
  new 'prepare filechooser  click' pattern so no OS dialog is shown during
  the AI image attachment test
2026-03-12 21:19:10 +08:00

142 lines
9.2 KiB
Gherkin

Feature: TidGi Default Wiki
As a user
I want app auto create a default wiki workspace for me
So that I can start using wiki immediately
Background:
# Note: tests expect the test wiki parent folder to exist. Run the preparation step before E2E:
# cross-env NODE_ENV=test pnpm dlx tsx scripts/developmentMkdir.ts
Given I cleanup test wiki so it could create a new one on start
When I launch the TidGi application
And I wait for the page to load completely
@wiki
Scenario: Application has default wiki workspace
Then I should see "page body and wiki workspace" elements with selectors:
| element description | selector |
| page body | body |
| wiki workspace | div[data-testid^='workspace-']:has-text('wiki') |
And the window title should contain ""
@wiki
Scenario: Default wiki workspace displays TiddlyWiki content in browser view
And the browser view should be loaded and visible
And I should see " TiddlyWiki" in the browser view content
@wiki @create-main-workspace
Scenario: Create new main workspace via UI from top sidebar
# Prerequisite: app starts with default wiki workspace
Then I should see a "default wiki workspace" element with selector "div[data-testid^='workspace-']:has-text('wiki')"
# Clear previous log markers before waiting for new ones
And I clear log lines containing "[test-id-WORKSPACE_CREATED]"
And I clear log lines containing "[test-id-VIEW_LOADED]"
# Step 1: Click add workspace button in top sidebar
When I click on an "add workspace button" element with selector "#add-workspace-button"
And I switch to "addWorkspace" window
And I wait for the page to load completely
# Step 2: Verify we're on "Create New Wiki" tab and main workspace mode
Then I should see "create new wiki tab and main/sub workspace switch" elements with selectors:
| element description | selector |
| create new wiki tab | button:has-text('') |
| main/sub workspace switch | [data-testid='main-sub-workspace-switch'] |
# Step 4: Enter a different wiki folder name (default "wiki" already exists)
# First clear any existing value in the input field
When I clear text in "wiki folder name input" element with selector "label:has-text('') + div input"
# Then type the new folder name
When I type "wiki2" in "wiki folder name input" element with selector "label:has-text('') + div input"
# Step 5: Click the create button to create the workspace
When I click on a "create wiki button" element with selector "button:has-text('')"
# Wait for workspace to be created using log marker
Then I wait for "workspace created" log marker "[test-id-WORKSPACE_CREATED]"
# Switch back to main window
When I switch to "main" window
# Wait for wiki view to fully load
Then I wait for "view loaded" log marker "[test-id-VIEW_LOADED]"
# Step 7: Verify the new workspace appears in the sidebar
Then I should see a "wiki2 workspace" element with selector "div[data-testid^='workspace-']:has-text('wiki2')"
# Step 8: Verify workspace is functional - click it and check browser view loads
When I click on a "wiki2 workspace button" element with selector "div[data-testid^='workspace-']:has-text('wiki2')"
And the browser view should be loaded and visible
# Verify TiddlyWiki content is displayed in the new workspace
Then I should see " TiddlyWiki" in the browser view content
@wiki @root-tiddler
Scenario: Configure root tiddler to use lazy-load and verify content still loads
# Wait for browser view to be fully loaded first
And the browser view should be loaded and visible
And I should see " TiddlyWiki" in the browser view content
# Now modify Index tiddler with unique test content before configuring root tiddler
When I modify file "wiki-test/wiki/tiddlers/Index.tid" to contain "Test content for lazy-all verification after restart"
# before restart, should not see the new content from fs yet (watch-fs is off by default)
And I should not see "Test content for lazy-all verification after restart" in the browser view content
# Update rootTiddler setting via API to use lazy-all, and ensure watch-fs is disabled
When I update workspace "wiki" settings:
| property | value |
| rootTiddler | $:/core/save/lazy-all |
| enableFileSystemWatch | false |
# Wait for config to be written
Then I wait for "config file written" log marker "[test-id-TIDGI_CONFIG_WRITTEN]"
# Restart the workspace to apply the rootTiddler configuration
When I restart workspace "wiki"
# Verify browser view is loaded and visible after restart
And the browser view should be loaded and visible
# Verify Index tiddler element exists (confirms rootTiddler=lazy-all config is applied)
Then I should see a "Index tiddler" element in browser view with selector "div[data-tiddler-title='Index']"
# Verify the actual content is displayed (confirms lazy-all loaded the file content on restart)
And I should see "Test content for lazy-all verification after restart" in the browser view content
@wiki @move-workspace
Scenario: Move workspace to a new location
# Enable file system watch for testing (default is false in production)
When I update workspace "wiki" settings:
| property | value |
| enableFileSystemWatch | true |
When I open edit workspace window for workspace with name "wiki"
And I switch to "editWorkspace" window
And I wait for the page to load completely
When I click on a "save and sync options accordion" element with selector "[data-testid='preference-section-saveAndSyncOptions']"
Then I should see a "move workspace button" element with selector "button:has-text('')"
# Test the actual move operation - this will trigger a file dialog
When I prepare to select directory in dialog "wiki-test-moved"
And I click on a "move workspace button" element with selector "button:has-text('')"
Then I wait for log markers:
| description | marker |
| workspace moved to wiki-test-moved | [test-id-WORKSPACE_MOVED: |
| workspace restarted after move | [test-id-WORKSPACE_RESTARTED_AFTER_MOVE: |
| watch-fs stabilized after restart | [test-id-WATCH_FS_STABILIZED] |
| SSE ready after restart | [test-id-SSE_READY] |
| view loaded | [test-id-VIEW_LOADED] |
# Verify the workspace was moved to the new location
Then file "wiki/tiddlywiki.info" should exist in "wiki-test-moved"
# Switch back to main window to interact with wiki
Then I switch to "main" window
# Verify Index tiddler is displayed (confirms view is loaded)
Then I should see a "Index tiddler" element in browser view with selector "div[data-tiddler-title='Index']"
# Verify the wiki is working by modifying a file in the new location
When I modify file "wiki-test-moved/wiki/tiddlers/Index.tid" to contain "Content after moving workspace"
Then I wait for tiddler "Index" to be updated by watch-fs
# The content check will automatically wait for IPC to sync
And I should see "Content after moving workspace" in the browser view content
# Move it back to original location for cleanup
# Clear test-id markers to ensure we're waiting for fresh logs from second restart
When I clear test-id markers from logs
And I switch to "editWorkspace" window
And I wait for the page to load completely
# Accordion is still expanded from the first move — do NOT click it again (that would collapse it)
When I prepare to select directory in dialog "wiki-test"
And I click on a "move workspace button" element with selector "button:has-text('')"
Then I wait for log markers:
| description | marker |
| workspace moved back to wiki-test | [test-id-WORKSPACE_MOVED: |
| workspace restarted after move back | [test-id-WORKSPACE_RESTARTED_AFTER_MOVE: |
| watch-fs stabilized after restart back | [test-id-WATCH_FS_STABILIZED] |
| SSE ready after restart back | [test-id-SSE_READY] |
| view loaded after restart back | [test-id-VIEW_LOADED] |
Then file "wiki/tiddlywiki.info" should exist in "wiki-test"
# Switch to main window and wait for view to be ready
Then I switch to "main" window
# Verify the wiki still works after moving back
When I modify file "wiki-test/wiki/tiddlers/Index.tid" to contain "Content after moving back"
Then I wait for tiddler "Index" to be updated by watch-fs
# The content check will automatically wait for IPC to sync
And I should see "Content after moving back" in the browser view content