Skip to main content
Glama
duplicate-analyzer.test.tsโ€ข7.84 kB
import { describe, it } from 'node:test'; import assert from 'node:assert'; import { TestCaseDuplicateAnalyzer } from '../../src/utils/duplicate-analyzer.js'; import { ZebrunnerTestCase } from '../../src/types/core.js'; describe('TestCaseDuplicateAnalyzer', () => { const analyzer = new TestCaseDuplicateAnalyzer(80); it('should extract steps from test case', () => { const testCase: ZebrunnerTestCase = { id: 1, key: 'TEST-1', title: 'Login Test', steps: [ { id: 1, action: 'Open login page', expectedResult: 'Login page displays' }, { id: 2, action: 'Enter username', expectedResult: 'Username field is filled' }, { id: 3, action: 'Enter password', expectedResult: 'Password field is filled' }, { id: 4, action: 'Click login button', expectedResult: 'User is logged in' } ] }; const steps = analyzer.extractSteps(testCase); assert.strictEqual(steps.length, 4); assert.strictEqual(steps[0].action, 'open login page'); assert.strictEqual(steps[0].expectedResult, 'login page displays'); }); it('should calculate similarity between similar test cases', () => { const testCase1: ZebrunnerTestCase = { id: 1, key: 'TEST-1', title: 'Login Test 1', steps: [ { id: 1, action: 'Open login page', expectedResult: 'Login page displays' }, { id: 2, action: 'Enter username and password', expectedResult: 'Credentials are entered' }, { id: 3, action: 'Click login button', expectedResult: 'User is logged in' } ] }; const testCase2: ZebrunnerTestCase = { id: 2, key: 'TEST-2', title: 'Login Test 2', steps: [ { id: 1, action: 'Navigate to login page', expectedResult: 'Login page is shown' }, { id: 2, action: 'Fill username and password', expectedResult: 'User credentials filled' }, { id: 3, action: 'Press login button', expectedResult: 'User successfully logged in' } ] }; const steps1 = analyzer.extractSteps(testCase1); const steps2 = analyzer.extractSteps(testCase2); const result = analyzer.calculateStepSimilarity(steps1, steps2); assert.ok(result.similarity > 50, `Similarity should be > 50%, got ${result.similarity}%`); assert.ok(result.sharedSteps >= 2, `Should have at least 2 shared steps, got ${result.sharedSteps}`); assert.ok(result.sharedStepsSummary.length > 0); }); it('should create clusters from similar test cases', () => { const testCases: ZebrunnerTestCase[] = [ { id: 1, key: 'TEST-1', title: 'Login Test 1', automationState: { id: 1, name: 'Manual' }, steps: [ { id: 1, action: 'Open login page', expectedResult: 'Login page displays' }, { id: 2, action: 'Enter credentials', expectedResult: 'Credentials entered' }, { id: 3, action: 'Click login', expectedResult: 'User logged in' } ] }, { id: 2, key: 'TEST-2', title: 'Login Test 2', automationState: { id: 2, name: 'Automated' }, steps: [ { id: 1, action: 'Navigate to login page', expectedResult: 'Login page shown' }, { id: 2, action: 'Fill credentials', expectedResult: 'Credentials filled' }, { id: 3, action: 'Press login button', expectedResult: 'User successfully logged in' } ] }, { id: 3, key: 'TEST-3', title: 'Logout Test', automationState: { id: 1, name: 'Manual' }, steps: [ { id: 1, action: 'Click logout button', expectedResult: 'User logged out' } ] } ]; const result = analyzer.analyzeDuplicates(testCases, 'TEST'); assert.strictEqual(result.totalTestCases, 3); assert.strictEqual(result.projectKey, 'TEST'); assert.ok(result.clustersFound >= 0); if (result.clustersFound > 0) { const cluster = result.clusters[0]; assert.ok(cluster.testCases.length >= 2); assert.ok(cluster.averageSimilarity > 0); assert.ok(cluster.recommendedBase.testCaseKey.length > 0); assert.ok(cluster.mergingStrategy.length > 0); } }); it('should handle test cases without steps', () => { const testCase: ZebrunnerTestCase = { id: 1, key: 'TEST-1', title: 'Empty Test', steps: [] }; const steps = analyzer.extractSteps(testCase); assert.strictEqual(steps.length, 0); }); it('should detect user type patterns', () => { const testCases: ZebrunnerTestCase[] = [ { id: 1, key: 'TEST-1', title: 'Login test for Free user', automationState: { id: 1, name: 'Manual' }, steps: [ { id: 1, action: 'Open login page', expectedResult: 'Login page displays' }, { id: 2, action: 'Enter credentials', expectedResult: 'Credentials entered' } ] }, { id: 2, key: 'TEST-2', title: 'Login test for Premium user', automationState: { id: 2, name: 'Automated' }, steps: [ { id: 1, action: 'Open login page', expectedResult: 'Login page displays' }, { id: 2, action: 'Enter credentials', expectedResult: 'Credentials entered' } ] } ]; const analyzer = new TestCaseDuplicateAnalyzer(70); const similarities = analyzer.calculateSimilarityMatrix(testCases); assert.ok(similarities.length > 0); assert.strictEqual(similarities[0].patternType, 'user_type'); assert.ok(similarities[0].variationDetails?.userTypes?.includes('Free')); assert.ok(similarities[0].variationDetails?.userTypes?.includes('Premium')); }); it('should detect theme patterns', () => { const testCases: ZebrunnerTestCase[] = [ { id: 1, key: 'TEST-1', title: 'Verify card display in Dark mode', automationState: { id: 1, name: 'Manual' }, steps: [ { id: 1, action: 'Open app', expectedResult: 'App opens' }, { id: 2, action: 'Check card display', expectedResult: 'Card visible' } ] }, { id: 2, key: 'TEST-2', title: 'Verify card display in Light mode', automationState: { id: 1, name: 'Manual' }, steps: [ { id: 1, action: 'Open app', expectedResult: 'App opens' }, { id: 2, action: 'Check card display', expectedResult: 'Card visible' } ] } ]; const analyzer = new TestCaseDuplicateAnalyzer(70); const similarities = analyzer.calculateSimilarityMatrix(testCases); assert.ok(similarities.length > 0); assert.strictEqual(similarities[0].patternType, 'theme'); assert.ok(similarities[0].variationDetails?.themes?.includes('Dark')); assert.ok(similarities[0].variationDetails?.themes?.includes('Light')); }); it('should provide pattern-specific merging strategies', () => { const testCases: ZebrunnerTestCase[] = [ { id: 1, key: 'TEST-1', title: 'Test for Free user', automationState: { id: 1, name: 'Manual' }, steps: [ { id: 1, action: 'Perform action', expectedResult: 'Action completed' } ] }, { id: 2, key: 'TEST-2', title: 'Test for Premium user', automationState: { id: 2, name: 'Automated' }, steps: [ { id: 1, action: 'Perform action', expectedResult: 'Action completed' } ] } ]; const analyzer = new TestCaseDuplicateAnalyzer(70); const result = analyzer.analyzeDuplicates(testCases, 'TEST'); if (result.clustersFound > 0) { const cluster = result.clusters[0]; assert.ok(cluster.mergingStrategy.includes('userType parameter')); assert.ok(cluster.mergingStrategy.includes('Free/Premium')); } }); });

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/maksimsarychau/mcp-zebrunner'

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