Skip to main content
Glama
response.test.ts9.76 kB
/** * Copyright (c) Microsoft Corporation. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ import { describe, it, expect, vi, beforeEach } from 'vitest'; import { Response } from '../src/response.js'; import type { Context } from '../src/context.js'; import type { Tab } from '../src/tab.js'; describe('Response', () => { let mockContext: Context; let mockTab: Tab; beforeEach(() => { mockTab = { page: { url: () => 'https://example.com' }, lastTitle: () => 'Example Page', isCurrentTab: () => true, captureSnapshot: vi.fn().mockResolvedValue({ url: 'https://example.com', title: 'Example Page', ariaSnapshot: 'button "Submit"', modalStates: [], consoleMessages: [], downloads: [], }), updateTitle: vi.fn().mockResolvedValue(undefined), } as any; mockContext = { currentTab: () => mockTab, currentTabOrDie: () => mockTab, tabs: () => [mockTab], config: { imageResponses: 'include', }, } as any; }); describe('constructor', () => { it('should create a response with tool name and args', () => { const response = new Response(mockContext, 'test_tool', { param: 'value' }); expect(response.toolName).toBe('test_tool'); expect(response.toolArgs).toEqual({ param: 'value' }); }); }); describe('addResult', () => { it('should add result text', () => { const response = new Response(mockContext, 'test_tool', {}); response.addResult('Test result'); expect(response.result()).toBe('Test result'); }); it('should concatenate multiple results', () => { const response = new Response(mockContext, 'test_tool', {}); response.addResult('Result 1'); response.addResult('Result 2'); expect(response.result()).toBe('Result 1\nResult 2'); }); }); describe('addError', () => { it('should add error text', () => { const response = new Response(mockContext, 'test_tool', {}); response.addError('Error occurred'); expect(response.result()).toBe('Error occurred'); }); it('should mark response as error', () => { const response = new Response(mockContext, 'test_tool', {}); expect(response.isError()).toBeUndefined(); response.addError('Error occurred'); expect(response.isError()).toBe(true); }); }); describe('addCode', () => { it('should add code snippet', () => { const response = new Response(mockContext, 'test_tool', {}); response.addCode('await page.click("button")'); expect(response.code()).toBe('await page.click("button")'); }); it('should concatenate multiple code snippets', () => { const response = new Response(mockContext, 'test_tool', {}); response.addCode('await page.click("button")'); response.addCode('await page.type("input", "text")'); expect(response.code()).toBe('await page.click("button")\nawait page.type("input", "text")'); }); }); describe('addImage', () => { it('should add image to response', () => { const response = new Response(mockContext, 'test_tool', {}); const imageBuffer = Buffer.from('test'); response.addImage({ contentType: 'image/png', data: imageBuffer }); expect(response.images()).toHaveLength(1); expect(response.images()[0]).toEqual({ contentType: 'image/png', data: imageBuffer, }); }); it('should add multiple images', () => { const response = new Response(mockContext, 'test_tool', {}); response.addImage({ contentType: 'image/png', data: Buffer.from('img1') }); response.addImage({ contentType: 'image/jpeg', data: Buffer.from('img2') }); expect(response.images()).toHaveLength(2); }); }); describe('setIncludeSnapshot', () => { it('should enable snapshot inclusion', async () => { const response = new Response(mockContext, 'test_tool', {}); response.setIncludeSnapshot(); await response.finish(); expect(mockTab.captureSnapshot).toHaveBeenCalled(); }); }); describe('setIncludeTabs', () => { it('should enable tabs listing', () => { const response = new Response(mockContext, 'test_tool', {}); response.setIncludeTabs(); const serialized = response.serialize(); expect(serialized.content[0].text).toContain('Open tabs'); }); }); describe('finish', () => { it('should capture snapshot if requested', async () => { const response = new Response(mockContext, 'test_tool', {}); response.setIncludeSnapshot(); await response.finish(); expect(mockTab.captureSnapshot).toHaveBeenCalled(); }); it('should update all tab titles', async () => { const response = new Response(mockContext, 'test_tool', {}); await response.finish(); expect(mockTab.updateTitle).toHaveBeenCalled(); }); }); describe('serialize', () => { it('should serialize basic response', () => { const response = new Response(mockContext, 'test_tool', {}); response.addResult('Test result'); const serialized = response.serialize(); expect(serialized.content).toHaveLength(1); expect(serialized.content[0].type).toBe('text'); expect(serialized.content[0].text).toContain('Test result'); }); it('should include code section when code is added', () => { const response = new Response(mockContext, 'test_tool', {}); response.addCode('await page.click("button")'); const serialized = response.serialize(); expect(serialized.content[0].text).toContain('Ran Playwright code'); expect(serialized.content[0].text).toContain('await page.click("button")'); }); it('should include images when present', () => { const response = new Response(mockContext, 'test_tool', {}); response.addImage({ contentType: 'image/png', data: Buffer.from('test') }); const serialized = response.serialize(); expect(serialized.content).toHaveLength(2); expect(serialized.content[1].type).toBe('image'); expect(serialized.content[1].mimeType).toBe('image/png'); }); it('should omit images when configured', () => { mockContext.config.imageResponses = 'omit'; const response = new Response(mockContext, 'test_tool', {}); response.addImage({ contentType: 'image/png', data: Buffer.from('test') }); const serialized = response.serialize(); expect(serialized.content).toHaveLength(1); }); it('should include error flag when error occurred', () => { const response = new Response(mockContext, 'test_tool', {}); response.addError('Error message'); const serialized = response.serialize(); expect(serialized.isError).toBe(true); }); it('should include snapshot when captured', async () => { const response = new Response(mockContext, 'test_tool', {}); response.setIncludeSnapshot(); await response.finish(); const serialized = response.serialize(); expect(serialized.content[0].text).toContain('Page state'); expect(serialized.content[0].text).toContain('Example Page'); }); it('should include console messages in snapshot', async () => { mockTab.captureSnapshot = vi.fn().mockResolvedValue({ url: 'https://example.com', title: 'Example Page', ariaSnapshot: '', modalStates: [], consoleMessages: [ { type: 'log', text: 'Test message', toString: () => '[LOG] Test message' } ], downloads: [], }); const response = new Response(mockContext, 'test_tool', {}); response.setIncludeSnapshot(); await response.finish(); const serialized = response.serialize(); expect(serialized.content[0].text).toContain('New console messages'); expect(serialized.content[0].text).toContain('Test message'); }); it('should include downloads in snapshot', async () => { mockTab.captureSnapshot = vi.fn().mockResolvedValue({ url: 'https://example.com', title: 'Example Page', ariaSnapshot: '', modalStates: [], consoleMessages: [], downloads: [{ download: { suggestedFilename: () => 'file.pdf' } as any, finished: true, outputFile: '/tmp/file.pdf' }], }); const response = new Response(mockContext, 'test_tool', {}); response.setIncludeSnapshot(); await response.finish(); const serialized = response.serialize(); expect(serialized.content[0].text).toContain('Downloads'); expect(serialized.content[0].text).toContain('file.pdf'); }); }); describe('tabSnapshot', () => { it('should return undefined before finish', () => { const response = new Response(mockContext, 'test_tool', {}); expect(response.tabSnapshot()).toBeUndefined(); }); it('should return snapshot after finish', async () => { const response = new Response(mockContext, 'test_tool', {}); response.setIncludeSnapshot(); await response.finish(); expect(response.tabSnapshot()).toBeDefined(); expect(response.tabSnapshot()?.url).toBe('https://example.com'); }); }); });

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/JustasMonkev/mcp-accessibility-scanner'

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