@craftapit/tester
Version:
A focused, LLM-powered testing framework for natural language test scenarios
181 lines (172 loc) • 6.77 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.AnthropicAdapter = void 0;
const BaseAdapter_1 = require("./BaseAdapter");
class AnthropicAdapter extends BaseAdapter_1.BaseAdapter {
constructor(config) {
super(config);
this.apiKey = config.apiKey || process.env.ANTHROPIC_API_KEY || '';
this.baseUrl = config.baseUrl || 'https://api.anthropic.com';
this.model = config.model || 'claude-2';
}
async initialize() {
console.log('Initializing Anthropic adapter');
if (!this.apiKey) {
throw new Error('Anthropic API key is required');
}
}
async cleanup() {
console.log('Cleaning up Anthropic adapter');
// Nothing to clean up
}
/**
* Complete a prompt with the LLM
* @param prompt The prompt to complete
* @returns The completion text
*/
async complete(prompt) {
console.log(`Completing prompt with Anthropic: ${prompt.substring(0, 50)}...`);
try {
const response = await fetch(`${this.baseUrl}/v1/messages`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'x-api-key': this.apiKey,
'anthropic-version': '2023-06-01'
},
body: JSON.stringify({
model: this.model,
messages: [{ role: 'user', content: prompt }],
max_tokens: 4000,
temperature: 0.2
})
});
if (!response.ok) {
throw new Error(`Anthropic API error: ${response.status} ${response.statusText}`);
}
const data = await response.json();
return data.content[0].text;
}
catch (error) {
console.error('Error calling Anthropic API:', error);
throw new Error(`Failed to get completion from Anthropic: ${error instanceof Error ? error.message : 'Unknown error'}`);
}
}
async suggestAction(instruction, screenState) {
console.log(`Suggesting action for: ${instruction}`);
const prompt = `
You are an AI assistant helping to automate UI testing.
Given the following instruction from a test scenario:
"${instruction}"
And the current screen state:
${JSON.stringify(screenState, null, 2)}
Determine the most appropriate action to take. Return a JSON object with:
- actionType: "click", "input", "navigate", "wait", "assert", etc.
- target: Element to interact with (if applicable)
- value: Value to input (if applicable)
- reasoning: Why this action was chosen
- confidence: A number between 0 and 1 indicating your confidence
Response (JSON only):
`;
try {
const response = await fetch(`${this.baseUrl}/v1/messages`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'x-api-key': this.apiKey,
'anthropic-version': '2023-06-01'
},
body: JSON.stringify({
model: this.model,
messages: [{ role: 'user', content: prompt }],
max_tokens: 1000,
temperature: 0.2
})
});
if (!response.ok) {
throw new Error(`Anthropic API error: ${response.status} ${response.statusText}`);
}
const data = await response.json();
const content = data.content[0].text;
// Extract JSON from the response
const jsonMatch = content.match(/```json\n([\s\S]*?)\n```/) ||
content.match(/{[\s\S]*}/);
if (jsonMatch) {
const actionJson = JSON.parse(jsonMatch[1] || jsonMatch[0]);
return {
actionType: actionJson.actionType,
target: actionJson.target,
value: actionJson.value,
reasoning: actionJson.reasoning,
confidence: actionJson.confidence
};
}
throw new Error('Could not parse action from LLM response');
}
catch (error) {
console.error('Error calling Anthropic API:', error);
// Fallback action
return {
actionType: 'click',
target: { text: 'Submit' },
reasoning: 'Fallback action due to API error',
confidence: 0.5
};
}
}
async verifyCondition(condition, screenState) {
console.log(`Verifying condition: ${condition}`);
const prompt = `
You are an AI assistant helping to automate UI testing.
Given the following condition to verify:
"${condition}"
And the current screen state:
${JSON.stringify(screenState, null, 2)}
Determine if the condition is met. Return a JSON object with:
- success: true or false
- reason: Explanation of why the condition is met or not met
Response (JSON only):
`;
try {
const response = await fetch(`${this.baseUrl}/v1/messages`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'x-api-key': this.apiKey,
'anthropic-version': '2023-06-01'
},
body: JSON.stringify({
model: this.model,
messages: [{ role: 'user', content: prompt }],
max_tokens: 1000,
temperature: 0.2
})
});
if (!response.ok) {
throw new Error(`Anthropic API error: ${response.status} ${response.statusText}`);
}
const data = await response.json();
const content = data.content[0].text;
// Extract JSON from the response
const jsonMatch = content.match(/```json\n([\s\S]*?)\n```/) ||
content.match(/{[\s\S]*}/);
if (jsonMatch) {
const resultJson = JSON.parse(jsonMatch[1] || jsonMatch[0]);
return {
success: resultJson.success,
reason: resultJson.reason
};
}
throw new Error('Could not parse verification result from LLM response');
}
catch (error) {
console.error('Error calling Anthropic API:', error);
// Fallback verification
return {
success: true,
reason: 'Fallback verification due to API error'
};
}
}
}
exports.AnthropicAdapter = AnthropicAdapter;