@craftapit/tester
Version:
A focused, LLM-powered testing framework for natural language test scenarios
144 lines (143 loc) • 5.31 kB
JavaScript
;
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || (function () {
var ownKeys = function(o) {
ownKeys = Object.getOwnPropertyNames || function (o) {
var ar = [];
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
return ar;
};
return ownKeys(o);
};
return function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
__setModuleDefault(result, mod);
return result;
};
})();
Object.defineProperty(exports, "__esModule", { value: true });
exports.ScenarioParser = void 0;
const fs = __importStar(require("fs/promises"));
class ScenarioParser {
/**
* Parse a scenario from a string
* @param content The scenario content as a string
* @returns The parsed scenario
*/
parse(content) {
const title = this.extractTitle(content);
const context = this.extractContext(content);
const steps = this.extractSteps(content);
const testType = this.extractTestType(content);
return {
title,
context,
steps,
testType,
filePath: 'memory' // Since this is parsed from a string, not a file
};
}
/**
* Parse a scenario from a file
* @param scenarioPath The path to the scenario file
* @returns The parsed scenario
*/
async parseScenario(scenarioPath) {
// Read the scenario file
const content = await fs.readFile(scenarioPath, 'utf-8');
// This is a placeholder implementation
// A real implementation would parse the markdown properly
const title = this.extractTitle(content);
const context = this.extractContext(content);
const steps = this.extractSteps(content);
const testType = this.extractTestType(content);
return {
title,
context,
steps,
testType,
filePath: scenarioPath
};
}
extractTestType(content) {
const contextMatch = content.match(/## Context\s+([\s\S]*?)(?=##|$)/);
if (!contextMatch)
return 'generic';
const contextContent = contextMatch[1].toLowerCase();
if (contextContent.includes('type: ui') ||
contextContent.includes('browser') ||
contextContent.includes('- ui')) {
return 'ui';
}
else if (contextContent.includes('type: api') ||
contextContent.includes('api') ||
contextContent.includes('endpoint')) {
return 'api';
}
else if (contextContent.includes('type: database') ||
contextContent.includes('database') ||
contextContent.includes('sql')) {
return 'database';
}
return 'generic';
}
extractTitle(content) {
// Extract the title from the markdown
const titleMatch = content.match(/^# (.+)$/m);
return titleMatch ? titleMatch[1].trim() : 'Untitled Scenario';
}
extractContext(content) {
// Extract the context section from the markdown
const contextMatch = content.match(/## Context\s+([\s\S]*?)(?=##|$)/);
if (!contextMatch) {
return {};
}
const contextLines = contextMatch[1].trim().split('\n');
const context = {};
for (const line of contextLines) {
const itemMatch = line.match(/^- (.+?): (.+)$/);
if (itemMatch) {
const [, key, value] = itemMatch;
context[key.trim()] = value.trim();
}
}
return context;
}
extractSteps(content) {
// Extract the steps section from the markdown
const stepsMatch = content.match(/### Steps\s+([\s\S]*?)(?=###|$)/);
if (!stepsMatch) {
return [];
}
const stepsContent = stepsMatch[1].trim();
const stepMatches = Array.from(stepsContent.matchAll(/(\d+)\. \*\*(Given|When|Then|And)\*\* (.+?)(?=\n\d+\. \*\*|\n?$)/gs));
const steps = [];
for (const match of stepMatches) {
const [, , type, instruction] = match;
steps.push({
type: type.toLowerCase(),
instruction: instruction.trim(),
lineNumber: parseInt(match[1])
});
}
return steps;
}
}
exports.ScenarioParser = ScenarioParser;