Skip to main content
Glama
html-tools-file-integration-regression.test.ts7.67 kB
/** * Regression test for HTML visualization tools file output integration * Ensures all HTML tools return file paths instead of HTML content */ import { describe, test, expect, beforeAll, afterAll } from '@jest/globals'; import { promises as fs } from 'fs'; import { join } from 'path'; import { createPaletteHtmlTool } from '../../src/tools/create-palette-html'; import { createColorWheelHtmlTool } from '../../src/tools/create-color-wheel-html'; import { createGradientHtmlTool } from '../../src/tools/create-gradient-html'; import { createThemePreviewHtmlTool } from '../../src/tools/create-theme-preview-html'; import { fileOutputManager } from '../../src/utils/file-output-manager'; describe('HTML Tools File Integration Regression Tests', () => { let testDir: string; let originalEnvVar: string | undefined; beforeAll(async () => { // Set up test directory testDir = join(__dirname, '../../test-output/regression'); await fs.mkdir(testDir, { recursive: true }); // Set environment variable for testing originalEnvVar = process.env['COLOR_MCP_VISUALIZATIONS_DIR']; process.env['COLOR_MCP_VISUALIZATIONS_DIR'] = testDir; // Force file creation in test environment process.env['MCP_FORCE_FILE_CREATION'] = 'true'; // Initialize file output manager await fileOutputManager.initialize(); }); afterAll(async () => { // Restore original environment variable if (originalEnvVar !== undefined) { process.env['COLOR_MCP_VISUALIZATIONS_DIR'] = originalEnvVar; } else { delete process.env['COLOR_MCP_VISUALIZATIONS_DIR']; } // Clean up force file creation flag delete process.env['MCP_FORCE_FILE_CREATION']; // Clean up test directory try { await fs.rm(testDir, { recursive: true, force: true }); } catch (error) { console.warn('Failed to clean up test directory:', error); } // Destroy file output manager fileOutputManager.destroy(); }); test('all HTML tools should return file paths instead of HTML content', async () => { const testCases = [ { name: 'create_palette_html', tool: createPaletteHtmlTool, params: { palette: ['#FF0000', '#00FF00', '#0000FF'], enable_background_controls: true, }, }, { name: 'create_color_wheel_html', tool: createColorWheelHtmlTool, params: { type: 'hsl', size: 400, enable_background_controls: true, }, }, { name: 'create_gradient_html', tool: createGradientHtmlTool, params: { gradient_css: 'linear-gradient(45deg, #FF0000, #0000FF)', enable_background_controls: true, }, }, { name: 'create_theme_preview_html', tool: createThemePreviewHtmlTool, params: { theme_colors: { primary: '#2563eb', background: '#ffffff', text: '#1e293b', }, enable_background_controls: true, }, }, ]; for (const testCase of testCases) { const result = await testCase.tool.handler(testCase.params); // Should succeed expect(result.success).toBe(true); if (result.success) { const data = result.data as any; // Should return file metadata in data expect(data).toHaveProperty('file_path'); expect(data).toHaveProperty('file_name'); expect(data).toHaveProperty('file_size'); expect(data).toHaveProperty('background_controls_enabled'); expect(data).toHaveProperty('accessibility_features'); // File path should be a string expect(typeof data.file_path).toBe('string'); expect(data.file_path).toMatch(/\.html$/); // Background controls should be enabled expect(data.background_controls_enabled).toBe(true); // Accessibility features should be an array expect(Array.isArray(data.accessibility_features)).toBe(true); expect(data.accessibility_features.length).toBeGreaterThan(0); // Visualizations should contain file path message, not HTML content expect(result.visualizations).toHaveProperty('html'); const visualizationHtml = result.visualizations as any; expect(visualizationHtml.html).toContain('File saved:'); expect(visualizationHtml.html).toContain(data.file_path); expect(visualizationHtml.html).not.toContain('<!DOCTYPE html>'); // File should actually exist const fileExists = await fs .access(data.file_path) .then(() => true) .catch(() => false); expect(fileExists).toBe(true); // File should contain valid HTML with background controls const fileContent = await fs.readFile(data.file_path, 'utf8'); expect(fileContent).toContain('<!DOCTYPE html>'); expect(fileContent).toContain('background-controls'); expect(fileContent).toContain('accessibility-features'); expect(fileContent).toContain('keyboard-shortcuts'); console.log(`✅ ${testCase.name}: File saved to ${data.file_path}`); } } }); test('HTML files should be self-contained with embedded CSS and JavaScript', async () => { const result = await createPaletteHtmlTool.handler({ palette: ['#FF0000'], interactive: true, enable_background_controls: true, }); expect(result.success).toBe(true); if (result.success) { const data = result.data as any; const fileContent = await fs.readFile(data.file_path, 'utf8'); // Should contain embedded CSS expect(fileContent).toContain('<style>'); expect(fileContent).toContain('</style>'); expect(fileContent).toContain('background-controls'); // Should contain embedded JavaScript expect(fileContent).toContain('<script>'); expect(fileContent).toContain('</script>'); expect(fileContent).toContain('BackgroundController'); // Should not contain external references expect(fileContent).not.toContain('<link rel="stylesheet"'); expect(fileContent).not.toContain('<script src='); } }); test('error handling should work correctly with file output system', async () => { // Test with invalid parameters const result = await createPaletteHtmlTool.handler({ palette: ['invalid-color'], }); expect(result.success).toBe(false); if (!result.success) { expect(result.error.code).toBe('INVALID_COLOR_FORMAT'); expect(result.error.suggestions).toBeDefined(); expect(result.error.suggestions!.length).toBeGreaterThan(0); } }); test('concurrent file generation should produce unique filenames', async () => { const promises = Array(3) .fill(null) .map(async (_, i) => { return createPaletteHtmlTool.handler({ palette: [`#${i.toString().padStart(6, '0')}`], }); }); const results = await Promise.all(promises); // All should succeed results.forEach(result => { expect(result.success).toBe(true); }); // All file paths should be unique const filePaths = results .filter(r => r.success) .map(r => (r.success ? (r.data as any).file_path : null)) .filter(Boolean) as string[]; const uniquePaths = new Set(filePaths); expect(uniquePaths.size).toBe(filePaths.length); // All files should exist for (const filePath of filePaths) { const fileExists = await fs .access(filePath) .then(() => true) .catch(() => false); expect(fileExists).toBe(true); } }); });

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/keyurgolani/ColorMcp'

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