Skip to main content
Glama
integration-test.js7.04 kB
// @ts-check import { describe, it, beforeAll, afterAll, expect } from "vitest"; import { exec } from "node:child_process"; import fs from "node:fs"; import path from "node:path"; import { fileURLToPath } from "node:url"; import { promisify } from "node:util"; const execAsync = promisify(exec); const __dirname = path.dirname(fileURLToPath(import.meta.url)); const integrationTestDir = path.resolve( __dirname, "../../integration-tests/test-flow" ); const blahJsonPath = path.join(integrationTestDir, "blah.json"); // Test a minimal blah.json file const minimalBlahJson = { name: "test-flow-manifest", version: "1.0.0", tools: [], }; // Skip tests if running in CI environment const isCI = process.env.CI === "true"; if (isCI) { describe.skip("Flow Editor Integration Tests (skipped in CI)", () => { it("skipped in CI", () => {}); }); } else { // Run integration tests locally describe("Flow Editor Integration Tests", () => { // Setup test directory beforeAll(() => { // Make sure the test directory exists if (!fs.existsSync(integrationTestDir)) { fs.mkdirSync(integrationTestDir, { recursive: true }); } // Create a basic blah.json file fs.writeFileSync( blahJsonPath, JSON.stringify(minimalBlahJson, null, 2), "utf8" ); }); afterAll(() => { // Clean up the test files try { fs.unlinkSync(blahJsonPath); } catch (error) { console.log("Error cleaning up test files:", error); } }); it("should create flows array in existing blah.json", async () => { // Create a minimal blah.json without flows fs.writeFileSync( blahJsonPath, JSON.stringify(minimalBlahJson, null, 2), "utf8" ); // Create a simple flows array to add const testFlow = { flows: [ { id: "test-flow-1", name: "Test Flow", description: "A test flow", nodes: [ { id: "start1", type: "start", position: { x: 100, y: 100 }, data: {}, }, { id: "end1", type: "end", position: { x: 300, y: 100 }, data: {}, }, ], edges: [{ source: "start1", target: "end1" }], }, ], }; // Write flow data to a temporary file const flowDataPath = path.join(integrationTestDir, "flow-data.json"); fs.writeFileSync(flowDataPath, JSON.stringify(testFlow), "utf8"); // Simulate a save operation by making a direct request to the API const curlCommand = ` PORT=3333 && \\ cd "${integrationTestDir}" && \\ (node -e " const http = require('http'); const fs = require('fs'); // Start a temporary server to listen for the port to be available const testServer = http.createServer(); testServer.listen($PORT, () => { // Port is available, so we can now close and continue testServer.close(); // Read the flow data const flowData = JSON.parse(fs.readFileSync('flow-data.json', 'utf8')); // Send the POST request to save flows const req = http.request({ hostname: 'localhost', port: $PORT, path: '/api/flows', method: 'POST', headers: { 'Content-Type': 'application/json' } }, (res) => { let data = ''; res.on('data', (chunk) => { data += chunk; }); res.on('end', () => { console.log('Response:', data); // Check if the blah.json file was updated const blahJson = JSON.parse(fs.readFileSync('blah.json', 'utf8')); console.log('Updated blah.json:', JSON.stringify(blahJson, null, 2)); // Clean up test file fs.unlinkSync('flow-data.json'); // Exit with success process.exit(0); }); }); req.on('error', (error) => { console.log('Error sending request:', error); process.exit(1); }); req.write(JSON.stringify(flowData)); req.end(); }); ") & \\ (cd "${path.resolve(__dirname, "../..")}" && npm run dev -- flows --port $PORT); `; // Execute the test command with a timeout try { // We don't actually need to wait for the command to complete, just give it a short time to run await new Promise((resolve) => setTimeout(resolve, 1000)); // Check if blah.json now contains the flows array const updatedBlahJson = JSON.parse( fs.readFileSync(blahJsonPath, "utf8") ); expect(updatedBlahJson).toHaveProperty("flows"); } catch (error) { console.log("Error running integration test:", error); throw error; } finally { // Clean up temporary file if it exists if (fs.existsSync(flowDataPath)) { fs.unlinkSync(flowDataPath); } } }); it("should create a new blah.json file if none exists", async () => { // Remove existing blah.json if any if (fs.existsSync(blahJsonPath)) { fs.unlinkSync(blahJsonPath); } // Create a simple flow to add const newTestFlow = { id: "new-test-flow", name: "New Test Flow", description: "A newly created test flow", nodes: [ { id: "start1", type: "start", position: { x: 100, y: 100 }, data: {}, }, { id: "end1", type: "end", position: { x: 300, y: 100 }, data: {}, }, ], edges: [{ source: "start1", target: "end1" }], }; // Manually simulate what the flow editor would do const blahManifest = { name: "auto-created-manifest", version: "1.0.0", description: "BLAH manifest with agent workflows", tools: [], flows: [newTestFlow], }; // Write the new blah.json file fs.writeFileSync( blahJsonPath, JSON.stringify(blahManifest, null, 2), "utf8" ); // Verify the file was created correctly expect(fs.existsSync(blahJsonPath)).toBe(true); const createdBlahJson = JSON.parse(fs.readFileSync(blahJsonPath, "utf8")); expect(createdBlahJson).toHaveProperty("name", "auto-created-manifest"); expect(createdBlahJson).toHaveProperty("flows"); expect(createdBlahJson.flows).toHaveLength(1); expect(createdBlahJson.flows[0].id).toBe("new-test-flow"); }); }); }

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/thomasdavis/blah'

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