@@ -229,6 +229,9 @@ export class IntegrationTestRunner {
229229 // Also run workflow integration tests
230230 await this . runWorkflowIntegrationTests ( baseDir ) ;
231231
232+ // Also run prompt integration tests
233+ await this . runPromptIntegrationTests ( baseDir ) ;
234+
232235 return totalIntegrationTests > 0 ;
233236 } catch ( error ) {
234237 this . logger . log ( `Error running integration tests: ${ error . message } ` , "ERROR" ) ;
@@ -1095,6 +1098,141 @@ export class IntegrationTestRunner {
10951098 return params ;
10961099 }
10971100
1101+ /**
1102+ * Run prompt-level integration tests.
1103+ * Discovers test fixtures under `integration-tests/primitives/prompts/`
1104+ * and calls `client.getPrompt()` for each, validating the response.
1105+ */
1106+ async runPromptIntegrationTests ( baseDir ) {
1107+ try {
1108+ this . logger . log ( "Discovering and running prompt integration tests..." ) ;
1109+
1110+ const promptTestsDir = path . join ( baseDir , ".." , "integration-tests" , "primitives" , "prompts" ) ;
1111+
1112+ if ( ! fs . existsSync ( promptTestsDir ) ) {
1113+ this . logger . log ( "No prompt integration tests directory found" , "INFO" ) ;
1114+ return true ;
1115+ }
1116+
1117+ // Get list of available prompts from the server
1118+ const response = await this . client . listPrompts ( ) ;
1119+ const prompts = response . prompts || [ ] ;
1120+ const promptNames = prompts . map ( ( p ) => p . name ) ;
1121+
1122+ this . logger . log ( `Found ${ promptNames . length } prompts available on server` ) ;
1123+
1124+ // Discover prompt test directories (each subdirectory = one prompt name)
1125+ const promptDirs = fs
1126+ . readdirSync ( promptTestsDir , { withFileTypes : true } )
1127+ . filter ( ( dirent ) => dirent . isDirectory ( ) )
1128+ . map ( ( dirent ) => dirent . name ) ;
1129+
1130+ this . logger . log (
1131+ `Found ${ promptDirs . length } prompt test directories: ${ promptDirs . join ( ", " ) } `
1132+ ) ;
1133+
1134+ let totalPromptTests = 0 ;
1135+ for ( const promptName of promptDirs ) {
1136+ if ( ! promptNames . includes ( promptName ) ) {
1137+ this . logger . log ( `Skipping ${ promptName } - prompt not found on server` , "WARN" ) ;
1138+ continue ;
1139+ }
1140+
1141+ const promptDir = path . join ( promptTestsDir , promptName ) ;
1142+ const testCases = fs
1143+ . readdirSync ( promptDir , { withFileTypes : true } )
1144+ . filter ( ( dirent ) => dirent . isDirectory ( ) )
1145+ . map ( ( dirent ) => dirent . name ) ;
1146+
1147+ this . logger . log ( `Running ${ testCases . length } test case(s) for prompt ${ promptName } ` ) ;
1148+
1149+ for ( const testCase of testCases ) {
1150+ await this . runSinglePromptIntegrationTest ( promptName , testCase , promptDir ) ;
1151+ totalPromptTests ++ ;
1152+ }
1153+ }
1154+
1155+ this . logger . log ( `Total prompt integration tests executed: ${ totalPromptTests } ` ) ;
1156+ return true ;
1157+ } catch ( error ) {
1158+ this . logger . log ( `Error running prompt integration tests: ${ error . message } ` , "ERROR" ) ;
1159+ return false ;
1160+ }
1161+ }
1162+
1163+ /**
1164+ * Run a single prompt integration test.
1165+ *
1166+ * Reads parameters from `before/monitoring-state.json`, calls `getPrompt()`,
1167+ * and validates that the response contains messages (no protocol-level error).
1168+ */
1169+ async runSinglePromptIntegrationTest ( promptName , testCase , promptDir ) {
1170+ const testName = `prompt:${ promptName } /${ testCase } ` ;
1171+ this . logger . log ( `\nRunning prompt integration test: ${ testName } ` ) ;
1172+
1173+ try {
1174+ const testCaseDir = path . join ( promptDir , testCase ) ;
1175+ const beforeDir = path . join ( testCaseDir , "before" ) ;
1176+ const afterDir = path . join ( testCaseDir , "after" ) ;
1177+
1178+ // Validate test structure
1179+ if ( ! fs . existsSync ( beforeDir ) ) {
1180+ this . logger . logTest ( testName , false , "Missing before directory" ) ;
1181+ return ;
1182+ }
1183+
1184+ if ( ! fs . existsSync ( afterDir ) ) {
1185+ this . logger . logTest ( testName , false , "Missing after directory" ) ;
1186+ return ;
1187+ }
1188+
1189+ // Load parameters from before/monitoring-state.json
1190+ const monitoringStatePath = path . join ( beforeDir , "monitoring-state.json" ) ;
1191+ if ( ! fs . existsSync ( monitoringStatePath ) ) {
1192+ this . logger . logTest ( testName , false , "Missing before/monitoring-state.json" ) ;
1193+ return ;
1194+ }
1195+
1196+ const monitoringState = JSON . parse ( fs . readFileSync ( monitoringStatePath , "utf8" ) ) ;
1197+ const params = monitoringState . parameters || { } ;
1198+ resolvePathPlaceholders ( params , this . logger ) ;
1199+
1200+ // Call the prompt
1201+ this . logger . log ( `Calling prompt ${ promptName } with params: ${ JSON . stringify ( params ) } ` ) ;
1202+
1203+ const result = await this . client . getPrompt ( {
1204+ name : promptName ,
1205+ arguments : params
1206+ } ) ;
1207+
1208+ // Validate that the response contains messages (no raw protocol error)
1209+ const hasMessages = result . messages && result . messages . length > 0 ;
1210+ if ( ! hasMessages ) {
1211+ this . logger . logTest ( testName , false , "Expected messages in prompt response" ) ;
1212+ return ;
1213+ }
1214+
1215+ // If the after/monitoring-state.json has expected content checks, validate
1216+ const afterMonitoringPath = path . join ( afterDir , "monitoring-state.json" ) ;
1217+ if ( fs . existsSync ( afterMonitoringPath ) ) {
1218+ const afterState = JSON . parse ( fs . readFileSync ( afterMonitoringPath , "utf8" ) ) ;
1219+ if ( afterState . expectedContentPatterns ) {
1220+ const text = result . messages [ 0 ] ?. content ?. text || "" ;
1221+ for ( const pattern of afterState . expectedContentPatterns ) {
1222+ if ( ! text . includes ( pattern ) ) {
1223+ this . logger . logTest ( testName , false , `Expected response to contain "${ pattern } "` ) ;
1224+ return ;
1225+ }
1226+ }
1227+ }
1228+ }
1229+
1230+ this . logger . logTest ( testName , true , `Prompt returned ${ result . messages . length } message(s)` ) ;
1231+ } catch ( error ) {
1232+ this . logger . logTest ( testName , false , `Error: ${ error . message } ` ) ;
1233+ }
1234+ }
1235+
10981236 /**
10991237 * Run workflow-level integration tests
11001238 * These tests validate complete workflows rather than individual tools
0 commit comments