3333
3434import * as assert from 'assert' ;
3535import * as fs from 'fs' ;
36- import { commands , window } from 'vscode' ;
36+ import { commands , Position , window } from 'vscode' ;
3737import { createTempDocument , deleteTempDocument } from './test-helpers' ;
3838
3939suite ( 'VS Code Organize Imports Behavior (Real VS Code Command)' , ( ) => {
@@ -56,11 +56,33 @@ suite('VS Code Organize Imports Behavior (Real VS Code Command)', () => {
5656 return condition ( ) ; // Final check
5757 }
5858
59+ /**
60+ * Wait for the TypeScript language service to be ready for a document.
61+ * Polls executeHoverProvider as a reliable "TS has processed this file" signal.
62+ * When TS is ready, hovering over an import keyword returns type information.
63+ */
64+ async function waitForTypeScriptReady ( uri : import ( 'vscode' ) . Uri , timeoutMs : number = 10000 ) : Promise < void > {
65+ const startTime = Date . now ( ) ;
66+ while ( Date . now ( ) - startTime < timeoutMs ) {
67+ try {
68+ const hovers = await commands . executeCommand < import ( 'vscode' ) . Hover [ ] > (
69+ 'vscode.executeHoverProvider' , uri , new Position ( 0 , 10 ) ,
70+ ) ;
71+ if ( hovers && hovers . length > 0 ) {
72+ return ; // TS language service is ready
73+ }
74+ } catch { /* TS not ready yet */ }
75+ await new Promise ( resolve => setTimeout ( resolve , 300 ) ) ;
76+ }
77+ // Timed out — proceed anyway (best effort)
78+ }
79+
5980 /**
6081 * Helper function to organize imports using VS Code's ACTUAL command
6182 * This executes "editor.action.organizeImports" - the real command!
6283 *
63- * Uses polling-based waiting instead of hardcoded delays for reliability.
84+ * Uses hover provider polling to reliably detect when the TypeScript
85+ * language service is ready before running the organize command.
6486 */
6587 async function organizeImportsViaVSCode ( content : string ) : Promise < string > {
6688 // Create temp file using shared helper
@@ -74,13 +96,9 @@ suite('VS Code Organize Imports Behavior (Real VS Code Command)', () => {
7496 await doc . save ( ) ;
7597
7698 // Wait for TypeScript language service to be ready
77- // We poll for diagnostics availability as a proxy for "TS is ready"
78- // This is more reliable than a fixed delay
79- await waitForCondition ( ( ) => {
80- // TypeScript service is ready when the file can be processed
81- // We can't easily check diagnostics, so we use a reasonable initial delay
82- return true ;
83- } , 2000 , 200 ) ;
99+ // This prevents the flaky failure where editor.action.organizeImports
100+ // runs before TS has registered its code action provider
101+ await waitForTypeScriptReady ( doc . uri ) ;
84102
85103 // Capture initial content to detect changes
86104 const initialContent = fs . readFileSync ( doc . uri . fsPath , 'utf-8' ) ;
0 commit comments