mirror of
https://github.com/compiler-explorer/compiler-explorer.git
synced 2025-12-27 10:33:59 -05:00
Add comprehensive Cypress E2E tests for Claude Explain feature (#7751)
- Add comprehensive test suite covering all Claude Explain functionality: - Basic pane opening and consent flow - no-ai directive detection - API interactions and error handling - Options/customization features - Caching behavior and persistence - Compilation state handling - State persistence across page loads - Fix caching bug in explain-view.ts: - Cache was incorrectly implemented as instance variable, losing cached explanations when panes were closed/reopened - Made cache static to persist across all pane instances (matches consent persistence pattern) - Fixes failing "Caching and reload" Cypress test - Aligns implementation with documented behavior: "shared across all explain views in the session" - Add test utilities and helpers: - Monaco editor content manipulation using clipboard events - Claude Explain specific helpers moved to test file - General utilities remain in utils.ts - Performance optimizations: - Clear Cypress intercepts in afterEach to prevent O(n²) degradation - Use :visible selectors to avoid GoldenLayout template elements - Proper mock setup timing to prevent race conditions - Add comprehensive README with lessons learned and best practices All tests use fake test data (test_first, focus_a, etc.) to clearly distinguish from production values and prevent accidental API calls.
This commit is contained in:
@@ -97,8 +97,6 @@ export class ExplainView extends Pane<ExplainViewState> {
|
||||
private readonly explanationInfoButton: JQuery;
|
||||
private readonly explainApiEndpoint: string;
|
||||
private readonly fontScale: FontScale;
|
||||
private readonly cache: LRUCache<string, ClaudeExplainResponse>;
|
||||
|
||||
// Use a static variable to persist consent across all instances during the session
|
||||
private static consentGiven = false;
|
||||
|
||||
@@ -106,6 +104,9 @@ export class ExplainView extends Pane<ExplainViewState> {
|
||||
private static availableOptions: AvailableOptions | null = null;
|
||||
private static optionsFetchPromise: Promise<AvailableOptions> | null = null;
|
||||
|
||||
// Static explanation cache shared across all instances (200KB limit)
|
||||
private static cache: LRUCache<string, ClaudeExplainResponse> | null = null;
|
||||
|
||||
// Instance variables for selected options
|
||||
private selectedAudience: string;
|
||||
private selectedExplanation: string;
|
||||
@@ -118,10 +119,14 @@ export class ExplainView extends Pane<ExplainViewState> {
|
||||
super(hub, container, state);
|
||||
|
||||
this.explainApiEndpoint = options.explainApiEndpoint ?? '';
|
||||
this.cache = new LRUCache({
|
||||
maxSize: 200 * 1024,
|
||||
sizeCalculation: n => JSON.stringify(n).length,
|
||||
});
|
||||
|
||||
// Initialize static cache if not already done
|
||||
if (!ExplainView.cache) {
|
||||
ExplainView.cache = new LRUCache({
|
||||
maxSize: 200 * 1024,
|
||||
sizeCalculation: n => JSON.stringify(n).length,
|
||||
});
|
||||
}
|
||||
|
||||
this.statusIcon = this.domRoot.find('.status-icon');
|
||||
this.consentElement = this.domRoot.find('.explain-consent');
|
||||
@@ -465,7 +470,7 @@ export class ExplainView extends Pane<ExplainViewState> {
|
||||
}
|
||||
|
||||
this.showSuccess();
|
||||
this.cache.set(cacheKey, data);
|
||||
ExplainView.cache!.set(cacheKey, data);
|
||||
this.renderMarkdown(data.explanation);
|
||||
this.showBottomBar();
|
||||
|
||||
@@ -505,7 +510,7 @@ export class ExplainView extends Pane<ExplainViewState> {
|
||||
|
||||
// Check cache first unless bypassing
|
||||
if (!bypassCache) {
|
||||
const cachedResult = this.cache.get(cacheKey);
|
||||
const cachedResult = ExplainView.cache!.get(cacheKey);
|
||||
if (cachedResult) {
|
||||
this.displayCachedResult(cachedResult);
|
||||
return;
|
||||
|
||||
Reference in New Issue
Block a user