@@ -35,30 +35,44 @@ const SLOW_SERVERS: Record<string, number> = {
3535 threejs : 2000 , // Three.js WebGL initialization
3636} ;
3737
38- // Server configurations (key is used for screenshot filenames, name is the MCP server name)
39- const SERVERS = [
40- { key : "integration" , name : "Integration Test Server" } ,
41- { key : "basic-preact" , name : "Basic MCP App Server (Preact)" } ,
42- { key : "basic-react" , name : "Basic MCP App Server (React)" } ,
43- { key : "basic-solid" , name : "Basic MCP App Server (Solid)" } ,
44- { key : "basic-svelte" , name : "Basic MCP App Server (Svelte)" } ,
45- { key : "basic-vanillajs" , name : "Basic MCP App Server (Vanilla JS)" } ,
46- { key : "basic-vue" , name : "Basic MCP App Server (Vue)" } ,
47- { key : "budget-allocator" , name : "Budget Allocator Server" } ,
48- { key : "cohort-heatmap" , name : "Cohort Heatmap Server" } ,
49- { key : "customer-segmentation" , name : "Customer Segmentation Server" } ,
50- { key : "map-server" , name : "Map Server" } ,
51- { key : "pdf-server" , name : "PDF Server" } ,
52- { key : "qr-server" , name : "QR Code Server" } ,
53- { key : "scenario-modeler" , name : "SaaS Scenario Modeler" } ,
54- { key : "shadertoy" , name : "ShaderToy Server" } ,
55- { key : "sheet-music" , name : "Sheet Music Server" } ,
56- { key : "system-monitor" , name : "System Monitor Server" } ,
57- { key : "threejs" , name : "Three.js Server" } ,
58- { key : "transcript" , name : "Transcript Server" } ,
59- { key : "wiki-explorer" , name : "Wiki Explorer" } ,
38+ // Servers to skip in CI (require special resources like GPU, large ML models)
39+ const SKIP_SERVERS = new Set < string > ( [
40+ // None currently - say-server widget works without TTS model for screenshots
41+ ] ) ;
42+
43+ // Optional: filter to a single example via EXAMPLE env var (folder name)
44+ const EXAMPLE_FILTER = process . env . EXAMPLE ;
45+
46+ // Server configurations (key is used for screenshot filenames, name is the MCP server name, dir is the folder name)
47+ const ALL_SERVERS = [
48+ { key : "integration" , name : "Integration Test Server" , dir : "integration-server" } ,
49+ { key : "basic-preact" , name : "Basic MCP App Server (Preact)" , dir : "basic-server-preact" } ,
50+ { key : "basic-react" , name : "Basic MCP App Server (React)" , dir : "basic-server-react" } ,
51+ { key : "basic-solid" , name : "Basic MCP App Server (Solid)" , dir : "basic-server-solid" } ,
52+ { key : "basic-svelte" , name : "Basic MCP App Server (Svelte)" , dir : "basic-server-svelte" } ,
53+ { key : "basic-vanillajs" , name : "Basic MCP App Server (Vanilla JS)" , dir : "basic-server-vanillajs" } ,
54+ { key : "basic-vue" , name : "Basic MCP App Server (Vue)" , dir : "basic-server-vue" } ,
55+ { key : "budget-allocator" , name : "Budget Allocator Server" , dir : "budget-allocator-server" } ,
56+ { key : "cohort-heatmap" , name : "Cohort Heatmap Server" , dir : "cohort-heatmap-server" } ,
57+ { key : "customer-segmentation" , name : "Customer Segmentation Server" , dir : "customer-segmentation-server" } ,
58+ { key : "map-server" , name : "Map Server" , dir : "map-server" } ,
59+ { key : "pdf-server" , name : "PDF Server" , dir : "pdf-server" } ,
60+ { key : "qr-server" , name : "QR Code Server" , dir : "qr-server" } ,
61+ { key : "say-server" , name : "Say Demo" , dir : "say-server" } ,
62+ { key : "scenario-modeler" , name : "SaaS Scenario Modeler" , dir : "scenario-modeler-server" } ,
63+ { key : "shadertoy" , name : "ShaderToy Server" , dir : "shadertoy-server" } ,
64+ { key : "sheet-music" , name : "Sheet Music Server" , dir : "sheet-music-server" } ,
65+ { key : "system-monitor" , name : "System Monitor Server" , dir : "system-monitor-server" } ,
66+ { key : "threejs" , name : "Three.js Server" , dir : "threejs-server" } ,
67+ { key : "transcript" , name : "Transcript Server" , dir : "transcript-server" } ,
68+ { key : "wiki-explorer" , name : "Wiki Explorer" , dir : "wiki-explorer-server" } ,
6069] ;
6170
71+ // Filter servers if EXAMPLE is specified
72+ const SERVERS = EXAMPLE_FILTER
73+ ? ALL_SERVERS . filter ( ( s ) => s . dir === EXAMPLE_FILTER )
74+ : ALL_SERVERS ;
75+
6276/**
6377 * Helper to get the app frame locator (nested: sandbox > app)
6478 */
@@ -129,12 +143,23 @@ test.describe("Host UI", () => {
129143
130144// Define tests for each server using forEach to avoid for-loop issues
131145SERVERS . forEach ( ( server ) => {
146+ // Skip servers that require special resources (GPU, large ML models)
147+ const shouldSkip = SKIP_SERVERS . has ( server . key ) ;
148+
132149 test . describe ( server . name , ( ) => {
133150 test ( "loads app UI" , async ( { page } ) => {
151+ if ( shouldSkip ) {
152+ test . skip ( ) ;
153+ return ;
154+ }
134155 await loadServer ( page , server . name ) ;
135156 } ) ;
136157
137158 test ( "screenshot matches golden" , async ( { page } ) => {
159+ if ( shouldSkip ) {
160+ test . skip ( ) ;
161+ return ;
162+ }
138163 await loadServer ( page , server . name ) ;
139164
140165 // Some servers (WebGL, tile-based) need extra stabilization time
@@ -153,12 +178,16 @@ SERVERS.forEach((server) => {
153178} ) ;
154179
155180// Interaction tests for integration server (tests all SDK communication APIs)
156- const integrationServer = SERVERS . find ( ( s ) => s . key === "integration" ) ! ;
181+ // Only run if integration-server is included (either no filter or EXAMPLE=integration-server)
182+ const integrationServer = SERVERS . find ( ( s ) => s . key === "integration" ) ;
183+ const integrationServerName = integrationServer ?. name ?? "Integration Test Server" ;
184+
185+ test . describe ( `Integration Test Server - Interactions` , ( ) => {
186+ test . skip ( ( ) => ! integrationServer , "Skipped: integration-server not in EXAMPLE filter" ) ;
157187
158- test . describe ( `${ integrationServer . name } - Interactions` , ( ) => {
159188 test ( "Send Message button triggers host callback" , async ( { page } ) => {
160189 const logs = captureHostLogs ( page ) ;
161- await loadServer ( page , integrationServer . name ) ;
190+ await loadServer ( page , integrationServerName ) ;
162191
163192 const appFrame = getAppFrame ( page ) ;
164193 await appFrame . locator ( 'button:has-text("Send Message")' ) . click ( ) ;
@@ -171,7 +200,7 @@ test.describe(`${integrationServer.name} - Interactions`, () => {
171200
172201 test ( "Send Log button triggers host callback" , async ( { page } ) => {
173202 const logs = captureHostLogs ( page ) ;
174- await loadServer ( page , integrationServer . name ) ;
203+ await loadServer ( page , integrationServerName ) ;
175204
176205 const appFrame = getAppFrame ( page ) ;
177206 await appFrame . locator ( 'button:has-text("Send Log")' ) . click ( ) ;
@@ -185,7 +214,7 @@ test.describe(`${integrationServer.name} - Interactions`, () => {
185214
186215 test ( "Open Link button triggers host callback" , async ( { page } ) => {
187216 const logs = captureHostLogs ( page ) ;
188- await loadServer ( page , integrationServer . name ) ;
217+ await loadServer ( page , integrationServerName ) ;
189218
190219 const appFrame = getAppFrame ( page ) ;
191220 await appFrame . locator ( 'button:has-text("Open Link")' ) . click ( ) ;
0 commit comments