@@ -3,100 +3,107 @@ import { listClientScenarios, getClientScenario } from '../index.js';
33import path from 'path' ;
44
55describe ( 'Server Scenarios' , ( ) => {
6- let serverProcess : ChildProcess ;
7- const TEST_PORT = 3001 ;
8- const SERVER_URL = `http://localhost:${ TEST_PORT } /mcp` ;
9- const SERVER_STARTUP_TIMEOUT = 10000 ; // 10 seconds to start
10-
11- beforeAll ( async ( ) => {
12- // Start the everything-server once for all scenarios
13- const serverPath = path . join ( process . cwd ( ) , 'examples/servers/typescript/everything-server.ts' ) ;
14-
15- serverProcess = spawn ( 'npx' , [ 'tsx' , serverPath ] , {
16- env : { ...process . env , PORT : TEST_PORT . toString ( ) } ,
17- stdio : [ 'ignore' , 'pipe' , 'pipe' ]
18- } ) ;
19-
20- // Wait for server to be ready
21- await new Promise < void > ( ( resolve , reject ) => {
22- const timeout = setTimeout ( ( ) => {
23- reject ( new Error ( `Server failed to start within ${ SERVER_STARTUP_TIMEOUT } ms` ) ) ;
24- } , SERVER_STARTUP_TIMEOUT ) ;
25-
26- serverProcess . stdout ?. on ( 'data' , data => {
27- const output = data . toString ( ) ;
28- if ( output . includes ( 'running on' ) ) {
29- clearTimeout ( timeout ) ;
30- resolve ( ) ;
31- }
32- } ) ;
33-
34- serverProcess . on ( 'error' , error => {
35- clearTimeout ( timeout ) ;
36- reject ( new Error ( `Failed to start server: ${ error . message } ` ) ) ;
37- } ) ;
38-
39- serverProcess . on ( 'exit' , code => {
40- if ( code !== null && code !== 0 ) {
41- clearTimeout ( timeout ) ;
42- reject ( new Error ( `Server exited prematurely with code ${ code } ` ) ) ;
43- }
44- } ) ;
45- } ) ;
46- } , SERVER_STARTUP_TIMEOUT + 5000 ) ;
47-
48- afterAll ( async ( ) => {
49- // Stop the server
50- if ( serverProcess ) {
51- serverProcess . kill ( 'SIGTERM' ) ;
52-
53- // Wait for graceful shutdown
54- await new Promise < void > ( resolve => {
55- const timeoutHandle = setTimeout ( ( ) => {
56- if ( ! serverProcess . killed ) {
57- serverProcess . kill ( 'SIGKILL' ) ;
58- }
59- resolve ( ) ;
60- } , 5000 ) ;
61-
62- const cleanUp = ( ) => {
63- clearTimeout ( timeoutHandle ) ;
64- serverProcess . removeListener ( 'exit' , cleanUp ) ;
65- resolve ( ) ;
66- } ;
67-
68- serverProcess . on ( 'exit' , cleanUp ) ;
69- } ) ;
70- }
6+ let serverProcess : ChildProcess ;
7+ const TEST_PORT = 3001 ;
8+ const SERVER_URL = `http://localhost:${ TEST_PORT } /mcp` ;
9+ const SERVER_STARTUP_TIMEOUT = 10000 ; // 10 seconds to start
10+
11+ beforeAll ( async ( ) => {
12+ // Start the everything-server once for all scenarios
13+ const serverPath = path . join (
14+ process . cwd ( ) ,
15+ 'examples/servers/typescript/everything-server.ts'
16+ ) ;
17+
18+ serverProcess = spawn ( 'npx' , [ 'tsx' , serverPath ] , {
19+ env : { ...process . env , PORT : TEST_PORT . toString ( ) } ,
20+ stdio : [ 'ignore' , 'pipe' , 'pipe' ]
7121 } ) ;
7222
73- // Generate individual test for each scenario
74- const scenarios = listClientScenarios ( ) ;
75-
76- for ( const scenarioName of scenarios ) {
77- it ( `${ scenarioName } ` , async ( ) => {
78- const scenario = getClientScenario ( scenarioName ) ;
79- expect ( scenario ) . toBeDefined ( ) ;
80-
81- if ( ! scenario ) {
82- throw new Error ( `Scenario ${ scenarioName } not found` ) ;
83- }
84-
85- const checks = await scenario . run ( SERVER_URL ) ;
86-
87- // Verify checks were returned
88- expect ( checks . length ) . toBeGreaterThan ( 0 ) ;
23+ // Wait for server to be ready
24+ await new Promise < void > ( ( resolve , reject ) => {
25+ const timeout = setTimeout ( ( ) => {
26+ reject (
27+ new Error ( `Server failed to start within ${ SERVER_STARTUP_TIMEOUT } ms` )
28+ ) ;
29+ } , SERVER_STARTUP_TIMEOUT ) ;
30+
31+ serverProcess . stdout ?. on ( 'data' , ( data ) => {
32+ const output = data . toString ( ) ;
33+ if ( output . includes ( 'running on' ) ) {
34+ clearTimeout ( timeout ) ;
35+ resolve ( ) ;
36+ }
37+ } ) ;
8938
90- // Verify all checks passed
91- const failures = checks . filter ( c => c . status === 'FAILURE' ) ;
92- if ( failures . length > 0 ) {
93- const failureMessages = failures . map ( c => `${ c . name } : ${ c . errorMessage || c . description } ` ) . join ( '\n ' ) ;
94- throw new Error ( `Scenario failed with checks:\n ${ failureMessages } ` ) ;
95- }
39+ serverProcess . on ( 'error' , ( error ) => {
40+ clearTimeout ( timeout ) ;
41+ reject ( new Error ( `Failed to start server: ${ error . message } ` ) ) ;
42+ } ) ;
9643
97- // All checks should be SUCCESS
98- const successes = checks . filter ( c => c . status === 'SUCCESS' ) ;
99- expect ( successes . length ) . toBe ( checks . length ) ;
100- } , 10000 ) ; // 10 second timeout per scenario
44+ serverProcess . on ( 'exit' , ( code ) => {
45+ if ( code !== null && code !== 0 ) {
46+ clearTimeout ( timeout ) ;
47+ reject ( new Error ( `Server exited prematurely with code ${ code } ` ) ) ;
48+ }
49+ } ) ;
50+ } ) ;
51+ } , SERVER_STARTUP_TIMEOUT + 5000 ) ;
52+
53+ afterAll ( async ( ) => {
54+ // Stop the server
55+ if ( serverProcess ) {
56+ serverProcess . kill ( 'SIGTERM' ) ;
57+
58+ // Wait for graceful shutdown
59+ await new Promise < void > ( ( resolve ) => {
60+ const timeoutHandle = setTimeout ( ( ) => {
61+ if ( ! serverProcess . killed ) {
62+ serverProcess . kill ( 'SIGKILL' ) ;
63+ }
64+ resolve ( ) ;
65+ } , 5000 ) ;
66+
67+ const cleanUp = ( ) => {
68+ clearTimeout ( timeoutHandle ) ;
69+ serverProcess . removeListener ( 'exit' , cleanUp ) ;
70+ resolve ( ) ;
71+ } ;
72+
73+ serverProcess . on ( 'exit' , cleanUp ) ;
74+ } ) ;
10175 }
76+ } ) ;
77+
78+ // Generate individual test for each scenario
79+ const scenarios = listClientScenarios ( ) ;
80+
81+ for ( const scenarioName of scenarios ) {
82+ it ( `${ scenarioName } ` , async ( ) => {
83+ const scenario = getClientScenario ( scenarioName ) ;
84+ expect ( scenario ) . toBeDefined ( ) ;
85+
86+ if ( ! scenario ) {
87+ throw new Error ( `Scenario ${ scenarioName } not found` ) ;
88+ }
89+
90+ const checks = await scenario . run ( SERVER_URL ) ;
91+
92+ // Verify checks were returned
93+ expect ( checks . length ) . toBeGreaterThan ( 0 ) ;
94+
95+ // Verify all checks passed
96+ const failures = checks . filter ( ( c ) => c . status === 'FAILURE' ) ;
97+ if ( failures . length > 0 ) {
98+ const failureMessages = failures
99+ . map ( ( c ) => `${ c . name } : ${ c . errorMessage || c . description } ` )
100+ . join ( '\n ' ) ;
101+ throw new Error ( `Scenario failed with checks:\n ${ failureMessages } ` ) ;
102+ }
103+
104+ // All checks should be SUCCESS
105+ const successes = checks . filter ( ( c ) => c . status === 'SUCCESS' ) ;
106+ expect ( successes . length ) . toBe ( checks . length ) ;
107+ } , 10000 ) ; // 10 second timeout per scenario
108+ }
102109} ) ;
0 commit comments