fix: address PR #1831 review findings for webgl-context-management

- Remove unused fireEvent import from DisplaySettings test
- Add i18n helper text below GPU acceleration dropdown (en/fr)
- Replace positional selectCallbacks array with Map keyed by Select id
- Move debugLog after delete in terminal-session-store cleanup timer
- Remove redundant hasExited guard in pty-manager synchronous write path

Co-Authored-By: Claude Opus 4.6 <[email protected]>
This commit is contained in:
AndyMik90
2026-02-17 15:32:44 +01:00
co-authored by Claude Opus 4.6
parent 9e276c4757
commit e17137e937
6 changed files with 34 additions and 27 deletions
@@ -663,9 +663,9 @@ export class TerminalSessionStore {
// Keep the ID in pendingDelete for a short time to handle any in-flight
// async operations, then clean up to prevent memory leaks
const timer = setTimeout(() => {
debugLog('[TerminalSessionStore] Cleanup timer fired for:', sessionId,
'removing from pendingDelete. Remaining:', this.pendingDelete.size - 1);
this.pendingDelete.delete(sessionId);
debugLog('[TerminalSessionStore] Cleanup timer fired for:', sessionId,
'removing from pendingDelete. Remaining:', this.pendingDelete.size);
this.pendingDeleteTimers.delete(sessionId);
}, 5000);
this.pendingDeleteTimers.set(sessionId, timer);
@@ -342,10 +342,6 @@ function performWrite(terminal: TerminalProcess, data: string): Promise<void> {
setImmediate(writeChunk);
} else {
try {
if (terminal.hasExited) {
resolve();
return;
}
terminal.pty.write(data);
debugLog('[PtyManager:writeToPty] Write completed successfully');
} catch (error) {
@@ -309,6 +309,9 @@ export function DisplaySettings({ settings, onSettingsChange }: DisplaySettingsP
</SelectContent>
</Select>
</div>
<p className="text-xs text-muted-foreground">
{t('gpuAcceleration.helperText')}
</p>
</div>
</div>
</SettingsSection>
@@ -2,7 +2,7 @@
* @vitest-environment jsdom
*/
import { describe, it, expect, vi, beforeEach } from 'vitest';
import { render, screen, fireEvent } from '@testing-library/react';
import { render, screen } from '@testing-library/react';
import '@testing-library/jest-dom';
import '../../../../shared/i18n';
import { DisplaySettings } from '../DisplaySettings';
@@ -15,20 +15,24 @@ vi.mock('../../../stores/settings-store', () => ({
}))
}));
// Track onValueChange callbacks per Select instance
let selectCallbacks: Array<(v: string) => void> = [];
// Track onValueChange callbacks per Select instance, keyed by the SelectTrigger id
let selectCallbacks: Map<string, (v: string) => void> = new Map();
let currentSelectCallback: ((v: string) => void) | null = null;
// Mock Radix Select to make it testable in jsdom (portals don't work in jsdom)
vi.mock('../../ui/select', () => {
return {
Select: ({ value, onValueChange, children }: { value: string; onValueChange: (v: string) => void; children: React.ReactNode }) => {
selectCallbacks.push(onValueChange);
const idx = selectCallbacks.length - 1;
return <div data-testid={`select-root-${idx}`} data-value={value}>{children}</div>;
currentSelectCallback = onValueChange;
return <div data-value={value}>{children}</div>;
},
SelectTrigger: ({ id, children }: { id?: string; className?: string; children: React.ReactNode }) => {
if (id && currentSelectCallback) {
selectCallbacks.set(id, currentSelectCallback);
currentSelectCallback = null;
}
return <button data-testid={`select-trigger-${id || 'unknown'}`}>{children}</button>;
},
SelectTrigger: ({ id, children }: { id?: string; className?: string; children: React.ReactNode }) => (
<button data-testid={`select-trigger-${id || 'unknown'}`}>{children}</button>
),
SelectValue: () => null,
SelectContent: ({ children }: { className?: string; children: React.ReactNode }) => (
<div data-testid="select-content">{children}</div>
@@ -52,7 +56,8 @@ describe('DisplaySettings - GPU Acceleration Dropdown', () => {
beforeEach(() => {
vi.clearAllMocks();
selectCallbacks = [];
selectCallbacks = new Map();
currentSelectCallback = null;
mockOnSettingsChange = vi.fn();
});
@@ -80,23 +85,25 @@ describe('DisplaySettings - GPU Acceleration Dropdown', () => {
it('should display the current GPU acceleration value from settings', () => {
const settingsWithOn: AppSettings = { ...defaultSettings, gpuAcceleration: 'on' };
const { container } = render(
render(
<DisplaySettings settings={settingsWithOn} onSettingsChange={mockOnSettingsChange} />
);
// The GPU acceleration select is the second Select rendered (index 1, after logOrder)
const gpuSelect = container.querySelector('[data-testid="select-root-1"]');
// The GPU acceleration select is identified by its trigger id
const gpuTrigger = screen.getByTestId('select-trigger-gpuAcceleration');
const gpuSelect = gpuTrigger.closest('[data-value]');
expect(gpuSelect).toHaveAttribute('data-value', 'on');
});
it('should default to "off" when gpuAcceleration is not set', () => {
const settingsWithoutGpu: AppSettings = { ...defaultSettings, gpuAcceleration: undefined };
const { container } = render(
render(
<DisplaySettings settings={settingsWithoutGpu} onSettingsChange={mockOnSettingsChange} />
);
const gpuSelect = container.querySelector('[data-testid="select-root-1"]');
const gpuTrigger = screen.getByTestId('select-trigger-gpuAcceleration');
const gpuSelect = gpuTrigger.closest('[data-value]');
expect(gpuSelect).toHaveAttribute('data-value', 'off');
});
@@ -105,8 +112,7 @@ describe('DisplaySettings - GPU Acceleration Dropdown', () => {
<DisplaySettings settings={defaultSettings} onSettingsChange={mockOnSettingsChange} />
);
// selectCallbacks[1] is the GPU acceleration Select's onValueChange
selectCallbacks[1]('on');
selectCallbacks.get('gpuAcceleration')!('on');
expect(mockOnSettingsChange).toHaveBeenCalledWith(
expect.objectContaining({ gpuAcceleration: 'on' })
@@ -118,7 +124,7 @@ describe('DisplaySettings - GPU Acceleration Dropdown', () => {
<DisplaySettings settings={defaultSettings} onSettingsChange={mockOnSettingsChange} />
);
selectCallbacks[1]('off');
selectCallbacks.get('gpuAcceleration')!('off');
expect(mockOnSettingsChange).toHaveBeenCalledWith(
expect.objectContaining({ gpuAcceleration: 'off' })
@@ -132,7 +138,7 @@ describe('DisplaySettings - GPU Acceleration Dropdown', () => {
<DisplaySettings settings={settingsWithOff} onSettingsChange={mockOnSettingsChange} />
);
selectCallbacks[1]('auto');
selectCallbacks.get('gpuAcceleration')!('auto');
expect(mockOnSettingsChange).toHaveBeenCalledWith(
expect.objectContaining({ gpuAcceleration: 'auto' })
@@ -197,7 +197,8 @@
"description": "Use WebGL for terminal rendering (experimental, faster with many terminals)",
"auto": "Auto (use WebGL when supported)",
"on": "Always on",
"off": "Off (default)"
"off": "Off (default)",
"helperText": "Changes apply to new terminals only"
},
"general": {
"otherAgentSettings": "Other Agent Settings",
@@ -197,7 +197,8 @@
"description": "Utiliser WebGL pour le rendu des terminaux (expérimental, plus rapide avec plusieurs terminaux)",
"auto": "Auto (utiliser WebGL si supporté)",
"on": "Toujours activé",
"off": "Désactivé (par défaut)"
"off": "Désactivé (par défaut)",
"helperText": "Les modifications s'appliquent uniquement aux nouveaux terminaux"
},
"general": {
"otherAgentSettings": "Autres paramètres de l'agent",