Skip to main content
Glama
multi-window.test.ts6.47 kB
import { describe, it, expect, beforeAll, afterAll } from 'vitest'; import { manageWindow } from '../../src/driver/plugin-commands'; import { executeJavaScript, screenshot, interact } from '../../src/driver/webview-interactions'; import { manageDriverSession } from '../../src/driver/session-manager'; import { getTestAppPort } from '../test-utils'; /** * E2E tests for multi-window support. * Tests the ability to list windows and target specific windows with tools. */ describe('Multi-Window Support E2E Tests', () => { const TIMEOUT = 10000; beforeAll(async () => { // App is already started globally - connect to the dynamically assigned port await manageDriverSession('start', undefined, getTestAppPort()); }); afterAll(async () => { await manageDriverSession('stop'); }); describe('Window Listing', () => { it('should list all windows', async () => { const result = await manageWindow({ action: 'list' }); const parsed = JSON.parse(result); expect(parsed).toHaveProperty('windows'); expect(parsed).toHaveProperty('defaultWindow', 'main'); expect(parsed).toHaveProperty('totalCount'); expect(Array.isArray(parsed.windows)).toBe(true); expect(parsed.windows.length).toBeGreaterThan(0); }, TIMEOUT); it('should return window info with expected properties', async () => { const result = await manageWindow({ action: 'list' }); const parsed = JSON.parse(result); const mainWindow = parsed.windows.find((w: { label: string }) => { return w.label === 'main'; }); expect(mainWindow).toBeDefined(); expect(mainWindow).toHaveProperty('label'); expect(mainWindow).toHaveProperty('focused'); expect(mainWindow).toHaveProperty('visible'); expect(mainWindow).toHaveProperty('isMain', true); }, TIMEOUT); }); describe('Window Targeting', () => { it('should execute JavaScript in default window when no windowId specified', async () => { const result = await executeJavaScript({ script: 'document.title' }); expect(result).toBeTruthy(); }, TIMEOUT); it('should execute JavaScript in main window when windowId is "main"', async () => { const result = await executeJavaScript({ script: 'document.title', windowId: 'main' }); expect(result).toBeTruthy(); }, TIMEOUT); it('should return error for non-existent window', async () => { await expect(executeJavaScript({ script: 'document.title', windowId: 'non-existent-window' })) .rejects .toThrow(/not found/i); }, TIMEOUT); }); describe('Backward Compatibility', () => { it('should work with existing tools without windowId', async () => { // Test that tools work without windowId (backward compatible) const result = await executeJavaScript({ script: '1 + 1' }); // Result includes window context info expect(result).toContain('2'); expect(result).toContain('[Executed in window: main]'); }, TIMEOUT); it('should take screenshot without windowId', async () => { const result = await screenshot({}); // Result is now a ScreenshotResult with content array (not a file result) expect('content' in result).toBe(true); if (!('content' in result)) { throw new Error('Expected ScreenshotResult with content'); } expect(Array.isArray(result.content)).toBe(true); // Should have text and image content type ContentItem = { type: string }; const textContent = result.content.find((c: ContentItem) => { return c.type === 'text'; }); const imageContent = result.content.find((c: ContentItem) => { return c.type === 'image'; }); expect(textContent).toBeDefined(); expect(imageContent).toBeDefined(); }, TIMEOUT); it('should interact without windowId', async () => { // Just verify it doesn't throw - actual interaction depends on page content const result = await interact({ action: 'scroll', scrollX: 0, scrollY: 10, }); expect(result).toBeTruthy(); }, TIMEOUT); }); describe('Window Resize', () => { it('should resize window to specified dimensions', async () => { const result = await manageWindow({ action: 'resize', width: 800, height: 600, }); const parsed = JSON.parse(result); expect(parsed.success).toBe(true); expect(parsed.windowLabel).toBe('main'); expect(parsed.width).toBe(800); expect(parsed.height).toBe(600); }, TIMEOUT); it('should resize window with logical pixels by default', async () => { const result = await manageWindow({ action: 'resize', width: 1024, height: 768, }); const parsed = JSON.parse(result); expect(parsed.success).toBe(true); expect(parsed.logical).toBe(true); }, TIMEOUT); it('should resize specific window by windowId', async () => { const result = await manageWindow({ action: 'resize', width: 640, height: 480, windowId: 'main', }); const parsed = JSON.parse(result); expect(parsed.success).toBe(true); expect(parsed.windowLabel).toBe('main'); }, TIMEOUT); }); describe('Window Info', () => { it('should get detailed info for main window', async () => { const result = await manageWindow({ action: 'info' }); const parsed = JSON.parse(result); expect(parsed).toHaveProperty('width'); expect(parsed).toHaveProperty('height'); expect(parsed).toHaveProperty('x'); expect(parsed).toHaveProperty('y'); expect(parsed).toHaveProperty('title'); expect(parsed).toHaveProperty('focused'); expect(parsed).toHaveProperty('visible'); }, TIMEOUT); it('should get info for specific window by windowId', async () => { const result = await manageWindow({ action: 'info', windowId: 'main' }); const parsed = JSON.parse(result); expect(parsed).toHaveProperty('width'); expect(parsed).toHaveProperty('height'); }, TIMEOUT); }); });

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/hypothesi/mcp-server-tauri'

If you have feedback or need assistance with the MCP directory API, please join our Discord server