1- import { test , expect } from "@playwright/test" ;
1+ import { test , expect , type Page } from "@playwright/test" ;
22
33// Server configurations
44const SERVERS = [
55 { key : "basic-react" , index : 0 , name : "Basic MCP App Server (React-based)" } ,
6- {
7- key : "basic-vanillajs" ,
8- index : 1 ,
9- name : "Basic MCP App Server (Vanilla JS)" ,
10- } ,
6+ { key : "basic-vanillajs" , index : 1 , name : "Basic MCP App Server (Vanilla JS)" } ,
117 { key : "budget-allocator" , index : 2 , name : "Budget Allocator Server" } ,
128 { key : "cohort-heatmap" , index : 3 , name : "Cohort Heatmap Server" } ,
13- {
14- key : "customer-segmentation" ,
15- index : 4 ,
16- name : "Customer Segmentation Server" ,
17- } ,
9+ { key : "customer-segmentation" , index : 4 , name : "Customer Segmentation Server" } ,
1810 { key : "scenario-modeler" , index : 5 , name : "SaaS Scenario Modeler" } ,
1911 { key : "system-monitor" , index : 6 , name : "System Monitor Server" } ,
2012 { key : "threejs" , index : 7 , name : "Three.js Server" } ,
@@ -24,13 +16,18 @@ const SERVERS = [
2416 * Wait for the MCP App to load inside nested iframes.
2517 * Structure: page > iframe (sandbox) > iframe (app)
2618 */
27- async function waitForAppLoad ( page : import ( "@playwright/test" ) . Page ) {
28- // Wait for outer iframe (sandbox)
19+ async function waitForAppLoad ( page : Page ) {
2920 const outerFrame = page . frameLocator ( "iframe" ) . first ( ) ;
30- // Wait for inner iframe (app) to be visible
3121 await expect ( outerFrame . locator ( "iframe" ) ) . toBeVisible ( ) ;
3222}
3323
24+ async function loadServer ( page : Page , serverIndex : number ) {
25+ await page . goto ( "/" ) ;
26+ await page . locator ( "select" ) . first ( ) . selectOption ( { index : serverIndex } ) ;
27+ await page . click ( 'button:has-text("Call Tool")' ) ;
28+ await waitForAppLoad ( page ) ;
29+ }
30+
3431test . describe ( "Host UI" , ( ) => {
3532 test ( "initial state shows controls" , async ( { page } ) => {
3633 await page . goto ( "/" ) ;
@@ -46,37 +43,19 @@ test.describe("Host UI", () => {
4643 } ) ;
4744} ) ;
4845
49- // Generate tests for each server
50- for ( const server of SERVERS ) {
51- test . describe ( `${ server . name } ` , ( ) => {
52- test ( `loads app UI` , async ( { page } ) => {
53- await page . goto ( "/" ) ;
54-
55- // Select server and call tool
56- await page . locator ( "select" ) . first ( ) . selectOption ( { index : server . index } ) ;
57- await page . click ( 'button:has-text("Call Tool")' ) ;
58-
59- // Wait for app to load in nested iframes
60- await waitForAppLoad ( page ) ;
46+ // Define tests for each server using forEach to avoid for-loop issues
47+ SERVERS . forEach ( ( server ) => {
48+ test . describe ( server . name , ( ) => {
49+ test ( "loads app UI" , async ( { page } ) => {
50+ await loadServer ( page , server . index ) ;
6151 } ) ;
6252
63- test ( `screenshot matches golden` , async ( { page } ) => {
64- await page . goto ( "/" ) ;
65-
66- // Select server and call tool
67- await page . locator ( "select" ) . first ( ) . selectOption ( { index : server . index } ) ;
68- await page . click ( 'button:has-text("Call Tool")' ) ;
69-
70- // Wait for app to load
71- await waitForAppLoad ( page ) ;
72-
73- // Brief stabilization for animations/rendering
74- await page . waitForTimeout ( 500 ) ;
75-
76- // Take screenshot
53+ test ( "screenshot matches golden" , async ( { page } ) => {
54+ await loadServer ( page , server . index ) ;
55+ await page . waitForTimeout ( 500 ) ; // Brief stabilization
7756 await expect ( page ) . toHaveScreenshot ( `${ server . key } .png` , {
78- maxDiffPixelRatio : 0.1 , // 10% tolerance for dynamic content
57+ maxDiffPixelRatio : 0.1 ,
7958 } ) ;
8059 } ) ;
8160 } ) ;
82- }
61+ } ) ;
0 commit comments