Skip to main content
Glama

Automation Script Generator MCP Server

core.test.js•11.8 kB
/** * Core Methods Unit Tests * Comprehensive test suite for all core functionality */ import { jest } from '@jest/globals'; import { AutomationScriptGenerator } from '../index.js'; import fs from 'fs-extra'; import path from 'path'; describe('AutomationScriptGenerator', () => { let generator; let testDir; beforeEach(async () => { generator = new AutomationScriptGenerator(); testDir = path.join(process.cwd(), 'test-temp'); await fs.ensureDir(testDir); }); afterEach(async () => { if (await fs.pathExists(testDir)) { await fs.remove(testDir); } }); describe('File Pattern Matching', () => { beforeEach(async () => { // Create test files await fs.ensureDir(path.join(testDir, 'features')); await fs.ensureDir(path.join(testDir, 'step-definitions')); await fs.ensureDir(path.join(testDir, 'pageobjects')); await fs.ensureDir(path.join(testDir, 'utils')); await fs.writeFile(path.join(testDir, 'features', 'login.feature'), 'Feature: Login'); await fs.writeFile(path.join(testDir, 'step-definitions', 'login.steps.js'), 'export const step = () => {};'); await fs.writeFile(path.join(testDir, 'pageobjects', 'login.page.js'), 'export class LoginPage {}'); await fs.writeFile(path.join(testDir, 'utils', 'helpers.js'), 'export const helper = () => {};'); }); test('should find feature files', async () => { const files = await generator.findFilesByPattern(testDir, 'features'); expect(files).toHaveLength(1); expect(files[0]).toMatch(/login\.feature$/); }); test('should find step files', async () => { const files = await generator.findFilesByPattern(testDir, 'steps'); expect(files).toHaveLength(1); expect(files[0]).toMatch(/login\.steps\.js$/); }); test('should find page files', async () => { const files = await generator.findFilesByPattern(testDir, 'pages'); expect(files).toHaveLength(1); expect(files[0]).toMatch(/login\.page\.js$/); }); test('should find utility files', async () => { const files = await generator.findFilesByPattern(testDir, 'utils'); expect(files).toHaveLength(1); expect(files[0]).toMatch(/helpers\.js$/); }); test('should handle non-existent directories gracefully', async () => { const files = await generator.findFilesByPattern('/non-existent', 'features'); expect(files).toEqual([]); }); }); describe('Pattern Extraction', () => { test('should extract feature patterns correctly', () => { const content = ` Feature: User Login @login @smoke Scenario: Successful login Given I am on the login page When I enter valid credentials Then I should be logged in `; const patterns = generator.extractFeaturePatterns(content); expect(patterns.scenarios).toContain('Successful login'); expect(patterns.tags).toContain('@login'); expect(patterns.tags).toContain('@smoke'); expect(patterns.steps).toContain('Given I am on the login page'); }); test('should extract step patterns correctly', () => { const content = ` import { Given, When, Then } from '@wdio/cucumber-framework'; Given('I am on the login page', async () => { await browser.url('/login'); }); function loginUser() { return 'logged in'; } `; const patterns = generator.extractStepPatterns(content); expect(patterns.stepDefinitions).toContain('Given'); expect(patterns.exports).toContain('loginUser'); }); test('should extract page object patterns correctly', () => { const content = ` class LoginPage { get usernameInput() { return $('#username'); } get passwordInput() { return $('#password'); } async login(username, password) { await this.usernameInput.setValue(username); } } `; const patterns = generator.extractPagePatterns(content); expect(patterns.className).toBe('LoginPage'); expect(patterns.methods).toContain('login'); expect(patterns.selectors).toHaveProperty('#username'); }); }); describe('Utility Function Extraction', () => { test('should extract function declarations', () => { const content = ` export function helper() {} async function asyncHelper() {} const arrowFunc = () => {}; const asyncArrow = async () => {}; `; const functions = generator.extractUtilFunctions(content); expect(functions).toHaveLength(4); expect(functions.find(f => f.name === 'helper')).toBeDefined(); expect(functions.find(f => f.name === 'asyncHelper')).toMatchObject({ name: 'asyncHelper', isAsync: true }); }); test('should extract exported functions', () => { const content = ` export { func1, func2 as renamed }; export default defaultFunc; export const directExport = () => {}; `; const exports = generator.extractExportedFunctions(content); expect(exports).toContain('func1'); expect(exports).toContain('func2'); expect(exports).toContain('defaultFunc'); expect(exports).toContain('directExport'); }); }); describe('Naming Convention Detection', () => { test('should detect kebab-case', () => { const pattern = generator.detectNamingPattern( ['my-file', 'another-file', 'test-case'], ['kebab-case', 'camelCase'] ); expect(pattern).toBe('kebab-case'); }); test('should detect camelCase', () => { const pattern = generator.detectNamingPattern( ['myFile', 'anotherFile', 'testCase'], ['kebab-case', 'camelCase'] ); expect(pattern).toBe('camelCase'); }); test('should detect PascalCase', () => { const pattern = generator.detectNamingPattern( ['MyClass', 'AnotherClass', 'TestCase'], ['PascalCase', 'camelCase'] ); expect(pattern).toBe('PascalCase'); }); }); describe('Smart File Analysis', () => { beforeEach(async () => { await fs.ensureDir(path.join(testDir, 'features')); await fs.writeFile(path.join(testDir, 'features', 'existing-login.feature'), ` Feature: User Authentication Scenario: Login with credentials Given I am on the login page `); }); test('should find similar features', async () => { const similar = await generator.findSimilarFeatures( testDir, 'User Login Process', 'Given I am on the login page' ); expect(similar).toHaveLength(1); expect(similar[0].similarity).toBeGreaterThan(0.6); }); test('should calculate feature similarity correctly', () => { const similarity = generator.calculateFeatureSimilarity( 'User Login', 'Given I am on the login page', 'Feature: User Authentication\nGiven I am on the login page' ); expect(similarity).toBeGreaterThan(0.5); }); }); describe('Step Implementation Generation', () => { test('should generate Given step implementation', () => { const implementation = generator.generateStepImplementation( 'Given I am on the login page', 'I am on the login page', 'Given' ); expect(implementation).toContain('browser.url'); expect(implementation).toContain('waitUntil'); }); test('should generate When step implementation', () => { const selectors = { usernameInput: '#username' }; const implementation = generator.generateStepImplementation( 'When I enter username', 'I enter username', 'When', selectors ); expect(implementation).toContain('setValue'); expect(implementation).toContain('#username'); }); test('should generate Then step implementation', () => { const implementation = generator.generateStepImplementation( 'Then I should see welcome message', 'I should see welcome message', 'Then' ); expect(implementation).toContain('expect'); expect(implementation).toContain('toBeDisplayed'); }); }); describe('Code Review', () => { test('should identify missing documentation', async () => { const content = ` function undocumentedFunction() { return 'test'; } `; const review = await generator.performCodeReview( content, ['docs'], null, 'test.js' ); expect(review.issues.length).toBeGreaterThan(0); expect(review.issues[0]).toMatch(/JSDoc/); }); test('should identify POM violations', async () => { const content = ` const selector = '#element'; function clickElement() { $(selector).click(); } `; const review = await generator.performCodeReview( content, ['pom'], null, 'page.js' ); expect(review.issues.length).toBeGreaterThan(0); expect(review.issues[0]).toMatch(/class/); }); }); describe('Configuration Management', () => { test('should validate schema correctly', () => { const validArgs = { scenario_title: 'Test Scenario', gherkin_syntax: 'Given test step', selectors: { button: '#btn' }, output_directory: './output' }; expect(() => { generator.validateArgs('process_test_scenario', validArgs); }).not.toThrow(); }); test('should reject invalid schema', () => { const invalidArgs = { scenario_title: '', // Empty title should fail selectors: { button: '#btn' }, output_directory: './output' }; expect(() => { generator.validateArgs('process_test_scenario', invalidArgs); }).toThrow(); }); }); describe('Error Handling', () => { test('should handle file read errors gracefully', async () => { const patterns = await generator.scanForPatterns('/non-existent-path', 'features'); expect(patterns).toEqual([]); }); test('should handle invalid content gracefully', () => { const patterns = generator.extractFeaturePatterns('invalid content'); expect(patterns.scenarios).toEqual([]); expect(patterns.tags).toEqual([]); expect(patterns.steps).toEqual([]); }); test('should handle missing selectors in step generation', () => { const implementation = generator.generateStepImplementation( 'When I click unknown element', 'I click unknown element', 'When', {} ); expect(implementation).toContain('$(".element")'); // Fallback selector }); }); });

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/raymondsambur/automation-script-generator'

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