@@ -25,6 +25,21 @@ function readWeauditData(workspaceFolder: vscode.WorkspaceFolder): SerializedDat
2525 return JSON . parse ( content ) as SerializedData ;
2626}
2727
28+ /**
29+ * Poll for a condition to become true, with timeout.
30+ * Returns true if condition was met, false if timed out.
31+ */
32+ async function waitForCondition ( condition : ( ) => boolean , timeoutMs : number = 5000 , pollIntervalMs : number = 100 ) : Promise < boolean > {
33+ const startTime = Date . now ( ) ;
34+ while ( Date . now ( ) - startTime < timeoutMs ) {
35+ if ( condition ( ) ) {
36+ return true ;
37+ }
38+ await new Promise ( ( resolve ) => setTimeout ( resolve , pollIntervalMs ) ) ;
39+ }
40+ return condition ( ) ; // Final check
41+ }
42+
2843suite ( "Editor Decorations" , ( ) => {
2944 const extensionId = "trailofbits.weaudit" ;
3045 let testFileUri : vscode . Uri ;
@@ -80,13 +95,15 @@ suite("Editor Decorations", () => {
8095
8196 // Toggle audited status
8297 await vscode . commands . executeCommand ( "weAudit.toggleAudited" ) ;
83- await new Promise ( ( resolve ) => setTimeout ( resolve , 500 ) ) ;
8498
85- // Verify the state changed
86- const dataAfter = readWeauditData ( workspaceFolder ) ;
87- const isAudited = dataAfter ?. auditedFiles . some ( ( f ) => f . path === relativePath ) ?? false ;
99+ // Wait for the state to actually change (poll instead of fixed delay)
100+ const stateChanged = await waitForCondition ( ( ) => {
101+ const dataAfter = readWeauditData ( workspaceFolder ) ;
102+ const isAudited = dataAfter ?. auditedFiles . some ( ( f ) => f . path === relativePath ) ?? false ;
103+ return isAudited !== wasAudited ;
104+ } ) ;
88105
89- assert . notStrictEqual ( isAudited , wasAudited , "Audited status should be toggled" ) ;
106+ assert . ok ( stateChanged , "Audited status should be toggled" ) ;
90107 } ) ;
91108
92109 test ( "addPartiallyAudited command adds partially audited region" , async function ( ) {
@@ -100,7 +117,11 @@ suite("Editor Decorations", () => {
100117 const dataCheck = readWeauditData ( workspaceFolder ) ;
101118 if ( dataCheck ?. auditedFiles . some ( ( f ) => f . path === relativePath ) ) {
102119 await vscode . commands . executeCommand ( "weAudit.toggleAudited" ) ;
103- await new Promise ( ( resolve ) => setTimeout ( resolve , 500 ) ) ;
120+ // Wait for the unaudit to complete
121+ await waitForCondition ( ( ) => {
122+ const data = readWeauditData ( workspaceFolder ) ;
123+ return ! data ?. auditedFiles . some ( ( f ) => f . path === relativePath ) ;
124+ } ) ;
104125 }
105126
106127 // Use lines that are not already partially audited
@@ -119,15 +140,17 @@ suite("Editor Decorations", () => {
119140
120141 // Add partially audited region
121142 await vscode . commands . executeCommand ( "weAudit.addPartiallyAudited" ) ;
122- await new Promise ( ( resolve ) => setTimeout ( resolve , 500 ) ) ;
123143
124- // Verify state changed
125- const dataAfter = readWeauditData ( workspaceFolder ) ;
126- const regionExistsAfter =
127- dataAfter ?. partiallyAuditedFiles . some ( ( f ) => f . path === relativePath && f . startLine === startLine && f . endLine === endLine ) ?? false ;
144+ // Wait for the state to actually change (poll instead of fixed delay)
145+ const stateChanged = await waitForCondition ( ( ) => {
146+ const dataAfter = readWeauditData ( workspaceFolder ) ;
147+ const regionExistsAfter =
148+ dataAfter ?. partiallyAuditedFiles . some ( ( f ) => f . path === relativePath && f . startLine === startLine && f . endLine === endLine ) ?? false ;
149+ return regionExistsAfter !== regionExistsBefore ;
150+ } ) ;
128151
129152 // The command toggles the region - so if it existed before it's removed, if it didn't exist it's added
130- assert . notStrictEqual ( regionExistsAfter , regionExistsBefore , "Partially audited region should be toggled" ) ;
153+ assert . ok ( stateChanged , "Partially audited region should be toggled" ) ;
131154 } ) ;
132155
133156 test ( "Extension survives file edits" , async function ( ) {
0 commit comments