Skip to main content
Glama

WebScraping-AI MCP Server

Official
index.test.js10.2 kB
import { describe, expect, jest, test, beforeEach, afterEach, } from '@jest/globals'; import { Client } from "@modelcontextprotocol/sdk/client/index.js"; import { StdioClientTransport } from "@modelcontextprotocol/sdk/client/stdio.js"; // Create mock WebScrapingAIClient class MockWebScrapingAIClient { constructor() { this.question = jest.fn().mockResolvedValue('This is the answer to your question.'); this.fields = jest.fn().mockResolvedValue({ field1: 'value1', field2: 'value2' }); this.html = jest.fn().mockResolvedValue('<html><body>Test HTML Content</body></html>'); this.text = jest.fn().mockResolvedValue('Test text content'); this.selected = jest.fn().mockResolvedValue('<div>Selected Element</div>'); this.selectedMultiple = jest.fn().mockResolvedValue(['<div>Element 1</div>', '<div>Element 2</div>']); this.account = jest.fn().mockResolvedValue({ requests: 100, remaining: 900, limit: 1000 }); } } // Test interfaces class RequestContext { constructor(toolName, args) { this.params = { name: toolName, arguments: args }; } } describe('WebScraping.AI MCP Server Tests', () => { let mockClient; let requestHandler; beforeEach(() => { jest.clearAllMocks(); mockClient = new MockWebScrapingAIClient(); // Create request handler function requestHandler = async (request) => { const { name: toolName, arguments: args } = request.params; if (!args && toolName !== 'webscraping_ai_account') { throw new Error('No arguments provided'); } return handleRequest(toolName, args || {}, mockClient); }; }); afterEach(() => { jest.clearAllMocks(); }); // Test question functionality test('should handle question request', async () => { const url = 'https://example.com'; const question = 'What is on this page?'; const response = await requestHandler( new RequestContext('webscraping_ai_question', { url, question }) ); expect(response).toEqual({ content: [{ type: 'text', text: 'This is the answer to your question.' }], isError: false }); expect(mockClient.question).toHaveBeenCalledWith(url, question, {}); }); // Test fields functionality test('should handle fields request', async () => { const url = 'https://example.com'; const fields = { title: 'Extract the title', price: 'Extract the price' }; const response = await requestHandler( new RequestContext('webscraping_ai_fields', { url, fields }) ); expect(response).toEqual({ content: [{ type: 'text', text: JSON.stringify({ field1: 'value1', field2: 'value2' }, null, 2) }], isError: false }); expect(mockClient.fields).toHaveBeenCalledWith(url, fields, {}); }); // Test html functionality test('should handle html request', async () => { const url = 'https://example.com'; const response = await requestHandler( new RequestContext('webscraping_ai_html', { url }) ); expect(response).toEqual({ content: [{ type: 'text', text: '<html><body>Test HTML Content</body></html>' }], isError: false }); expect(mockClient.html).toHaveBeenCalledWith(url, {}); }); // Test text functionality test('should handle text request', async () => { const url = 'https://example.com'; const response = await requestHandler( new RequestContext('webscraping_ai_text', { url }) ); expect(response).toEqual({ content: [{ type: 'text', text: 'Test text content' }], isError: false }); expect(mockClient.text).toHaveBeenCalledWith(url, {}); }); // Test selected functionality test('should handle selected request', async () => { const url = 'https://example.com'; const selector = '.main-content'; const response = await requestHandler( new RequestContext('webscraping_ai_selected', { url, selector }) ); expect(response).toEqual({ content: [{ type: 'text', text: '<div>Selected Element</div>' }], isError: false }); expect(mockClient.selected).toHaveBeenCalledWith(url, selector, {}); }); // Test selected_multiple functionality test('should handle selected_multiple request', async () => { const url = 'https://example.com'; const selectors = ['.item1', '.item2']; const response = await requestHandler( new RequestContext('webscraping_ai_selected_multiple', { url, selectors }) ); expect(response).toEqual({ content: [{ type: 'text', text: JSON.stringify(['<div>Element 1</div>', '<div>Element 2</div>'], null, 2) }], isError: false }); expect(mockClient.selectedMultiple).toHaveBeenCalledWith(url, selectors, {}); }); // Test account functionality test('should handle account request', async () => { const response = await requestHandler( new RequestContext('webscraping_ai_account', {}) ); expect(response).toEqual({ content: [{ type: 'text', text: JSON.stringify({ requests: 100, remaining: 900, limit: 1000 }, null, 2) }], isError: false }); expect(mockClient.account).toHaveBeenCalled(); }); // Test error handling test('should handle API errors', async () => { const url = 'https://example.com'; mockClient.question.mockRejectedValueOnce(new Error('API Error')); const response = await requestHandler( new RequestContext('webscraping_ai_question', { url, question: 'What is on this page?' }) ); expect(response.isError).toBe(true); expect(response.content[0].text).toContain('API Error'); }); // Test unknown tool test('should handle unknown tool request', async () => { const response = await requestHandler( new RequestContext('unknown_tool', { some: 'args' }) ); expect(response.isError).toBe(true); expect(response.content[0].text).toContain('Unknown tool'); }); // Test MCP Client Connection xtest('should connect to MCP server and list tools', async () => { const transport = new StdioClientTransport({ command: "node", args: ["src/index.js"] }); const client = new Client({ name: "webscraping-ai-test-client", version: "1.0.0" }); await client.connect(transport); const response = await client.listTools(); expect(response.tools).toEqual(expect.arrayContaining([ expect.objectContaining({ name: 'webscraping_ai_question', inputSchema: expect.any(Object) }), expect.objectContaining({ name: 'webscraping_ai_fields', inputSchema: expect.any(Object) }), expect.objectContaining({ name: 'webscraping_ai_html', inputSchema: expect.any(Object) }), expect.objectContaining({ name: 'webscraping_ai_text', inputSchema: expect.any(Object) }), expect.objectContaining({ name: 'webscraping_ai_selected', inputSchema: expect.any(Object) }), expect.objectContaining({ name: 'webscraping_ai_selected_multiple', inputSchema: expect.any(Object) }), expect.objectContaining({ name: 'webscraping_ai_account', inputSchema: expect.any(Object) }) ])); await client.close(); }); }); // Helper function to simulate request handling async function handleRequest(name, args, client) { try { const options = { ...args }; // Remove required parameters from options for each tool type switch (name) { case 'webscraping_ai_question': { const { url, question, ...rest } = options; if (!url || !question) { throw new Error('URL and question are required'); } const result = await client.question(url, question, rest); return { content: [{ type: 'text', text: result }], isError: false }; } case 'webscraping_ai_fields': { const { url, fields, ...rest } = options; if (!url || !fields) { throw new Error('URL and fields are required'); } const result = await client.fields(url, fields, rest); return { content: [{ type: 'text', text: JSON.stringify(result, null, 2) }], isError: false }; } case 'webscraping_ai_html': { const { url, ...rest } = options; if (!url) { throw new Error('URL is required'); } const result = await client.html(url, rest); return { content: [{ type: 'text', text: result }], isError: false }; } case 'webscraping_ai_text': { const { url, ...rest } = options; if (!url) { throw new Error('URL is required'); } const result = await client.text(url, rest); return { content: [{ type: 'text', text: result }], isError: false }; } case 'webscraping_ai_selected': { const { url, selector, ...rest } = options; if (!url || !selector) { throw new Error('URL and selector are required'); } const result = await client.selected(url, selector, rest); return { content: [{ type: 'text', text: result }], isError: false }; } case 'webscraping_ai_selected_multiple': { const { url, selectors, ...rest } = options; if (!url || !selectors) { throw new Error('URL and selectors are required'); } const result = await client.selectedMultiple(url, selectors, rest); return { content: [{ type: 'text', text: JSON.stringify(result, null, 2) }], isError: false }; } case 'webscraping_ai_account': { const result = await client.account(); return { content: [{ type: 'text', text: JSON.stringify(result, null, 2) }], isError: false }; } default: throw new Error(`Unknown tool: ${name}`); } } catch (error) { return { content: [{ type: 'text', text: error.message }], isError: true }; } }

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/webscraping-ai/webscraping-ai-mcp-server'

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