mirror of
https://github.com/tiddly-gittly/TidGi-Desktop.git
synced 2026-03-09 00:10:31 -07:00
* Create ErrorDuringRelease.md
* Enforce test timeouts and add root tiddler scenario
Set global and step timeouts to 5s (local) and 10s (CI) across cucumber config and step definitions to standardize test execution times. Add a new scenario to verify root tiddler configuration and content loading after restart. Enhance start-e2e-app script to accept or auto-detect test scenario names and pass them to the app.
* Improve error handling for window and view initialization
Enhanced error reporting and handling when browser windows are not ready or fail to register in windowService. Updated focus logic to dynamically retrieve the current browser window, improving reliability during workspace hibernation and wake-up scenarios.
* Remove AfterAll hook and add --exit to e2e tests
Eliminates the AfterAll hook that forced process exit in cleanup.ts to prevent hanging after tests. Adds the --exit flag to the cucumber-js command in the e2e test script to ensure proper test process termination.
* Add step to restart workspace in wiki tests
Introduces a new step definition 'I restart workspace {string}' to programmatically restart a wiki workspace during tests. Updates the root tiddler scenario to use this step for verifying lazy-load behavior after workspace restart, improving test reliability and clarity.
* Centralize and standardize E2E test timeouts
Extracted timeout values into features/supports/timeouts.ts and replaced hardcoded timeouts in step definitions with named constants. This ensures consistent timeout handling across local and CI environments, reduces duplication, and clarifies intent. Also improved workspace update logic to check watch-fs state before restart and cleaned up related log marker handling.
* Improve i18n coverage and add Windows installer log access
Expanded and unified i18n keys for error messages and UI labels across multiple languages. Refactored code to remove hardcoded default values from translation calls. Added a Developer Tools option to open the Windows installer log folder (SquirrelTemp) when running on Windows. Introduced a placeholder file to preserve dynamic i18n keys for error messages.
* Initialize Tidgi mini window before workspace views
Moved the initialization of the Tidgi mini window to occur before initializing all workspace views in main.ts to ensure correct view creation. Added a clarifying comment in DeveloperTools.tsx regarding the SquirrelSetup.log path.
* Refactor Tidgi mini window initialization logic
Tidgi mini window creation now only creates the window; view creation is deferred to initializeAllWorkspaceView. Updated related comments and logging for clarity. Also fixed formatting in French translations and improved documentation for error handling during release.
* Add model feature chips to model selection UI
Introduces a ModelFeatureChip component to visually display model features in the model selector and new model dialog. Updates defaultProviders to include new models with features, and enhances the UI to show feature chips for each model, improving clarity for users selecting models.
* Add image attachment support to chat messages
This update enables users to attach image files to chat messages, including UI changes for file selection and preview, backend persistence of attachments, and prompt concatenation logic to include images in AI requests. It also adds error handling and i18n for model vision support, updates message rendering to display images, and improves logging and API validation for vision-capable models.
* Improve streaming status handling for agent messages
Adds a failsafe to clear streaming status when an agent reaches a terminal state and refines logic to prevent marking completed messages as streaming. Also updates message stream completion in AgentInstanceService to ensure proper cleanup and delivery of IPC messages. Includes new feature tests for message streaming status and image upload scenarios.
* Add cross-window sync feature and test steps
Introduces a new feature file for cross-window synchronization scenarios. Adds step definitions to open workspaces in new windows and execute TiddlyWiki code programmatically. Removes obsolete wiki.ts.backup file and updates agentActions for related actions.
* feat(sync): fix cross-window synchronization via SSE
- Remove overly aggressive echo prevention in backend that blocked all SSE updates
- Backend now forwards all wiki change events to subscribers
- Add comprehensive cross-window sync tests verifying bidirectional updates
- Test main->new window sync and new->main window sync scenarios
- Version bump to 0.13.0-prerelease19
* Improve file attachment handling in chat and tests
Refactors file input handling in chat tests to use Playwright's setInputFiles, updates message sending types to support optional file attachments, and enhances file metadata persistence and logging. Adjusts test expectations and UI logic to better handle and display image attachments, and clarifies combobox value assertions in ExternalAPI tests.
* Add file input validation and improve i18n messages
Added image type and size validation (10MB limit) to file input in InputContainer. Improved image preview logic. Updated French, Japanese, and Russian translations with new error messages for missing/default model and vision support. Enhanced type safety in promptConcatWithImage tests and messagePersistence logging. Fixed race condition in ExternalAPIService lazy initialization. Updated CommitDetailsPanel to use common cancel translation key.
* review
* Update browserView.ts
* Update timeouts.ts
* Update cucumber.config.js
* Update cucumber.config.js
* Move global timeout config to separate module
Extracted global timeout setup from cucumber.config.js to features/supports/timeout-config.ts using setDefaultTimeout. This ensures the timeout is set via code rather than config, improving clarity and maintainability.
* Update newAgent.feature
130 lines
4.9 KiB
TypeScript
130 lines
4.9 KiB
TypeScript
import { After, Before } from '@cucumber/cucumber';
|
|
import fs from 'fs-extra';
|
|
import path from 'path';
|
|
import { makeSlugPath } from '../supports/paths';
|
|
import { clearAISettings } from './agent';
|
|
import { ApplicationWorld } from './application';
|
|
import { clearTidgiMiniWindowSettings } from './tidgiMiniWindow';
|
|
import { clearGitTestData, clearHibernationTestData, clearSubWikiRoutingTestData } from './wiki';
|
|
|
|
Before(async function(this: ApplicationWorld, { pickle }) {
|
|
// Initialize scenario-specific paths
|
|
this.scenarioName = pickle.name;
|
|
this.scenarioSlug = makeSlugPath(pickle.name, 60);
|
|
|
|
const scenarioRoot = path.resolve(process.cwd(), 'test-artifacts', this.scenarioSlug);
|
|
const logsDirectory = path.resolve(scenarioRoot, 'userData-test', 'logs');
|
|
const screenshotsDirectory = path.resolve(logsDirectory, 'screenshots');
|
|
const wikiTestRoot = path.resolve(scenarioRoot, 'wiki-test');
|
|
|
|
// Create necessary directories for this scenario
|
|
await fs.ensureDir(logsDirectory);
|
|
await fs.ensureDir(screenshotsDirectory);
|
|
await fs.ensureDir(wikiTestRoot); // Ensure wiki-test root exists for default wiki creation
|
|
|
|
if (pickle.tags.some((tag) => tag.name === '@ai-setting')) {
|
|
await clearAISettings(scenarioRoot);
|
|
}
|
|
if (pickle.tags.some((tag) => tag.name === '@tidgi-mini-window')) {
|
|
await clearTidgiMiniWindowSettings(scenarioRoot);
|
|
}
|
|
});
|
|
|
|
After(async function(this: ApplicationWorld, { pickle }) {
|
|
// IMPORTANT: Close app FIRST before cleaning up files
|
|
// This releases file locks so wiki folders can be deleted
|
|
if (this.app) {
|
|
try {
|
|
// Close all windows including tidgi mini window before closing the app, otherwise it might hang, and refused to exit until ctrl+C
|
|
const allWindows = this.app.windows();
|
|
|
|
// Try to close windows gracefully with short timeout, then force close
|
|
await Promise.allSettled(
|
|
allWindows.map(async (window) => {
|
|
if (window.isClosed()) return;
|
|
|
|
try {
|
|
// Very short timeout for window close - we'll force close anyway
|
|
await Promise.race([
|
|
window.close(),
|
|
new Promise((_, reject) =>
|
|
setTimeout(() => {
|
|
reject(new Error('Window close timeout'));
|
|
}, 1000)
|
|
),
|
|
]);
|
|
} catch {
|
|
// Window close failed or timed out, ignore and continue
|
|
// Force close will happen at app level
|
|
}
|
|
}),
|
|
);
|
|
|
|
// Try to close app gracefully with short timeout
|
|
try {
|
|
await Promise.race([
|
|
this.app.close(),
|
|
new Promise((_, reject) =>
|
|
setTimeout(() => {
|
|
reject(new Error('App close timeout'));
|
|
}, 1000)
|
|
),
|
|
]);
|
|
} catch {
|
|
// App close failed or timed out, force close immediately
|
|
}
|
|
} catch {
|
|
// Any error in the try block, continue to force close
|
|
} finally {
|
|
// ALWAYS force close, regardless of success/failure above
|
|
// This ensures resources are freed even if graceful close hangs
|
|
try {
|
|
if (this.app) {
|
|
// Force close browser context - this kills all processes
|
|
await Promise.race([
|
|
this.app.context().close({ reason: 'Force cleanup after test' }),
|
|
new Promise((resolve) => setTimeout(resolve, 500)), // 500ms max for force close
|
|
]);
|
|
}
|
|
} catch {
|
|
// Even force close can fail, but we don't care - move on
|
|
}
|
|
|
|
// Clear references immediately
|
|
this.app = undefined;
|
|
this.mainWindow = undefined;
|
|
this.currentWindow = undefined;
|
|
}
|
|
}
|
|
|
|
const scenarioRoot = path.resolve(process.cwd(), 'test-artifacts', this.scenarioSlug);
|
|
|
|
// Clean up settings and test data AFTER app is closed
|
|
if (pickle.tags.some((tag) => tag.name === '@tidgi-mini-window')) {
|
|
await clearTidgiMiniWindowSettings(scenarioRoot);
|
|
}
|
|
if (pickle.tags.some((tag) => tag.name === '@ai-setting')) {
|
|
await clearAISettings(scenarioRoot);
|
|
}
|
|
if (pickle.tags.some((tag) => tag.name === '@subwiki')) {
|
|
await clearSubWikiRoutingTestData(scenarioRoot);
|
|
}
|
|
// Clean up git test data to prevent state pollution between git tests
|
|
// Removes entire wiki folder - it will be recreated on next test start
|
|
if (pickle.tags.some((tag) => tag.name === '@git')) {
|
|
await clearGitTestData(scenarioRoot);
|
|
}
|
|
// Clean up hibernation test data - remove wiki2 folder created during tests
|
|
if (pickle.tags.some((tag) => tag.name === '@hibernation')) {
|
|
await clearHibernationTestData(scenarioRoot);
|
|
}
|
|
// Clean up move workspace test data - remove wiki-test-moved folder
|
|
if (pickle.tags.some((tag) => tag.name === '@move-workspace')) {
|
|
const wikiTestMovedPath = path.resolve(scenarioRoot, 'wiki-test-moved');
|
|
if (await fs.pathExists(wikiTestMovedPath)) {
|
|
await fs.remove(wikiTestMovedPath);
|
|
}
|
|
}
|
|
|
|
// Scenario-specific logs are already in the right place, no need to move them
|
|
});
|